@membranehq/cli 1.3.0 → 1.4.0
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/README.md +4 -2
- package/dist/index.js +1 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ The CLI can be configured using either environment variables or a configuration
|
|
|
42
42
|
```bash
|
|
43
43
|
export MEMBRANE_WORKSPACE_KEY=<your-workspace-key>
|
|
44
44
|
export MEMBRANE_WORKSPACE_SECRET=<your-workspace-secret>
|
|
45
|
-
export MEMBRANE_API_URI=https://api.
|
|
45
|
+
export MEMBRANE_API_URI=https://api.your-membrane-instance.com # Only needed when using a self-hosted version of Membrane. Set to the URL of your hosted membrane instance. Defaults to https://api.getmembrane.com
|
|
46
46
|
export MEMBRANE_TEST_CUSTOMER_ID=<test-customer-id> # Optional: test customer ID for testing integrations
|
|
47
47
|
```
|
|
48
48
|
|
|
@@ -54,12 +54,14 @@ The CLI uses a configuration file at `membrane.config.yml`:
|
|
|
54
54
|
workspaceKey: <your-workspace-key>
|
|
55
55
|
workspaceSecret: <your-workspace-secret>
|
|
56
56
|
# Optional
|
|
57
|
-
apiUri: https://api.
|
|
57
|
+
apiUri: https://api.your-membrane-instance.com # Only needed when using a self-hosted version of Membrane. Set to the URL of your hosted membrane instance. Defaults to https://api.getmembrane.com
|
|
58
58
|
testCustomerId: test-customer # Internal id of the customer to be used for testing integrations.
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
**Note:** When both environment variables and configuration file are present, environment variables take precedence.
|
|
62
62
|
|
|
63
|
+
**Self-Hosting:** For details on self-hosting Membrane, see [Self-Hosting Documentation](https://getmembrane.com/features/self-hosting).
|
|
64
|
+
|
|
63
65
|
## Version Control
|
|
64
66
|
|
|
65
67
|
`membrane.config.yml` contains secrets. You should exclude it from version control.
|
package/dist/index.js
CHANGED
|
@@ -152,8 +152,7 @@ Use it for anything related to Membrane or integrations.
|
|
|
152
152
|
`,version:"1.0.0"});for(const g of u){const y=g.execute;g.execute=async p=>(wl(process.pid,process.cwd()),y(p)),f.addTool(g)}xs({isRunning:!0,startTime:new Date().toISOString(),toolsCount:u.length,lastActivity:new Date().toISOString(),processId:process.pid,cwd:process.cwd(),agentName:process.env.AGENT_NAME||"Unnamed Agent"});const d=setInterval(()=>{xs({processId:process.pid,cwd:process.cwd(),lastActivity:new Date().toISOString()})},5e3),h=c(async()=>{clearInterval(d),Pt(process.pid,process.cwd());try{await f.stop()}catch{}},"cleanup");await f.start({transportType:"stdio"}),process.on("SIGINT",async()=>{await h(),process.exit(0)}),process.on("SIGTERM",async()=>{await h(),process.exit(0)}),process.on("exit",()=>{Pt(process.pid,process.cwd())}),process.on("uncaughtException",async g=>{console.error("Uncaught exception:",g.message),await h(),process.exit(1)}),process.on("unhandledRejection",async g=>{console.error("Unhandled rejection:",g),await h(),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(Fl,"setupMcpCommand");const Kl={info:"\u{1F4DD}",success:"\u2728",warning:"\u26A0\uFE0F",error:"\u274C",debug:"\u{1F50D}"},Bl={info:v.white,success:v.green,warning:v.yellow,error:v.red,debug:v.gray};class j{static{c(this,"Logger")}static formatMessage(e,t,n={icon:!1}){const r=n.timestamp?`${v.gray(new Date().toISOString())} `:"",i=n.prefix?`${v.gray(n.prefix)} `:"",o=n.suffix?` ${v.gray(n.suffix)}`:"",a=Kl[t],l=Bl[t];return`${r}${n.icon?a:""} ${i}${l(e)}${o}`}static info(e,t){let n=v.white;if(t?.color&&(n=v[t.color.toLowerCase()]||v.white),t?.timestamp){const r=new Date().toLocaleTimeString();console.debug(`${v.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(v.gray(`[${t.prefix}] ${e}`),t.error?`
|
|
153
153
|
${v.red(t.error)}`:""):console.debug(v.gray(e),t?.error?`
|
|
154
154
|
${v.red(t.error)}`:"")}static step(e,t){}static header(e){console.debug(),console.debug(v.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 ql(s){s.command("open").description("Open the workspace in the browser").addHelpText("after",["","Examples:"," membrane open # Open workspace in browser",""].join(`
|
|
155
|
-
`)).action(async()=>{try{j.header("Opening Workspace in Browser"),j.info("Loading configuration...");const e=Kt();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");j.info("Retrieving workspace ID...");const t=await mr(process.cwd()),n=`${e.consoleUri||ya}/w/${t}`;j.info(`Opening ${n}...`);const{default:r}=await import("open");await r(n),j.success("Browser opened successfully")}catch(e){e instanceof Error&&(j.error(e.message),process.exit(1)),j.error("An unknown error occurred"),process.exit(1)}})}c(ql,"setupOpenCommand");async function js(s,e,t={}){const{jobId:n,accessKey:r}=await e(),i=`${n}:${r}`;b.debug(`[background-job] Started job ${n}`);const o=Date.now(),{pollIntervalMs:a=1e3,timeoutMs:l=3e5,maxRetries:u=3}=t;let f=0;for(;;){if(Date.now()-o>l)throw new Error(`Background job ${n} timed out after ${l}ms`);await new Promise(g=>setTimeout(g,a));let h;try{h=await s.get(`background-jobs/${i}`),f=0}catch(g){if(g instanceof xo&&f<u){f++,b.debug(`[background-job] Job ${n} not found, retrying (${f}/${u})`);continue}throw g}if(h.status==="completed"){if(b.debug(`[background-job] Completed job ${n}`),!h.result)throw new Error(`Background job ${n} completed but returned no result`);return h.result}if(h.status==="failed"){const g=h.
|
|
156
|
-
`)}`),new Error(`Background job ${n} failed: ${g}`)}b.debug(`[background-job] Polling job ${n} (status: ${h.status})`)}}c(js,"pollBackgroundJob");function Ul(s,e){_s(x.dirname(s)),O.writeFileSync(s,e)}c(Ul,"writeFile");function Jl(s){O.existsSync(s)&&O.rmSync(s)}c(Jl,"deleteFile");function ro(s){O.existsSync(s)&&O.rmSync(s,{recursive:!0,force:!0})}c(ro,"deleteDir");function Wl(s,e=!0){if(O.existsSync(s))try{const t=O.readFileSync(s,"utf8");return ue.load(t)||void 0}catch(t){if(!e)return;if(t instanceof Error){const n=x.relative(process.cwd(),s);throw new Error(`Failed to parse YAML file "${n}": ${t.message}`)}throw t}}c(Wl,"readYaml");function io(s,e,t){try{_s(x.dirname(s));const n=ue.dump(e,t);O.writeFileSync(s,n,"utf8")}catch(n){if(n instanceof Error){const r=x.relative(process.cwd(),s);throw new Error(`Failed to write YAML file "${r}": ${n.message}`)}throw n}return e}c(io,"writeYaml");function _s(s){O.existsSync(s)||O.mkdirSync(s,{recursive:!0})}c(_s,"ensureDirExists");function oo(s,e=!0){if(!O.existsSync(s)||!O.statSync(s).isDirectory())return;let t=O.readdirSync(s);t.length>0&&(t.forEach(n=>oo(x.join(s,n),!1)),t=O.readdirSync(s)),t.length===0&&!e&&O.rmdirSync(s)}c(oo,"cleanupEmptyFolders");function Vl(s){const e=s.split(/[\\/]/).join("/");return e.endsWith("/")?e+"**":e}c(Vl,"normalizePattern");async function ao(s,e=[]){return new Promise(async(t,n)=>{const r=e.map(Vl),i=nr("zip",{zlib:{level:9}}),o=[];i.on("data",l=>o.push(l)),i.on("end",()=>t(Buffer.concat(o))),i.on("error",l=>n(l));const a=new Map;for(const l of s[N.Integration]||[])a.set(l.uuid,l.key);for(const[l,u]of Object.entries(s))for(const f of u){const d=f.key,h=a.get(f.integrationUuid),g=Po(l,d,h);if(r.length>0&&!r.some(p=>na(g,p)))continue;const y=ue.dump(f);i.append(y,{name:g})}i.finalize()})}c(ao,"createMembraneZip");async function Fs(s,e){const t=await ar.loadAsync(s),n=[];for(const[r,i]of Object.entries(t.files)){if(i.dir)continue;const o=Re(r);if(!o)continue;const a=await i.async("string"),l=ue.load(a);if(!l)continue;const u=await e(r,l,o);u!==void 0&&n.push(u)}return n}c(Fs,"iterateZipItems");async function Gl(s){const e=await ar.loadAsync(s),t={};for(const[n,r]of Object.entries(e.files)){if(r.dir)continue;const i=Re(n);if(!i)continue;const o=await r.async("string"),a=ue.load(o);t[i.type]||(t[i.type]=[]),t[i.type].push(a)}return t}c(Gl,"readMembraneZip");async function co(s=process.cwd()){const e=await lo(ie(s)),t={};for(const{data:n,type:r}of e)t[r]||(t[r]=[]),t[r].push(n);return t}c(co,"readMembraneDir");async function lo(s){const e=uo(s),t=[];for(const n of e){if(n.isDirectory())continue;const r=Re(n.path);if(!r)continue;const i=await n.readContent(),o=ue.load(i),a=x.join(s,n.path);t.push({filePath:a,data:o,type:r.type})}return t}c(lo,"iterateMembraneFiles");function uo(s,e){const t=[];if(e||(e=s),!O.existsSync(e)||e.startsWith(x.join(s,"connectors")))return t;const n=O.readdirSync(e,{withFileTypes:!0});for(const r of n){const i=x.join(e,r.name),o=x.relative(s,i);r.isDirectory()?t.push(...uo(s,i)):r.isFile()&&Re(o)&&t.push({path:o,isDirectory:c(()=>!1,"isDirectory"),readContent:c(async()=>O.readFileSync(i,"utf8"),"readContent")})}return t}c(uo,"getMembraneFiles");function fo(){const s={},e=x.join(ie(process.cwd()),"connectors");if(!O.existsSync(e))return s;const t=O.readdirSync(e);for(const n of t){const r=x.join(e,n);if(!O.statSync(r).isDirectory())continue;const i=x.join(r,`${n}.yml`),o=Wl(i,!1);if(!o?.uuid)continue;const a=new Set,l=O.readdirSync(r);for(const u of l){if(u.endsWith(".yml"))continue;const f=x.join(r,u);O.statSync(f).isDirectory()&&a.add(u=="development"?"":u)}s[o.uuid]={key:n,id:o.id,versions:Array.from(a)}}return s}c(fo,"readConnectorsDir");function Tn(s,e){const t=x.join(ie(process.cwd()),"connectors",s);return e==""||e===Ys?x.join(t,"development"):e?x.join(t,e):t}c(Tn,"getConnectorPath");const ho=300,po=6e4;async function zl(){const s=await D.withClient(async t=>js(t,()=>t.get("export"),{pollIntervalMs:ho,timeoutMs:po}));if(!s)throw new Error("Failed to export workspace");const e=await Ct.get(s.downloadUrl,{responseType:"arraybuffer"});return Buffer.from(e.data)}c(zl,"downloadWorkspaceExport");async function mo(s,e={}){const t=new sr;t.append("file",s,{filename:"membrane.zip",contentType:"application/zip"});const n=await D.withClient(async i=>{const o=`import?dryRun=${e.dryRun??!1}&partial=${e.partial??!1}`,{jobId:a,accessKey:l}=await i.post(o,t,{headers:t.getHeaders()});return js(i,()=>Promise.resolve({jobId:a,accessKey:l}),{pollIntervalMs:1e3,timeoutMs:3e5})});if(!n)throw new Error("Failed to import workspace");const r={};for(const[i,o]of Object.entries(n))r[i]=new Set(o||[]);return r}c(mo,"importWorkspace");async function Hl(s,e){const t=await D.withClient(async r=>js(r,()=>r.get(`connectors/${s}/export-files`,{version:e}),{pollIntervalMs:ho,timeoutMs:po}));if(!t)throw new Error("Failed to export connector version");const n=await Ct.get(t.downloadUrl,{responseType:"arraybuffer"});return Buffer.from(n.data)}c(Hl,"exportConnector");const go=5;function Yl(s){s.command("pull").description("Pull workspace data from specified workspace").option("--force","Overwrite conflicts with remote data",!1).addHelpText("after",["","Examples:"," membrane pull # Pull from default workspace"," membrane pull --force # Overwrite conflicts with remote data",""].join(`
|
|
155
|
+
`)).action(async()=>{try{j.header("Opening Workspace in Browser"),j.info("Loading configuration...");const e=Kt();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");j.info("Retrieving workspace ID...");const t=await mr(process.cwd()),n=`${e.consoleUri||ya}/w/${t}`;j.info(`Opening ${n}...`);const{default:r}=await import("open");await r(n),j.success("Browser opened successfully")}catch(e){e instanceof Error&&(j.error(e.message),process.exit(1)),j.error("An unknown error occurred"),process.exit(1)}})}c(ql,"setupOpenCommand");async function js(s,e,t={}){const{jobId:n,accessKey:r}=await e(),i=`${n}:${r}`;b.debug(`[background-job] Started job ${n}`);const o=Date.now(),{pollIntervalMs:a=1e3,timeoutMs:l=3e5,maxRetries:u=3}=t;let f=0;for(;;){if(Date.now()-o>l)throw new Error(`Background job ${n} timed out after ${l}ms`);await new Promise(g=>setTimeout(g,a));let h;try{h=await s.get(`background-jobs/${i}`),f=0}catch(g){if(g instanceof xo&&f<u){f++,b.debug(`[background-job] Job ${n} not found, retrying (${f}/${u})`);continue}throw g}if(h.status==="completed"){if(b.debug(`[background-job] Completed job ${n}`),!h.result)throw new Error(`Background job ${n} completed but returned no result`);return h.result}if(h.status==="failed"){const g=h.error?.message||"Unknown error";throw b.error(`[background-job] Failed job ${n}: ${g}`),h.error?.stack&&b.error(`Stacktrace: ${h.error.stack}`),new Error(`Background job ${n} failed: ${g}`)}b.debug(`[background-job] Polling job ${n} (status: ${h.status})`)}}c(js,"pollBackgroundJob");function Ul(s,e){_s(x.dirname(s)),O.writeFileSync(s,e)}c(Ul,"writeFile");function Jl(s){O.existsSync(s)&&O.rmSync(s)}c(Jl,"deleteFile");function ro(s){O.existsSync(s)&&O.rmSync(s,{recursive:!0,force:!0})}c(ro,"deleteDir");function Wl(s,e=!0){if(O.existsSync(s))try{const t=O.readFileSync(s,"utf8");return ue.load(t)||void 0}catch(t){if(!e)return;if(t instanceof Error){const n=x.relative(process.cwd(),s);throw new Error(`Failed to parse YAML file "${n}": ${t.message}`)}throw t}}c(Wl,"readYaml");function io(s,e,t){try{_s(x.dirname(s));const n=ue.dump(e,t);O.writeFileSync(s,n,"utf8")}catch(n){if(n instanceof Error){const r=x.relative(process.cwd(),s);throw new Error(`Failed to write YAML file "${r}": ${n.message}`)}throw n}return e}c(io,"writeYaml");function _s(s){O.existsSync(s)||O.mkdirSync(s,{recursive:!0})}c(_s,"ensureDirExists");function oo(s,e=!0){if(!O.existsSync(s)||!O.statSync(s).isDirectory())return;let t=O.readdirSync(s);t.length>0&&(t.forEach(n=>oo(x.join(s,n),!1)),t=O.readdirSync(s)),t.length===0&&!e&&O.rmdirSync(s)}c(oo,"cleanupEmptyFolders");function Vl(s){const e=s.split(/[\\/]/).join("/");return e.endsWith("/")?e+"**":e}c(Vl,"normalizePattern");async function ao(s,e=[]){return new Promise(async(t,n)=>{const r=e.map(Vl),i=nr("zip",{zlib:{level:9}}),o=[];i.on("data",l=>o.push(l)),i.on("end",()=>t(Buffer.concat(o))),i.on("error",l=>n(l));const a=new Map;for(const l of s[N.Integration]||[])a.set(l.uuid,l.key);for(const[l,u]of Object.entries(s))for(const f of u){const d=f.key,h=a.get(f.integrationUuid),g=Po(l,d,h);if(r.length>0&&!r.some(p=>na(g,p)))continue;const y=ue.dump(f);i.append(y,{name:g})}i.finalize()})}c(ao,"createMembraneZip");async function Fs(s,e){const t=await ar.loadAsync(s),n=[];for(const[r,i]of Object.entries(t.files)){if(i.dir)continue;const o=Re(r);if(!o)continue;const a=await i.async("string"),l=ue.load(a);if(!l)continue;const u=await e(r,l,o);u!==void 0&&n.push(u)}return n}c(Fs,"iterateZipItems");async function Gl(s){const e=await ar.loadAsync(s),t={};for(const[n,r]of Object.entries(e.files)){if(r.dir)continue;const i=Re(n);if(!i)continue;const o=await r.async("string"),a=ue.load(o);t[i.type]||(t[i.type]=[]),t[i.type].push(a)}return t}c(Gl,"readMembraneZip");async function co(s=process.cwd()){const e=await lo(ie(s)),t={};for(const{data:n,type:r}of e)t[r]||(t[r]=[]),t[r].push(n);return t}c(co,"readMembraneDir");async function lo(s){const e=uo(s),t=[];for(const n of e){if(n.isDirectory())continue;const r=Re(n.path);if(!r)continue;const i=await n.readContent(),o=ue.load(i),a=x.join(s,n.path);t.push({filePath:a,data:o,type:r.type})}return t}c(lo,"iterateMembraneFiles");function uo(s,e){const t=[];if(e||(e=s),!O.existsSync(e)||e.startsWith(x.join(s,"connectors")))return t;const n=O.readdirSync(e,{withFileTypes:!0});for(const r of n){const i=x.join(e,r.name),o=x.relative(s,i);r.isDirectory()?t.push(...uo(s,i)):r.isFile()&&Re(o)&&t.push({path:o,isDirectory:c(()=>!1,"isDirectory"),readContent:c(async()=>O.readFileSync(i,"utf8"),"readContent")})}return t}c(uo,"getMembraneFiles");function fo(){const s={},e=x.join(ie(process.cwd()),"connectors");if(!O.existsSync(e))return s;const t=O.readdirSync(e);for(const n of t){const r=x.join(e,n);if(!O.statSync(r).isDirectory())continue;const i=x.join(r,`${n}.yml`),o=Wl(i,!1);if(!o?.uuid)continue;const a=new Set,l=O.readdirSync(r);for(const u of l){if(u.endsWith(".yml"))continue;const f=x.join(r,u);O.statSync(f).isDirectory()&&a.add(u=="development"?"":u)}s[o.uuid]={key:n,id:o.id,versions:Array.from(a)}}return s}c(fo,"readConnectorsDir");function Tn(s,e){const t=x.join(ie(process.cwd()),"connectors",s);return e==""||e===Ys?x.join(t,"development"):e?x.join(t,e):t}c(Tn,"getConnectorPath");const ho=300,po=6e4;async function zl(){const s=await D.withClient(async t=>js(t,()=>t.get("export"),{pollIntervalMs:ho,timeoutMs:po}));if(!s)throw new Error("Failed to export workspace");const e=await Ct.get(s.downloadUrl,{responseType:"arraybuffer"});return Buffer.from(e.data)}c(zl,"downloadWorkspaceExport");async function mo(s,e={}){const t=new sr;t.append("file",s,{filename:"membrane.zip",contentType:"application/zip"});const n=await D.withClient(async i=>{const o=`import?dryRun=${e.dryRun??!1}&partial=${e.partial??!1}`,{jobId:a,accessKey:l}=await i.post(o,t,{headers:t.getHeaders()});return js(i,()=>Promise.resolve({jobId:a,accessKey:l}),{pollIntervalMs:1e3,timeoutMs:3e5})});if(!n)throw new Error("Failed to import workspace");const r={};for(const[i,o]of Object.entries(n))r[i]=new Set(o||[]);return r}c(mo,"importWorkspace");async function Hl(s,e){const t=await D.withClient(async r=>js(r,()=>r.get(`connectors/${s}/export-files`,{version:e}),{pollIntervalMs:ho,timeoutMs:po}));if(!t)throw new Error("Failed to export connector version");const n=await Ct.get(t.downloadUrl,{responseType:"arraybuffer"});return Buffer.from(n.data)}c(Hl,"exportConnector");const go=5;function Yl(s){s.command("pull").description("Pull workspace data from specified workspace").option("--force","Overwrite conflicts with remote data",!1).addHelpText("after",["","Examples:"," membrane pull # Pull from default workspace"," membrane pull --force # Overwrite conflicts with remote data",""].join(`
|
|
157
156
|
`)).action(async e=>{const t=or({text:"Pulling workspace",color:"white"}).start();try{const n=await Zl(e,t);t.stop(),eu(n.workspaceExport,n.connectors)}catch(n){t.stop(),nu(n),process.exit(1)}})}c(Yl,"setupPullCommand");async function Zl(s,e){const t=await co(),n=await ao(t),r=await zl(),i=await Gl(r),{comparison:o}=Lo(t,i);o[we.DELETE].size>0&&!s.force&&(await tu(o,n),j.error("Use --force to delete local elements"),process.exit(1));const l=await lo(ie(process.cwd()));for(const{filePath:f,data:d}of l)o[we.DELETE].has(d.uuid)&&Jl(f);return oo(ie(process.cwd())),await Fs(r,(f,d)=>{if(Re(f)&&(o[we.CREATE].has(d.uuid)||o[we.UPDATE].has(d.uuid))){const g=_.join(ie(process.cwd()),f);io(g,d)}}),{connectors:await Ql(i[N.Integration],e),workspaceExport:i}}c(Zl,"pullWorkspace");async function Ql(s,e){e.text="Pulling connectors";const t=new Map,{id:n}=await D.withClient(u=>u.get("org-workspace-id")),{items:r=[]}=await D.withClient(u=>u.get(`/connectors?workspaceId=${n}`));for(const u of r){const f=u.uuid??u.id;!u.isPublic&&f&&t.set(f,new Set([""]))}for(const u of s??[]){const{connectorUuid:f,connectorVersion:d}=u;f&&(t.has(f)||t.set(f,new Set),t.get(f).add(d??""))}const i=fo();for(const[u,{key:f,versions:d}]of Object.entries(i)){if(!t.has(u)){const g=Tn(f);ro(g);continue}const h=t.get(u);for(const g of d)if(!h.has(g)){const y=Tn(f,g);ro(y)}}const o=Array.from(t.entries()),a=o.length,l=c((u,f)=>{u==="pulling"?e.start(`Pulling connector ${f}...`):e.succeed(`Pulled connector ${f}`)},"onProgress");for(let u=0;u<a;u+=go){const f=o.slice(u,u+go);await Promise.all(f.map(([d,h])=>Xl(d,Array.from(h),l)))}return Array.from(t.keys())}c(Ql,"pullConnectors");async function Xl(s,e,t){const n=await D.withClient(u=>u.get(`connectors/${s}/export-json`),!1),r=await D.withClient(u=>u.get(`connectors/${s}`),!1);if(!n||!r||!n.key||!r.key)return;const i=r.name||n.key;t?.("pulling",i);const o={...n,id:r.id,uuid:r.uuid},a=Tn(n.key),l=_.join(a,`${n.key}.yml`);io(l,o);for(const u of e){const f=await Hl(s,u),d=Tn(n.key,u);if(Ul(_.join(d,"src.zip"),f),!u||u===Ys){const h=_.join(d,"src");_s(h),await(await rr.Open.buffer(f)).extract({path:h})}}t?.("pulled",i)}c(Xl,"pullConnector");function eu(s,e=[]){const t=Object.values(s).reduce((n,r)=>n+(r?.length??0),0)+e.length;j.info(`\u25CF Pulled workspace elements \xB7 ${t}`);for(const n of Object.keys(s).sort()){const r=s[n];j.info(`\u2514\u2500\u2500 ${n}s \xB7 ${r?.length??0}`)}e.length>0&&j.info(`\u2514\u2500\u2500 connectors \xB7 ${e.length}`)}c(eu,"showStats$1");async function tu(s,e){const t=s[we.DELETE].size;j.info(`\u2299 Pull: conflicts detected \xB7 ${t}`),await Fs(e,(n,r)=>{Re(n)&&s[we.DELETE].has(r.uuid)&&j.info(`\u2514\u2500\u2500 ./membrane/${n} (deleted in remote)`)})}c(tu,"showConflicts$1");async function nu(s){j.error("\u25A0 Error"),j.error(`\u2514\u2500\u2500 ${s.message}`),j.error(` ${s.stack}`)}c(nu,"showError$1");const Q=[];for(let s=0;s<256;++s)Q.push((s+256).toString(16).slice(1));function su(s,e=0){return(Q[s[e+0]]+Q[s[e+1]]+Q[s[e+2]]+Q[s[e+3]]+"-"+Q[s[e+4]]+Q[s[e+5]]+"-"+Q[s[e+6]]+Q[s[e+7]]+"-"+Q[s[e+8]]+Q[s[e+9]]+"-"+Q[s[e+10]]+Q[s[e+11]]+Q[s[e+12]]+Q[s[e+13]]+Q[s[e+14]]+Q[s[e+15]]).toLowerCase()}c(su,"unsafeStringify");let Ks;const ru=new Uint8Array(16);function iu(){if(!Ks){if(typeof crypto>"u"||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");Ks=crypto.getRandomValues.bind(crypto)}return Ks(ru)}c(iu,"rng");const ou=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto);var yo={randomUUID:ou};function au(s,e,t){if(yo.randomUUID&&!s)return yo.randomUUID();s=s||{};const n=s.random??s.rng?.()??iu();if(n.length<16)throw new Error("Random bytes length must be >= 16");return n[6]=n[6]&15|64,n[8]=n[8]&63|128,su(n)}c(au,"v4");function cu(s){s.command("push").description("Push workspace data to specified workspace").argument("[files...]","Files, directories, or glob patterns to push").option("--force","Overwrite conflicts with local data",!1).addHelpText("after",["","Examples:"," membrane push # Push all workspace elements"," membrane push data-sources/ # Push all data-sources"," membrane push actions/my-action/spec.yaml # Push specific action"," membrane push flows/*-test/spec.yaml # Push flows matching pattern"," membrane push --force # Overwrite conflicts with local data",""].join(`
|
|
158
157
|
`)).action(async(e,t)=>{const n=or({text:"Pushing workspace",color:"white"}).start();try{await lu(e,t,n)}catch(r){n.stop(),mu(r),process.exit(1)}})}c(cu,"setupPushCommand");async function lu(s,e,t){const n=s.length>0,r=await co(),i=fo(),o=uu(r,i),a=await ao(o,n?s:void 0);t.text="Comparing workspace";const l=await mo(a,{dryRun:!0,partial:n});l[we.DELETE].size>0&&!e.force&&(t.stop(),await pu(l,a),j.error("Use --force to delete remote elements"),process.exit(1));const{pushedConnectors:f=[]}=await Wi({onProgress:c((d,h)=>{d==="pushing"?t.start(`Pushing connector ${h}...`):t.succeed(`Pushed connector ${h}`)},"onProgress")});t.start("Pushing workspace..."),await mo(a,{partial:n}),t.stop(),hu(o,f),process.exit(0)}c(lu,"pushWorkspace");function uu(s,e){const t=fu(s),n=du(t,e),r={};for(const[i,o]of Object.entries(t)){const a=i,l=ye[a]?.parentFieldKey||"parentId";r[a]=(o||[]).map(u=>{const f={...u};if(f.integrationId&&!f.integrationUuid&&(f.integrationUuid=n.get(f.integrationId.toString())||f.integrationId,delete f.integrationId),f.connectorId){if(!f.connectorUuid){const d=n.get(f.connectorId.toString());d&&(f.connectorUuid=d)}delete f.connectorId}if(f[l]){const d=f[l].toString();f.parentUuid=n.get(d)||d}return a===N.Package&&f.elements&&(f.elements=f.elements.map(d=>{if(d.id&&!d.uuid){const h=n.get(d.id.toString());if(h)return{uuid:h,type:d.type}}return d})),delete f.id,f})}return r}c(uu,"resolveLegacyIdReferences");function fu(s){const e={};for(const[t,n]of Object.entries(s))e[t]=(n||[]).map(r=>r.uuid?r:{...r,uuid:au()});return e}c(fu,"generateMissingUuids");function du(s,e){const t=new Map;for(const n of Object.values(s))for(const r of n||[])r.id&&r.uuid&&t.set(r.id.toString(),r.uuid);for(const[n,r]of Object.entries(e))r.id&&t.set(r.id.toString(),n);return t}c(du,"buildIdToUuidLookup");function hu(s,e=[]){const t=Object.values(s).reduce((n,r)=>n+(r?.length??0),0)+e.length;j.info(`\u25CF Pushed workspace elements \xB7 ${t}`);for(const n of Object.keys(s).sort()){const r=s[n];j.info(`\u2514\u2500\u2500 ${n}s \xB7 ${r?.length??0}`)}e.length>0&&j.info(`\u2514\u2500\u2500 connectors \xB7 ${e.length}`)}c(hu,"showStats");async function pu(s,e){const t=s[we.DELETE].size;j.info(`\u2299 Push: conflicts detected \xB7 ${t}`),await Fs(e,(n,r)=>{Re(n)&&s[we.DELETE].has(r.uuid)&&j.info(`\u2514\u2500\u2500 ./membrane/${n} (deleted locally)`)})}c(pu,"showConflicts");async function mu(s){j.error("\u25A0 Error"),j.error(`\u2514\u2500\u2500 ${s.message}`),j.error(` ${s.stack}`)}c(mu,"showError");const Bs=[{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=x.join(process.cwd(),".mcp.json"),e={mcpServers:{membrane:{command:"membrane",args:["mcp"],env:{AGENT_NAME:"Claude Code"}}}};let t={};if(O.existsSync(s))try{t=JSON.parse(O.readFileSync(s,"utf8"))}catch{t={}}const n={...t,mcpServers:{...t.mcpServers,...e.mcpServers}};return O.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=x.join(process.cwd(),".cursor"),e=x.join(s,"mcp.json");O.existsSync(s)||O.mkdirSync(s);const t={mcpServers:{membrane:{command:"membrane",args:["mcp"],env:{AGENT_NAME:"Cursor"}}}};let n={};if(O.existsSync(e))try{n=JSON.parse(O.readFileSync(e,"utf8"))}catch{n={}}const r={...n,mcpServers:{...n.mcpServers,...t.mcpServers}};return O.writeFileSync(e,JSON.stringify(r,null,2)),`MCP server configuration added to ${e}`},"addConfig")}];function gu({onExit:s,onComplete:e}){const[t,n]=q(0),[r,i]=q(!1),[o,a]=q(null),[l,u]=q(""),[f,d]=q("");Me((y,p)=>{if(l||f){(p.escape||y==="q"||p.return)&&e();return}if(r)p.return||y===" "?h(o):p.escape&&(i(!1),a(null));else if(p.escape)s();else if(p.upArrow||y==="k")n(Math.max(0,t-1));else if(p.downArrow||y==="j")n(Math.min(Bs.length-1,t+1));else if(p.return||y===" "){const w=Bs[t];a(w),i(!0)}});const h=c(y=>{try{const p=y.addConfig();u(p)}catch(p){d(`Failed to write configuration: ${p.message||p}`)}},"addMcpConfiguration"),g=Math.min(80,process.stdout.columns||80);return l?T(S,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:g,children:[m(S,{marginTop:-1,marginBottom:1,children:T(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",m(C,{color:"green",children:"Success"})]})}),T(S,{flexDirection:"column",paddingLeft:2,children:[m(C,{color:"green",children:l}),m(S,{marginTop:1,children:m(C,{color:"grey",children:"The agent will now be able to use Membrane's integration capabilities."})})]}),m(S,{marginTop:1,paddingLeft:2,children:m(C,{color:"white",children:"[esc/q/enter: exit]"})})]}):f?T(S,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:g,children:[m(S,{marginTop:-1,marginBottom:1,children:T(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",m(C,{color:"red",children:"Error"})]})}),m(S,{flexDirection:"column",paddingLeft:2,children:m(C,{color:"red",children:f})}),m(S,{marginTop:1,children:m(C,{color:"grey",children:"[esc/q/enter: exit]"})})]}):r&&o?T(S,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:g,children:[m(S,{marginTop:-1,marginBottom:1,children:T(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",m(C,{color:"cyan",children:"Confirmation"})]})}),T(S,{flexDirection:"column",paddingLeft:2,children:[T(C,{children:["Connect ",m(C,{bold:!0,children:o.name})," to Membrane via MCP?"]}),m(S,{marginTop:1,children:m(C,{color:"grey",children:"This will add an MCP server configuration that allows the agent to use Membrane's integration capabilities."})}),m(S,{marginTop:1,children:m(C,{color:"yellow",bold:!0,children:o.actionDescription})}),m(S,{marginTop:2,marginBottom:1,children:T(C,{children:[m(C,{color:"white",bold:!0,children:"[Enter] Confirm"})," ",m(C,{color:"gray",children:"[Esc] Cancel"})]})})]})]}):T(S,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:g,children:[m(S,{marginTop:-1,marginBottom:1,children:T(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",m(C,{color:"cyan",children:"Select Agent"})]})}),T(S,{flexDirection:"column",paddingLeft:2,children:[m(C,{color:"grey",children:"Choose an agent to connect to Membrane via MCP:"}),m(S,{marginTop:1,children:m(C,{color:"grey",children:"This will add an MCP server configuration that allows the agent to use Membrane's integration capabilities."})}),m(S,{marginTop:1,flexDirection:"column",children:Bs.map((y,p)=>T(S,{children:[T(C,{color:t===p?"cyan":"white",children:[t===p?"\u25B6 ":" ",y.name]}),T(C,{color:"grey",children:[" \u2014 ",y.description]})]},y.id))})]}),m(S,{marginTop:1,children:m(C,{color:"grey",children:"[\u2191\u2193: select] [enter: choose] [esc: exit]"})})]})}c(gu,"AddMcpServerScreen");function yu(){const[s,e]=q(null),[t,n]=q([]),[r,i]=q(null);return ze(()=>{const o=c(({status:l})=>{e(l),i(null)},"handleMcpStatusChanged"),a=c(({servers:l})=>{n(l),i(null)},"handleMcpServersChanged");return Ne.on(H.McpStatusChanged,o),Ne.on(H.McpServersChanged,a),()=>{Ne.off(H.McpStatusChanged,o),Ne.off(H.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(yu,"useMcpStatus");function wu(){const{error:s,serverCount:e,allMcpServers:t}=yu(),n=Math.min(100,process.stdout.columns||100);return T(S,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:n,children:[m(S,{marginTop:-1,marginBottom:0,flexDirection:"column",children:T(C,{bold:!0,children:["\u{1F916} Connected AI Agents:"," ",s?m(C,{color:"red",children:"error reading status"}):e===0?m(C,{color:"yellow",children:"none"}):m(C,{color:"green",children:e})]})}),!s&&e===0&&m(S,{marginTop:1,children:T(C,{color:"grey",children:["Connect your AI agents to Membrane.",m(Ko,{}),"It will give them tools and context to build integrations."]})}),t.length>0&&m(S,{flexDirection:"column",paddingLeft:2,marginTop:1,children:t.map((r,i)=>m(S,{children:T(C,{color:"grey",children:["#",i+1," ",r.agentName,": ",r.totalRequests," calls"]})},r.processId))}),m(S,{marginTop:1,children:m(C,{color:"grey",children:"[a: connect an agent]"})})]})}c(wu,"Agent");const wo=c(s=>{switch(s){case"error":return"red";case"success":return"green";case"warning":return"yellow";default:return}},"getLogColor");function bo(s,e){return e<3?s.slice(0,Math.max(0,e)):s.length<=e?s:`${s.slice(0,e-3)}...`}c(bo,"truncateText");function bu({children:s}){const{state:e,logs:t}=he();return!e||e===M.NOT_INITIALIZED?T(S,{gap:1,flexDirection:"row",children:[m(ea,{type:"dots"}),m(C,{children:"Initializing..."})]}):e===M.SETTING_UP?m(S,{gap:1,flexDirection:"row",children:m(C,{children:"No workspace selected. Please run `membrane init` to select a workspace."})}):e===M.ERROR?m(S,{flexDirection:"column",children:t.slice().map((n,r)=>m(C,{color:wo(n.type),children:n.message},n.timestamp+r))}):s}c(bu,"EnsureInitialized");function Su(){const{stats:s}=he(),e=Object.entries(s).filter(([t,n])=>n>0);return e.length===0?null:T(S,{flexDirection:"column",children:[m(S,{children:m(S,{width:12,children:m(C,{color:"grey",children:"Elements:"})})}),m(S,{flexDirection:"column",marginLeft:1,children:e.map(([t,n])=>T(S,{children:[m(S,{width:20,children:T(C,{children:[t,":"]})}),m(C,{color:"green",children:n})]},t))})]})}c(Su,"ElementStats");const qs=5,Cu=6;function vu(){const{logs:s}=he(),[e,t]=q(0),n=Math.min(100,process.stdout.columns||100),r=qs,i=Math.max(0,s.length-r-e),o=s.length-e,a=s.slice(i,o),l=n-Cu,u=e<s.length-r,f=e>0;return Me((d,h)=>{if(s.length!==0)if(h.upArrow){const g=Math.max(0,s.length-r);t(y=>Math.min(g,y+1))}else h.downArrow?t(g=>Math.max(0,g-1)):(d==="G"||d==="g")&&t(0)}),T(S,{flexDirection:"column",paddingTop:1,children:[T(C,{color:"grey",children:["Recent Activity (",i+1,"-",o," of ",s.length,"):",s.length>qs&&m(C,{color:"grey",children:" [arrows: scroll] [g: end]"})]}),a.map((d,h)=>m(S,{marginLeft:1,children:m(C,{color:wo(d.type),children:bo(d.message,l)})},d.timestamp+h)),s.length>qs&&T(S,{marginLeft:1,flexDirection:"row",children:[u&&m(C,{color:"grey",children:"\u2191 "}),f&&m(C,{color:"grey",children:"\u2193 "})]})]})}c(vu,"Logs");const In=[{value:"sync",label:"Continue (overwrite/delete)",key:""},{value:"exit",label:"Cancel",key:""}];function ku(){const{state:s,resolveConflicts:e,exit:t}=he(),[n,r]=q(0),[i,o]=q(!1),[a,l]=q(!1);return Me((u,f)=>{if(!i){if(f.ctrl&&u.toLowerCase()==="r"){l(!a);return}f.upArrow?r(d=>d>0?d-1:In.length-1):f.downArrow?r(d=>d<In.length-1?d+1:0):u.toLowerCase()==="y"?r(0):u.toLowerCase()==="n"?r(1):(f.return||u===" ")&&(o(!0),In[n].value==="sync"?e({watch:!0}):t())}}),ze(()=>{s!==M.CONFLICTS&&i&&o(!1)},[s,i]),T(S,{flexDirection:"column",paddingTop:1,children:[m(S,{children:m(S,{flexDirection:"row",gap:2,children:m(C,{bold:!0,color:"white",children:"Conflicts with remote"})})}),m(S,{children:m(C,{color:"grey",children:"The remote workspace has changes that aren't in your local workspace:"})}),m(S,{marginTop:1,marginLeft:2,children:m(Tu,{isExpanded:a})}),T(S,{marginTop:2,flexDirection:"row",gap:1,children:[m(C,{color:"white",bold:!0,children:"What would you like to do?"}),m(C,{color:"grey",children:"[up/down, enter]"})]}),m(S,{children:i?T(S,{flexDirection:"row",gap:1,children:[m(_t,{type:"dots"}),m(C,{color:"blue",bold:!0,children:"Syncing with remote..."})]}):m(S,{flexDirection:"column",children:In.map((u,f)=>m(S,{flexDirection:"column",children:T(S,{flexDirection:"row",gap:1,children:[m(C,{color:n===f?"cyan":"grey",children:n===f?"\u25B6":" "}),m(C,{color:n===f?"cyan":"grey",bold:n===f,children:u.label})]})},u.value))})})]})}c(ku,"ResolveChangesUI");const Eu={[be.UPDATE]:{incoming:{label:"Elements updated in remote",description:"(to be overwritten from remote)"},outgoing:{label:"Elements updated locally",description:"(to be pushed to remote)"}},[be.DELETE]:{incoming:{label:"Elements not existing in remote",description:"(to be deleted locally)"},outgoing:{label:"Elements deleted locally",description:"(to be deleted from remote)"}},[be.CREATE]:{incoming:{label:"Elements created in remote",description:"(to be created locally)"},outgoing:{label:"Elements created locally",description:"(to be created in remote)"}}};function Tu({isExpanded:s,showControls:e=!0}){const{conflicts:t}=he(),n=5,r=Fo(()=>{const i={};return t.forEach(o=>{const a=`${o.type}-${o.direction}`;i[a]||(i[a]=[]),i[a].push(o)}),i},[t]);return m(S,{flexDirection:"column",children:Object.entries(r).map(([i,o])=>{if(o.length===0)return null;const[a,l]=i.split("-"),u=Eu[a][l];return T(S,{flexDirection:"column",children:[T(S,{flexDirection:"row",gap:1,children:[T(C,{color:"yellow",children:[u.label," (",o.length,")"]}),m(C,{color:"white",children:u.description})]}),(s?o:o.slice(0,n)).map(f=>m(S,{marginLeft:2,children:T(C,{color:"grey",children:["\u2022 ",f.element.id," (",f.element.relativePath,")"]})},f.element.id)),!s&&o.length>n&&m(S,{marginLeft:2,children:T(C,{color:"cyan",children:["... and ",o.length-n," more",e?" (press Ctrl+R to show all)":""]})}),s&&o.length>n&&e&&m(S,{marginLeft:2,children:m(C,{color:"cyan",children:"(press Ctrl+R to collapse)"})})]},i)})})}c(Tu,"Conflicts");function Iu(){const{config:s,state:e,logs:t,currentWorkspace:n,pull:r}=he(),i=n?.name,o=i?bo(i,30):s?.workspaceKey,a=Math.min(100,process.stdout.columns||100);return ze(()=>{r({watch:!0})},[]),T(S,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:a,children:[m(S,{marginTop:-1,marginBottom:1,children:T(S,{flexDirection:"row",gap:1,children:[m(C,{bold:!0,children:"\u{1F504} Workspace"}),T(C,{color:Au(e),children:[" [",Ou(e),"] "]})]})}),T(S,{children:[m(S,{width:12,children:m(C,{color:"grey",children:"Local:"})}),m(C,{color:"grey",children:process.cwd()})]}),T(S,{children:[m(S,{width:12,children:m(C,{color:"grey",children:"Remote:"})}),s?.workspaceKey?T(C,{color:"grey",children:[o," [o: open in console] [w: change]"]}):T(C,{children:[m(C,{color:"yellow",children:"not selected"})," [w: select]"]})]}),e===M.CONFLICTS?m(ku,{}):T(jt,{children:[m(S,{paddingTop:1,children:m(Su,{})}),t.length>0&&m(vu,{})]})]})}c(Iu,"Workspace");function Ou(s){switch(s){case M.PULLING:return"pulling";case M.PUSHING:return"pushing";case M.CONFLICTS:return"conflicts";case M.SYNCED:return"synced";case M.ERROR:return"error";case M.WATCHING:return"tracking changes";case M.RESOLVING:return"resolving";case M.NOT_SYNCED:return"not synced";case M.INITIALIZED:return"initialized";case M.SETTING_UP:return"setup required";default:return"unknown"}}c(Ou,"getStatusDisplay");function Au(s){switch(s){case M.PULLING:return"yellow";case M.PUSHING:return"yellow";case M.CONFLICTS:return"red";case M.SYNCED:return"green";case M.ERROR:return"red";case M.WATCHING:return"green";case M.RESOLVING:return"yellow";case M.NOT_SYNCED:return"grey";case M.SETTING_UP:return"yellow";default:return"grey"}}c(Au,"getStatusColor");const $u="https://console.integration.app/w";function Nu(){const s=Al(),e=_n(!0),{exit:t,state:n}=he(),[r,i]=q(null),o=r??(n===M.SETTING_UP?"setup":"main");Me(l=>{o==="main"&&(l==="w"&&i("workspace-selection"),l==="a"&&i("add-mcp-server"),l==="o"&&n===M.INITIALIZED&&a(),l==="s"&&i("setup"))});async function a(){try{const l=await mr(s),u=`${$u}/${l}`,f=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";sa(`${f} "${u}"`)}catch(l){console.error("Failed to open workspace:",l),t()}}return c(a,"handleOpenWorkspace"),ze(()=>(e.current=!0,()=>{e.current=!1}),[]),o==="workspace-selection"?m(to,{onExit:c(()=>i(null),"onExit")}):o==="add-mcp-server"?m(gu,{onExit:c(()=>i(null),"onExit"),onComplete:c(()=>i(null),"onComplete")}):o==="setup"?m(no,{onComplete:c(()=>i(null),"onComplete")},Date.now()):m(bu,{children:T(S,{flexDirection:"column",children:[m(S,{flexGrow:1,children:m(wu,{})}),m(Iu,{}),m(S,{paddingLeft:2,children:m(C,{color:"grey",children:"[s: (re-)setup]"})})]})})}c(Nu,"Main");const xu=c(()=>[v.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"),v.yellow("\u2502 \u26A0\uFE0F EXPERIMENTAL FEATURE WARNING \u2502"),v.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"),v.yellow("\u2502 Real-time agent mode is experimental and subject to changes. \u2502"),v.yellow("\u2502 Use in production environments is not recommended. \u2502"),v.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(`
|
|
159
158
|
`),"createExperimentalWarning$1");function Pu(s,e){s.command("sync").description("\u26A0\uFE0F EXPERIMENTAL: Sync workspace data in real-time - This feature is experimental and subject to changes. Use in production environments is not recommended.").option("--watch","Watch for changes and sync automatically",!1).option("--rps <number>","Maximum requests per second (default: 80)",t=>parseInt(t,10)).addHelpText("after",["","Examples:"," membrane sync --watch # Start real-time sync with watch mode"," membrane sync --watch --rps 5 # Limit to 5 requests per second",""].join(`
|