lensmcp 1.25.17 → 1.25.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/bin.js +1 -1
  2. package/bundled/bridge.js +38 -37
  3. package/bundled/capture-runner.js +6 -6
  4. package/bundled/dashboard-ui/app.css +1 -1
  5. package/bundled/dashboard-ui/app.js +92 -92
  6. package/bundled/dashboard-ui/chunks/ReplayView-vO4p7cGp.js +131 -0
  7. package/bundled/dashboard.js +288 -279
  8. package/bundled/main.js +228 -221
  9. package/bundled/shim.js +8 -8
  10. package/lib/agent-asked.js +4 -4
  11. package/lib/agent-plugins.js +2 -2
  12. package/lib/bridge-origins.js +1 -1
  13. package/lib/call-command.js +2 -2
  14. package/lib/cli-help.js +3 -3
  15. package/lib/cli.js +12 -12
  16. package/lib/dashboard-login.d.ts +9 -2
  17. package/lib/dashboard-login.js +3 -3
  18. package/lib/dismiss-command.js +2 -2
  19. package/lib/duplicate-registration.js +1 -1
  20. package/lib/forward-signals.js +1 -1
  21. package/lib/gateway-registration.js +1 -1
  22. package/lib/guest-graph.js +4 -4
  23. package/lib/heap-analyzer-main.js +1 -1
  24. package/lib/heap-analyzer.js +1 -1
  25. package/lib/hook-memory.js +1 -1
  26. package/lib/instance-command.js +9 -9
  27. package/lib/instance-registry.js +2 -2
  28. package/lib/instance-resources.js +5 -5
  29. package/lib/instance-worktree.js +6 -6
  30. package/lib/lens-ignore.js +2 -2
  31. package/lib/lint-args.js +1 -1
  32. package/lib/logs-follow.js +1 -1
  33. package/lib/mcp-mode.js +3 -3
  34. package/lib/mcp-restart.js +1 -1
  35. package/lib/mcp-sessions.js +2 -2
  36. package/lib/mcp-token.js +3 -3
  37. package/lib/mcp-wiring.js +2 -2
  38. package/lib/mem-command.js +3 -3
  39. package/lib/perf-rules-check.js +4 -4
  40. package/lib/plugin-version.js +3 -3
  41. package/lib/pod-source-maps.js +1 -1
  42. package/lib/process-identity.js +1 -1
  43. package/lib/process-ownership.js +2 -2
  44. package/lib/project-files.js +1 -1
  45. package/lib/recycle-policy.js +1 -1
  46. package/lib/resp-client.js +5 -5
  47. package/lib/restart-command.js +2 -2
  48. package/lib/server-bundle.js +2 -2
  49. package/lib/status-client.js +2 -2
  50. package/lib/status-policy.js +2 -2
  51. package/lib/sweep.js +1 -1
  52. package/lib/upgrade.js +2 -2
  53. package/lib/workspace-scope.js +2 -2
  54. package/package.json +4 -4
  55. package/plugin/.claude-plugin/plugin.json +1 -1
  56. package/plugin/skills/dashboard/SKILL.md +2 -1
  57. package/plugin/skills/using-lensmcp/SKILL.md +28 -1
  58. package/plugin/skills/worktrees/SKILL.md +2 -1
  59. package/plugins/lensmcp/.codex-plugin/plugin.json +1 -1
  60. package/plugins/lensmcp/skills/lensmcp-dashboard/SKILL.md +2 -1
  61. package/plugins/lensmcp/skills/using-lensmcp/SKILL.md +27 -1
@@ -1 +1 @@
1
- "use strict";var d=Object.defineProperty;var r=(e,t)=>d(e,"name",{value:t,configurable:!0});var p=Object.defineProperty,s=r((e,t)=>p(e,"name",{value:t,configurable:!0}),"r"),u=Object.defineProperty,o=s((e,t)=>u(e,"name",{value:t,configurable:!0}),"s");import{DEFAULT_MCP_MODE as g}from"./mcp-mode.js";export function detectDuplicateRegistration(e){const t=new Set(e.disabledServers??[]),n=new Set(e.pluginServers),i=e.pluginEnabled?[...new Set(e.workspaceServers)].filter(l=>n.has(l)&&!t.has(l)):[];if(e.pluginReadable===!1)return{duplicated:!1,names:[],indeterminate:!0,detail:"could not read the plugin manifest \u2014 cannot tell whether the server is registered twice",hint:"run `lensmcp plugin status` to check the plugin install, then re-run doctor"};if(i.length===0)return{duplicated:!1,names:[],indeterminate:!1,detail:"one registration",hint:""};const a=i.join(", "),c=(e.mcpMode??g)==="shared"?`'${a}' is registered TWICE \u2014 once in this workspace's .mcp.json and once by the enabled Claude plugin. On shared MCP mode both routes proxy into the SAME server, so there is one event window; the cost is a redundant client shim per agent session.`:`'${a}' is registered TWICE \u2014 once in this workspace's .mcp.json and once by the enabled Claude plugin, so every agent session starts two servers (each with its own event window).`;return{duplicated:!0,names:i,indeterminate:!1,detail:c,hint:`Add "disabledMcpjsonServers": ["${i[0]}"] to .claude/settings.local.json to keep the plugin's copy, or remove the plugin (\`/plugin\` \u2192 uninstall) to keep the .mcp.json one. (settings.local.json is the file Claude Code itself writes these to.)`}}r(detectDuplicateRegistration,"detectDuplicateRegistration"),s(detectDuplicateRegistration,"detectDuplicateRegistration"),o(detectDuplicateRegistration,"detectDuplicateRegistration");export function mcpServerNames(e){const t=e?.mcpServers;return!t||typeof t!="object"||Array.isArray(t)?[]:Object.keys(t)}r(mcpServerNames,"mcpServerNames"),s(mcpServerNames,"mcpServerNames"),o(mcpServerNames,"mcpServerNames");export function pluginEnabledInSettings(e,t){const n=e?.enabledPlugins;return!n||typeof n!="object"?!1:n[t]===!0}r(pluginEnabledInSettings,"pluginEnabledInSettings"),s(pluginEnabledInSettings,"pluginEnabledInSettings"),o(pluginEnabledInSettings,"pluginEnabledInSettings");export function disabledMcpServers(e){const t=e?.disabledMcpjsonServers;return Array.isArray(t)?t.filter(n=>typeof n=="string"):[]}r(disabledMcpServers,"disabledMcpServers"),s(disabledMcpServers,"disabledMcpServers"),o(disabledMcpServers,"disabledMcpServers");
1
+ "use strict";var d=Object.defineProperty;var r=(e,t)=>d(e,"name",{value:t,configurable:!0});var c=Object.defineProperty,i=r((e,t)=>c(e,"name",{value:t,configurable:!0}),"s");import{DEFAULT_MCP_MODE as p}from"./mcp-mode.js";export function detectDuplicateRegistration(e){const t=new Set(e.disabledServers??[]),n=new Set(e.pluginServers),s=e.pluginEnabled?[...new Set(e.workspaceServers)].filter(a=>n.has(a)&&!t.has(a)):[];if(e.pluginReadable===!1)return{duplicated:!1,names:[],indeterminate:!0,detail:"could not read the plugin manifest \u2014 cannot tell whether the server is registered twice",hint:"run `lensmcp plugin status` to check the plugin install, then re-run doctor"};if(s.length===0)return{duplicated:!1,names:[],indeterminate:!1,detail:"one registration",hint:""};const o=s.join(", "),l=(e.mcpMode??p)==="shared"?`'${o}' is registered TWICE \u2014 once in this workspace's .mcp.json and once by the enabled Claude plugin. On shared MCP mode both routes proxy into the SAME server, so there is one event window; the cost is a redundant client shim per agent session.`:`'${o}' is registered TWICE \u2014 once in this workspace's .mcp.json and once by the enabled Claude plugin, so every agent session starts two servers (each with its own event window).`;return{duplicated:!0,names:s,indeterminate:!1,detail:l,hint:`Add "disabledMcpjsonServers": ["${s[0]}"] to .claude/settings.local.json to keep the plugin's copy, or remove the plugin (\`/plugin\` \u2192 uninstall) to keep the .mcp.json one. (settings.local.json is the file Claude Code itself writes these to.)`}}r(detectDuplicateRegistration,"detectDuplicateRegistration"),i(detectDuplicateRegistration,"detectDuplicateRegistration");export function mcpServerNames(e){const t=e?.mcpServers;return!t||typeof t!="object"||Array.isArray(t)?[]:Object.keys(t)}r(mcpServerNames,"mcpServerNames"),i(mcpServerNames,"mcpServerNames");export function pluginEnabledInSettings(e,t){const n=e?.enabledPlugins;return!n||typeof n!="object"?!1:n[t]===!0}r(pluginEnabledInSettings,"pluginEnabledInSettings"),i(pluginEnabledInSettings,"pluginEnabledInSettings");export function disabledMcpServers(e){const t=e?.disabledMcpjsonServers;return Array.isArray(t)?t.filter(n=>typeof n=="string"):[]}r(disabledMcpServers,"disabledMcpServers"),i(disabledMcpServers,"disabledMcpServers");
@@ -1 +1 @@
1
- "use strict";var g=Object.defineProperty;var i=(e,n)=>g(e,"name",{value:n,configurable:!0});var m=Object.defineProperty,a=i((e,n)=>m(e,"name",{value:n,configurable:!0}),"s"),w=Object.defineProperty,s=a((e,n)=>w(e,"name",{value:n,configurable:!0}),"s");import{spawn as S}from"node:child_process";import{constants as v}from"node:os";export const FORWARDED_SIGNALS=["SIGTERM","SIGINT","SIGHUP"],REPEAT_COALESCE_MS=250;export function exitCodeOf(e,n){return e!==null?e:n!==null?128+(v.signals[n]??0):1}i(exitCodeOf,"exitCodeOf"),a(exitCodeOf,"exitCodeOf"),s(exitCodeOf,"exitCodeOf");export function runForwardingSignals(e,n,l=process){return new Promise(p=>{const t=S(process.execPath,e.args,{cwd:e.cwd,env:e.env,stdio:"inherit",detached:process.platform!=="win32"});let c=Number.NEGATIVE_INFINITY;const f=s(r=>{if(t.pid===void 0||t.exitCode!==null||t.signalCode!==null)return;const o=Date.now();if(!(o-c<REPEAT_COALESCE_MS)){c=o;try{t.kill(r)}catch{}}},"forward");for(const r of FORWARDED_SIGNALS)l.on(r,f);let d=!1;const u=s(r=>{if(!d){d=!0;for(const o of FORWARDED_SIGNALS)l.off(o,f);p(r)}},"settle");t.on("error",r=>{t.pid===void 0&&(n(`${e.label} failed to start: ${r.message}`),u(1))}),t.on("exit",(r,o)=>u(exitCodeOf(r,o)))})}i(runForwardingSignals,"runForwardingSignals"),a(runForwardingSignals,"runForwardingSignals"),s(runForwardingSignals,"runForwardingSignals");
1
+ "use strict";var p=Object.defineProperty;var s=(o,r)=>p(o,"name",{value:r,configurable:!0});var w=Object.defineProperty,i=s((o,r)=>w(o,"name",{value:r,configurable:!0}),"s");import{spawn as g}from"node:child_process";import{constants as m}from"node:os";export const FORWARDED_SIGNALS=["SIGTERM","SIGINT","SIGHUP"],REPEAT_COALESCE_MS=250;export function exitCodeOf(o,r){return o!==null?o:r!==null?128+(m.signals[r]??0):1}s(exitCodeOf,"exitCodeOf"),i(exitCodeOf,"exitCodeOf");export function runForwardingSignals(o,r,a=process){return new Promise(u=>{const n=g(process.execPath,o.args,{cwd:o.cwd,env:o.env,stdio:"inherit",detached:process.platform!=="win32"});let l=Number.NEGATIVE_INFINITY;const c=i(e=>{if(n.pid===void 0||n.exitCode!==null||n.signalCode!==null)return;const t=Date.now();if(!(t-l<REPEAT_COALESCE_MS)){l=t;try{n.kill(e)}catch{}}},"forward");for(const e of FORWARDED_SIGNALS)a.on(e,c);let f=!1;const d=i(e=>{if(!f){f=!0;for(const t of FORWARDED_SIGNALS)a.off(t,c);u(e)}},"settle");n.on("error",e=>{n.pid===void 0&&(r(`${o.label} failed to start: ${e.message}`),d(1))}),n.on("exit",(e,t)=>d(exitCodeOf(e,t)))})}s(runForwardingSignals,"runForwardingSignals"),i(runForwardingSignals,"runForwardingSignals");
@@ -1 +1 @@
1
- "use strict";var u=Object.defineProperty;var r=(e,t)=>u(e,"name",{value:t,configurable:!0});var h=Object.defineProperty,o=r((e,t)=>h(e,"name",{value:t,configurable:!0}),"r"),f=Object.defineProperty,s=o((e,t)=>f(e,"name",{value:t,configurable:!0}),"n");import{realpathSync as d}from"node:fs";import{resolve as m}from"node:path";const i=s(e=>{try{return d(e)}catch{return m(e)}},"canonical");export function registrationState(e,t,a){const n=e.find(c=>c.key===t);return n?n.root===void 0||i(n.root)===i(a)?{kind:"mine"}:{kind:"other-checkout",root:n.root}:{kind:"free"}}r(registrationState,"registrationState"),o(registrationState,"registrationState"),s(registrationState,"registrationState");export function otherCheckoutLines(e,t,a){return[`'${e}' is already served from ${t}.`,`This checkout (${a}) derives the same key, and two checkouts cannot share a key or hosts behind one gateway \u2014 nothing was registered.`,`To serve it beside the other under hosts named after it, run \`lensmcp instance start\` here (a git worktree needs no arguments; a plain copy takes \`--name <name>\`). Otherwise run \`lensmcp gateway stop\` in ${t} first.`]}r(otherCheckoutLines,"otherCheckoutLines"),o(otherCheckoutLines,"otherCheckoutLines"),s(otherCheckoutLines,"otherCheckoutLines");export function refusalMessage(e){if(!e||e.status!==409||!e.json||typeof e.json!="object")return;const t=e.json.message;return typeof t=="string"&&t.trim()?t:void 0}r(refusalMessage,"refusalMessage"),o(refusalMessage,"refusalMessage"),s(refusalMessage,"refusalMessage");
1
+ "use strict";var c=Object.defineProperty;var r=(e,t)=>c(e,"name",{value:t,configurable:!0});var u=Object.defineProperty,o=r((e,t)=>u(e,"name",{value:t,configurable:!0}),"n");import{realpathSync as h}from"node:fs";import{resolve as d}from"node:path";const a=o(e=>{try{return h(e)}catch{return d(e)}},"canonical");export function registrationState(e,t,s){const n=e.find(i=>i.key===t);return n?n.root===void 0||a(n.root)===a(s)?{kind:"mine"}:{kind:"other-checkout",root:n.root}:{kind:"free"}}r(registrationState,"registrationState"),o(registrationState,"registrationState");export function otherCheckoutLines(e,t,s){return[`'${e}' is already served from ${t}.`,`This checkout (${s}) derives the same key, and two checkouts cannot share a key or hosts behind one gateway \u2014 nothing was registered.`,`To serve it beside the other under hosts named after it, run \`lensmcp instance start\` here (a git worktree needs no arguments; a plain copy takes \`--name <name>\`). Otherwise run \`lensmcp gateway stop\` in ${t} first.`]}r(otherCheckoutLines,"otherCheckoutLines"),o(otherCheckoutLines,"otherCheckoutLines");export function refusalMessage(e){if(!e||e.status!==409||!e.json||typeof e.json!="object")return;const t=e.json.message;return typeof t=="string"&&t.trim()?t:void 0}r(refusalMessage,"refusalMessage"),o(refusalMessage,"refusalMessage");
@@ -1,4 +1,4 @@
1
- "use strict";var j=Object.defineProperty;var n=(t,e)=>j(t,"name",{value:e,configurable:!0});var y=Object.defineProperty,a=n((t,e)=>y(t,"name",{value:e,configurable:!0}),"n"),v=Object.defineProperty,i=a((t,e)=>v(t,"name",{value:e,configurable:!0}),"i");import{spawnSync as m}from"node:child_process";import{mkdtempSync as b,readFileSync as O,rmSync as S}from"node:fs";import{createRequire as x}from"node:module";import{tmpdir as w}from"node:os";import{join as f}from"node:path";const G=12e4;export function graphSnapshotScriptOf(t){try{return x(f(t,"package.json")).resolve("@lensmcp/cluster/graph-snapshot.js")}catch{return}}n(graphSnapshotScriptOf,"graphSnapshotScriptOf"),a(graphSnapshotScriptOf,"graphSnapshotScriptOf"),i(graphSnapshotScriptOf,"graphSnapshotScriptOf");export function forwardedProjectGraph(t,e=process.env){const r=graphSnapshotScriptOf(t);if(!r)return;const o=b(f(w(),"lensmcp-graph-")),s=f(o,"graph.json");try{if(m(process.execPath,[r,s],{cwd:t,env:e,timeout:G,stdio:"ignore"}).status!==0)return;const c=JSON.parse(O(s,"utf8"));return c&&typeof c=="object"&&!Array.isArray(c)?c:void 0}catch{return}finally{S(o,{recursive:!0,force:!0})}}n(forwardedProjectGraph,"forwardedProjectGraph"),a(forwardedProjectGraph,"forwardedProjectGraph"),i(forwardedProjectGraph,"forwardedProjectGraph");export function projectDependenciesOf(t){const e=t.projectGraph?.dependencies;if(!(!e||typeof e!="object"))return Object.fromEntries(Object.entries(e).map(([r,o])=>[r,Array.isArray(o)?o.flatMap(s=>typeof s?.target=="string"?[s.target]:[]):[]]))}n(projectDependenciesOf,"projectDependenciesOf"),a(projectDependenciesOf,"projectDependenciesOf"),i(projectDependenciesOf,"projectDependenciesOf");export function registrationGraphFields(t,e){const r=forwardedProjectGraph(t),o=(r&&projectDependenciesOf(r))??e();return{...o?{projectDependencies:o}:{},...r?{projectGraph:r}:{}}}n(registrationGraphFields,"registrationGraphFields"),a(registrationGraphFields,"registrationGraphFields"),i(registrationGraphFields,"registrationGraphFields");export function graphVerdictLine(t){if(!t||typeof t!="object")return;const e=t.projectGraph;return!e||e.accepted!==!1?void 0:` services \u2192 through \`nx run\` until the gateway has this workspace's project graph (${e.forwarded===!1?"none could be computed here":`the gateway refused the one sent${typeof e.reason=="string"?`: ${e.reason}`:""}`})`}n(graphVerdictLine,"graphVerdictLine"),a(graphVerdictLine,"graphVerdictLine"),i(graphVerdictLine,"graphVerdictLine");export function controlRequest(t,e,r,o,s=5e3){const c=["-s","-o","-","-w",`
2
- %{http_code}`,"--unix-socket",t,"-X",e,`http://localhost${r}`],u=o===void 0?void 0:JSON.stringify(o);u!==void 0&&c.push("-H","content-type: application/json","--data-binary","@-");const p=m("curl",c,{encoding:"utf8",timeout:s,...u!==void 0?{input:u}:{},maxBuffer:16*1024*1024});if(p.status!==0||typeof p.stdout!="string"||p.stdout.length===0)return null;const d=p.stdout.split(`
3
- `),h=Number(d.pop());let l=null;try{const g=d.join(`
4
- `).trim();l=g?JSON.parse(g):null}catch{}return Number.isFinite(h)?{status:h,json:l}:null}n(controlRequest,"controlRequest"),a(controlRequest,"controlRequest"),i(controlRequest,"controlRequest");
1
+ "use strict";var g=Object.defineProperty;var n=(t,e)=>g(t,"name",{value:e,configurable:!0});var y=Object.defineProperty,a=n((t,e)=>y(t,"name",{value:e,configurable:!0}),"i");import{spawnSync as m}from"node:child_process";import{mkdtempSync as j,readFileSync as v,rmSync as b}from"node:fs";import{createRequire as S}from"node:module";import{tmpdir as x}from"node:os";import{join as u}from"node:path";const O=12e4;export function graphSnapshotScriptOf(t){try{return S(u(t,"package.json")).resolve("@lensmcp/cluster/graph-snapshot.js")}catch{return}}n(graphSnapshotScriptOf,"graphSnapshotScriptOf"),a(graphSnapshotScriptOf,"graphSnapshotScriptOf");export function forwardedProjectGraph(t,e=process.env){const r=graphSnapshotScriptOf(t);if(!r)return;const o=j(u(x(),"lensmcp-graph-")),s=u(o,"graph.json");try{if(m(process.execPath,[r,s],{cwd:t,env:e,timeout:O,stdio:"ignore"}).status!==0)return;const c=JSON.parse(v(s,"utf8"));return c&&typeof c=="object"&&!Array.isArray(c)?c:void 0}catch{return}finally{b(o,{recursive:!0,force:!0})}}n(forwardedProjectGraph,"forwardedProjectGraph"),a(forwardedProjectGraph,"forwardedProjectGraph");export function projectDependenciesOf(t){const e=t.projectGraph?.dependencies;if(!(!e||typeof e!="object"))return Object.fromEntries(Object.entries(e).map(([r,o])=>[r,Array.isArray(o)?o.flatMap(s=>typeof s?.target=="string"?[s.target]:[]):[]]))}n(projectDependenciesOf,"projectDependenciesOf"),a(projectDependenciesOf,"projectDependenciesOf");export function registrationGraphFields(t,e){const r=forwardedProjectGraph(t),o=(r&&projectDependenciesOf(r))??e();return{...o?{projectDependencies:o}:{},...r?{projectGraph:r}:{}}}n(registrationGraphFields,"registrationGraphFields"),a(registrationGraphFields,"registrationGraphFields");export function graphVerdictLine(t){if(!t||typeof t!="object")return;const e=t.projectGraph;return!e||e.accepted!==!1?void 0:` services \u2192 through \`nx run\` until the gateway has this workspace's project graph (${e.forwarded===!1?"none could be computed here":`the gateway refused the one sent${typeof e.reason=="string"?`: ${e.reason}`:""}`})`}n(graphVerdictLine,"graphVerdictLine"),a(graphVerdictLine,"graphVerdictLine");export function controlRequest(t,e,r,o,s=5e3){const c=["-s","-o","-","-w",`
2
+ %{http_code}`,"--unix-socket",t,"-X",e,`http://localhost${r}`],p=o===void 0?void 0:JSON.stringify(o);p!==void 0&&c.push("-H","content-type: application/json","--data-binary","@-");const i=m("curl",c,{encoding:"utf8",timeout:s,...p!==void 0?{input:p}:{},maxBuffer:16*1024*1024});if(i.status!==0||typeof i.stdout!="string"||i.stdout.length===0)return null;const f=i.stdout.split(`
3
+ `),d=Number(f.pop());let h=null;try{const l=f.join(`
4
+ `).trim();h=l?JSON.parse(l):null}catch{}return Number.isFinite(d)?{status:d,json:h}:null}n(controlRequest,"controlRequest"),a(controlRequest,"controlRequest");
@@ -1,3 +1,3 @@
1
- "use strict";var c=Object.defineProperty;var n=(e,r)=>c(e,"name",{value:r,configurable:!0});var p=Object.defineProperty,m=n((e,r)=>p(e,"name",{value:r,configurable:!0}),"n"),u=Object.defineProperty,d=m((e,r)=>u(e,"name",{value:r,configurable:!0}),"a");import{analyzeHeapSnapshot as b}from"./heap-analyzer.js";const t=process.argv.slice(2),a=d(e=>{const r=t.indexOf(e);return r>=0?t[r+1]:void 0},"flag"),s=t[0];try{if(!s||s.startsWith("--"))throw new Error("usage: heap-analyzer-main <snapshot> [--bundle <path>] [--top <n>] [--max-mb <n>]");const e=a("--bundle"),r=Number(a("--top")??"")||void 0,o=Number(a("--max-mb")??"")||void 0,i=b(s,{...e?{bundlePath:e}:{},...r?{top:r}:{},...o?{maxBytes:o*1024*1024}:{}});process.stdout.write(JSON.stringify(i)+`
1
+ "use strict";var c=Object.defineProperty;var n=(e,t)=>c(e,"name",{value:t,configurable:!0});var p=Object.defineProperty,d=n((e,t)=>p(e,"name",{value:t,configurable:!0}),"a");import{analyzeHeapSnapshot as m}from"./heap-analyzer.js";const r=process.argv.slice(2),s=d(e=>{const t=r.indexOf(e);return t>=0?r[t+1]:void 0},"flag"),a=r[0];try{if(!a||a.startsWith("--"))throw new Error("usage: heap-analyzer-main <snapshot> [--bundle <path>] [--top <n>] [--max-mb <n>]");const e=s("--bundle"),t=Number(s("--top")??"")||void 0,o=Number(s("--max-mb")??"")||void 0,i=m(a,{...e?{bundlePath:e}:{},...t?{top:t}:{},...o?{maxBytes:o*1024*1024}:{}});process.stdout.write(JSON.stringify(i)+`
2
2
  `)}catch(e){process.stdout.write(JSON.stringify({error:e?.message??String(e)})+`
3
3
  `),process.exitCode=1}
@@ -1 +1 @@
1
- "use strict";var at=Object.defineProperty;var $=(r,s)=>at(r,"name",{value:s,configurable:!0});var lt=Object.defineProperty,A=$((r,s)=>lt(r,"name",{value:s,configurable:!0}),"m"),ft=Object.defineProperty,p=A((r,s)=>ft(r,"name",{value:s,configurable:!0}),"h");import{closeSync as Re,existsSync as ge,fstatSync as ct,openSync as Ee,readSync as dt}from"node:fs";import{basename as Ne,dirname as E,isAbsolute as ut,join as be,relative as ze,resolve as ht,sep as te}from"node:path";import{fileURLToPath as pt}from"node:url";const _=1024*1024;export function estimateAnalysisBytes(r,s){return r.nodeCount*72+r.edgeCount*13+Math.round(s*.25)+64*_}$(estimateAnalysisBytes,"estimateAnalysisBytes"),A(estimateAnalysisBytes,"estimateAnalysisBytes"),p(estimateAnalysisBytes,"estimateAnalysisBytes");class Ie{static{$(this,"Ne")}static{A(this,"Le")}static{p(this,"ByteReader")}constructor(s){this.fd=s,this.buf=Buffer.allocUnsafe(32*_),this.len=0,this.pos=0,this.filePos=0,this.eof=!1}next(){if(this.pos>=this.len){if(this.eof)return-1;if(this.len=dt(this.fd,this.buf,0,this.buf.length,this.filePos),this.filePos+=this.len,this.pos=0,this.len===0)return this.eof=!0,-1}return this.buf[this.pos++]}skipPast(s){const a=[...s].map(l=>l.charCodeAt(0));let i=0;for(;;){const l=this.next();if(l<0)throw new Error(`not a V8 heap snapshot: no ${s}`);if(l===a[i]){if(i+=1,i===a.length)return}else i=l===a[0]?1:0}}ints(s,a){let i=0,l=0,S=!1;for(;i<s;){const b=this.next();if(b>=48&&b<=57)l=l*10+(b-48),S=!0;else if(S&&(a(i++,l),l=0,S=!1),b<0)break}}}function se(r){let s="";for(;;){const l=r.next();if(l<0||s.length>1*_)throw new Error('not a V8 heap snapshot: no "nodes" array');if(s+=String.fromCharCode(l),s.endsWith('"nodes":['))break}const a=s.slice(s.indexOf('{"meta"'),s.lastIndexOf("},")+1),i=JSON.parse(a);return{nodeCount:i.node_count,edgeCount:i.edge_count,nodeFields:i.meta.node_fields,edgeFields:i.meta.edge_fields,nodeTypes:i.meta.node_types[0],edgeTypes:i.meta.edge_types[0]}}$(se,"pe"),A(se,"Ie"),p(se,"readHeader");export function readSnapshotHeader(r){const s=Ee(r,"r");try{return se(new Ie(s))}finally{Re(s)}}$(readSnapshotHeader,"readSnapshotHeader"),A(readSnapshotHeader,"readSnapshotHeader"),p(readSnapshotHeader,"readSnapshotHeader");export class WorkspaceProjects{static{$(this,"WorkspaceProjects")}static{A(this,"WorkspaceProjects")}static{p(this,"WorkspaceProjects")}constructor(s){this.root=s,this.marked=new Map,this.workspaces=new Map}static ofBundle(s){return new WorkspaceProjects(s?ne(E(s),"nx.json"):void 0)}workspaceOf(s){return this.root&&(s===this.root||s.startsWith(this.root+te))?this.root:this.root?void 0:ne(E(s),"nx.json",this.workspaces)}absolute(s){return this.root?ht(this.root,s):void 0}projectOf(s){const a=this.workspaceOf(s);if(!a)return;const i=ze(a,s).split(te).join("/");if(!(!i||i.startsWith(".."))){for(let l=E(s);l.length>a.length&&l.startsWith(a+te);l=E(l))if(this.isProjectRoot(l))return{root:ze(a,l).split(te).join("/"),file:i};return{root:i.split("/").slice(0,Math.min(2,i.split("/").length-1)).join("/")||i,file:i}}}isProjectRoot(s){let a=this.marked.get(s);return a===void 0&&(a=ge(be(s,"project.json"))||ge(be(s,"package.json")),this.marked.set(s,a)),a}}function ne(r,s,a=new Map){for(let i=r;;i=E(i)){let l=a.get(i);if(l===void 0&&(l=ge(be(i,s)),a.set(i,l)),l)return i;if(E(i)===i)return}}$(ne,"ye"),A(ne,"Pe"),p(ne,"findUp");export function ownerOfUrl(r,s,a=WorkspaceProjects.ofBundle(s)){if(!r)return null;for(const b of["webpack-internal:///","webpack:///","webpack://"])if(r.startsWith(b)){const h=r.slice(b.length),N=h.indexOf("node_modules/");if(N>=0)return oe(h.slice(N+13));if(h.startsWith("./")){const c=a.absolute(h),j=c?a.projectOf(c):void 0;return j?{bucket:`bundle:${j.root}`,file:j.file}:{bucket:`bundle:${h.split("/").slice(1,3).join("/")}`,file:h.slice(2)}}return{bucket:`bundle:${h.split("/").slice(0,2).join("/")}`,file:h}}if(r.startsWith("node:"))return{bucket:`node:${r.slice(5).split("/").slice(0,2).join("/")}`,file:r.slice(5)};let i=r;if(r.startsWith("file://"))try{i=pt(r)}catch{i=r.slice(7)}if(s&&i===s)return{bucket:`bundle:<${Ne(s)}>`};const l=i.lastIndexOf("/node_modules/");if(l>=0)return oe(i.slice(l+14));if(!ut(i))return null;const S=a.projectOf(i);return S?{bucket:`bundle:${S.root}`,file:S.file}:{bucket:`file:${Ne(i)}`,file:i}}$(ownerOfUrl,"ownerOfUrl"),A(ownerOfUrl,"ownerOfUrl"),p(ownerOfUrl,"ownerOfUrl");export function bucketOfUrl(r,s,a){return ownerOfUrl(r,s,a)?.bucket??null}$(bucketOfUrl,"bucketOfUrl"),A(bucketOfUrl,"bucketOfUrl"),p(bucketOfUrl,"bucketOfUrl");function oe(r){return{bucket:`npm:${we(r)}`,file:r}}$(oe,"ge"),A(oe,"Ge"),p(oe,"npmOwner");function we(r){const s=r.split("/");return s[0]?.startsWith("@")?`${s[0]}/${s[1]??""}`:s[0]??"?"}$(we,"ze"),A(we,"at"),p(we,"packageOf");const k=4294967295,yt=10,me=3;export function analyzeHeapSnapshot(r,s={}){const a=Date.now(),i=s.top??15,l=Ee(r,"r");try{const S=ct(l).size,b=new Ie(l),h=se(b),N=estimateAnalysisBytes(h,S);if(s.maxBytes!==void 0&&N>s.maxBytes)throw new Error(`this snapshot (${h.nodeCount.toLocaleString()} nodes, ${h.edgeCount.toLocaleString()} edges) needs about ${Math.round(N/_)} MB to analyse, over the ${Math.round(s.maxBytes/_)} MB cap \u2014 raise LENSMCP_HEAP_ANALYZE_MAX_MB`);const c=h.nodeCount,j=h.edgeCount,D=h.nodeFields.length,ie=h.edgeFields.length,w=new Uint8Array(c),$e=new Uint32Array(c),H=new Float64Array(c),ke=new Uint32Array(c),Ve=h.nodeFields.indexOf("type"),De=h.nodeFields.indexOf("name"),Je=h.nodeFields.indexOf("self_size"),Xe=h.nodeFields.indexOf("edge_count");b.ints(c*D,(e,t)=>{const n=e/D|0,o=e%D;o===Ve?w[n]=t:o===De?$e[n]=t:o===Je?H[n]=t:o===Xe&&(ke[n]=t)}),b.skipPast('"edges":[');const m=new Uint8Array(j),C=new Uint32Array(j),O=new Uint32Array(j),Ye=h.edgeFields.indexOf("type"),Ze=h.edgeFields.indexOf("name_or_index");b.ints(j*ie,(e,t)=>{const n=e/ie|0,o=e%ie;o===Ye?m[n]=t:o===Ze?C[n]=t:O[n]=t/D}),b.skipPast('"strings":[');const v=[];for(;;){let e=b.next();for(;e===44||e===10||e===32||e===13;)e=b.next();if(e===93||e<0)break;if(e!==34)throw new Error(`not a V8 heap snapshot: bad string at #${v.length}`);const t=[];let n=!0;for(;e=b.next(),!(e<0);){if(e===92){const d=b.next();n&&t.push(e,d);continue}if(e===34)break;n&&(t.push(e),t.length>1200&&(n=!1))}let o;const f=Buffer.from(t).toString("utf8");try{o=JSON.parse(`"${f}"`)}catch{o=f}v.push(o.length>300?o.slice(0,300):o)}const G=p(e=>h.nodeTypes.indexOf(e),"T"),R=p(e=>h.edgeTypes.indexOf(e),"ET"),re=G("object"),J=G("closure"),qe=G("native"),Ke=G("code"),xe=G("string"),Qe=G("concatenated string"),et=G("sliced string"),ae=R("element"),le=R("hidden"),Ae=R("weak"),tt=R("shortcut"),Oe=R("property"),Be=R("internal"),g=new Uint32Array(c+1);for(let e=0,t=0;e<c;e++)g[e]=t,t+=ke[e],g[e+1]=t;const U=p(e=>v[$e[e]]??"","name"),Ue=p(e=>m[e]===ae||m[e]===le?`[${C[e]}]`:v[C[e]]??"?","edgeName"),fe=p(e=>{if(e===0)return"(root)";let t=U(e).replace(/[\r\n\t]/g," ");return t.length>70&&(t=`${t.slice(0,70)}\u2026`),`${h.nodeTypes[w[e]]??"?"}:${t}`},"label"),ce=p((e,t=0)=>{if(w[e]===xe||t>8)return U(e);if(w[e]!==Qe&&w[e]!==et)return"";let n="",o="";for(let f=g[e];f<g[e+1];f++){const d=v[C[f]];d==="first"||d==="parent"?n=ce(O[f],t+1):d==="second"&&(o=ce(O[f],t+1))}return n+o},"stringValue"),x=0,X=p((e,t)=>m[t]!==Ae&&!(e===x&&m[t]===tt),"essential");let Se=0;for(let e=0;e<c;e++)Se+=H[e];const T=new Uint32Array(c),W=new Uint32Array(c).fill(k);let M=0;{const e=new Uint8Array(c),t=new Uint32Array(c),n=new Uint32Array(c);let o=0;for(t[0]=x,n[0]=g[x],e[x]=1;o>=0;){const f=t[o],d=n[o];if(d<g[f+1]){if(n[o]=d+1,!X(f,d))continue;const u=O[d];if(e[u])continue;e[u]=1,o++,t[o]=u,n[o]=g[u]}else W[f]=M,T[M++]=f,o--}}const L=new Uint32Array(c+1);for(let e=0;e<c;e++)if(W[e]!==k)for(let t=g[e];t<g[e+1];t++)X(e,t)&&(L[O[t]+1]+=1);for(let e=0;e<c;e++)L[e+1]+=L[e];const je=new Uint32Array(L[c]);{const e=L.slice(0,c);for(let t=0;t<c;t++)if(W[t]!==k)for(let n=g[t];n<g[t+1];n++)X(t,n)&&(je[e[O[n]]++]=t)}const F=new Uint32Array(M).fill(k);F[W[x]]=W[x];for(let e=!0;e;){e=!1;for(let t=M-2;t>=0;t--){const n=T[t];let o=k;for(let f=L[n];f<L[n+1];f++){const d=W[je[f]];if(d===k||F[d]===k)continue;if(o===k){o=d;continue}let u=d,y=o;for(;u!==y;){for(;u<y;)u=F[u];for(;y<u;)y=F[y]}o=u}o!==k&&F[t]!==o&&(F[t]=o,e=!0)}}const z=new Float64Array(M);for(let e=0;e<M;e++)z[e]+=H[T[e]];for(let e=0;e<M-1;e++)z[F[e]]+=z[e];const ve=p(e=>W[e]===k?0:z[W[e]],"R"),We=p(e=>T[F[W[e]]],"idom"),Me=p(e=>`${h.nodeTypes[w[e]]}:${U(e).slice(0,60)}`,"keyOf"),de=new Map;for(let e=0;e<M-1;e++){const t=T[e],n=w[t];if(n!==re&&n!==J&&n!==qe)continue;const o=Me(t);let f=We(t),d=!1;for(let y=0;y<50&&f!==x;y++){if(Me(f)===o){d=!0;break}f=We(f)}const u=de.get(o)??{type:h.nodeTypes[n]??"?",name:U(t).slice(0,60),count:0,selfBytes:0,retainedBytes:0};u.count+=1,u.selfBytes+=H[t],d||(u.retainedBytes+=z[e]),de.set(o,u)}const st=[...de.values()].sort((e,t)=>t.retainedBytes-e.retainedBytes).slice(0,i),I=p((e,t)=>{for(let n=g[e];n<g[e+1];n++)if(!(m[n]===ae||m[n]===le)&&v[C[n]]===t)return O[n];return-1},"edgeTo"),Y=[],Fe=new Map,nt=s.workspaceRoot?new WorkspaceProjects(s.workspaceRoot):WorkspaceProjects.ofBundle(s.bundlePath),Pe=new Map,Ce=p(e=>{let t=Pe.get(e);if(t===void 0){const n=ownerOfUrl(e,s.bundlePath,nt);if(!n)t=-1;else{const o=`${n.bucket}\0${n.file??""}`;t=Fe.get(o),t===void 0&&(t=Y.length,Y.push(n),Fe.set(o,t))}Pe.set(e,t)}return t},"ownerOf"),ot=p(e=>e.startsWith("webpack")||e.startsWith("file://")||e.startsWith("/")||e.startsWith("node:"),"isUrl"),it=p(e=>{const t=U(e);if(t)return t;for(let n=g[e];n<g[e+1];n++){if(m[n]!==ae&&m[n]!==le&&m[n]!==Be)continue;const o=O[n];if(w[o]===xe&&ot(U(o)))return U(o)}return""},"scriptUrl"),B=new Int32Array(c).fill(-1),_e=new Map;for(let e=0;e<c;e++)if(w[e]===Ke){const t=U(e);if(t.startsWith("webpack")||t.startsWith("/")||t.startsWith("node:")||t.startsWith("file://")){const n=Ce(t);n>=0&&(B[e]=n)}}else if(w[e]===J){const t=I(e,"shared");if(t<0)continue;let n=_e.get(t);if(n===void 0){const o=I(t,"script"),f=o>=0?it(o):"";n=f?Ce(f):-1,_e.set(t,n)}n>=0&&(B[e]=n)}for(let e=0;e<c;e++){if(w[e]!==re||U(e)==="system / Context")continue;const t=I(e,"map"),n=t>=0?I(t,"constructor"):-1;n>=0&&w[n]===J&&B[n]>=0&&(B[e]=B[n])}for(let e=0;e<c;e++){if(w[e]!==J||B[e]<0)continue;const t=I(e,"context");t>=0&&B[t]<0&&(B[t]=B[e])}const Z=new Int32Array(c).fill(-2);for(let e=M-1;e>=0;e--){const t=T[e];if(t===x){Z[t]=-1;continue}Z[t]=B[t]>=0?B[t]:Z[T[F[e]]]}const q=new Float64Array(Y.length);let ue=0,he=0;for(let e=0;e<c;e++){const t=Z[e];t!==-2&&(t>=0?q[t]+=H[e]:ue+=H[e],he+=H[e])}const K=new Map;ue>0&&K.set("(unattributed)",{bytes:ue,files:[]}),Y.forEach((e,t)=>{if(q[t]===0)return;const n=K.get(e.bucket)??{bytes:0,files:[]};n.bytes+=q[t],e.file&&n.files.push({file:e.file,bytes:q[t]}),K.set(e.bucket,n)});const rt=[...K.entries()].sort((e,t)=>t[1].bytes-e[1].bytes).slice(0,i).map(([e,{bytes:t,files:n}])=>({bucket:e,bytes:t,share:he>0?t/he:0,...n.length?{files:n.sort((o,f)=>f.bytes-o.bytes).slice(0,yt)}:{}})),He=[],Ge=[],pe=[];for(let e=0;e<c;e++){if(w[e]!==re||U(e)!=="LensmcpClosedGeneration")continue;let t="closed generation";const n=[];for(let o=g[e];o<g[e+1];o++){if(m[o]!==Oe)continue;const f=v[C[o]],d=O[o];if(f==="label"&&(t=ce(d)||t),f==="refs")for(let u=g[d];u<g[d+1];u++){if(m[u]!==Oe)continue;const y=O[u];for(let P=g[y];P<g[y+1];P++)m[P]===Ae&&v[C[P]]==="target"&&n.push({target:v[C[u]]??"?",node:O[P]})}}pe.push({label:t,targets:n})}if(pe.length){const e=new Uint32Array(c).fill(k),t=new Uint32Array(c).fill(k),n=new Uint32Array(c);let o=0,f=0;for(n[f++]=x,e[x]=x;o<f;){const d=n[o++];for(let u=g[d];u<g[d+1];u++){if(!X(d,u))continue;const y=O[u];e[y]===k&&(e[y]=d,t[y]=u,n[f++]=y)}}for(const d of pe){const u=d.targets.filter(y=>e[y.node]!==k);if(u.length===0){Ge.push(d.label);continue}for(const y of u){const P=[];for(let Q=y.node,Te=0;Q!==x&&Te<64;Te++){const ee=e[Q],ye=t[Q],Le=ee===x?0:ve(ee);P.push(`${fe(ee)}${Le>=_?` (${(Le/_).toFixed(1)} MB)`:""} -[${m[ye]===Be?`(${Ue(ye)})`:Ue(ye)}]->`),Q=ee}P.reverse(),He.push({label:d.label,target:y.target,node:fe(y.node),retainedBytes:ve(y.node),path:[...P.slice(-24),fe(y.node)]})}}}return{file:r,nodes:c,edges:j,totalBytes:Se,topRetained:st,attribution:rt,closedGenerations:He,closedGenerationsGone:Ge,ms:Date.now()-a}}finally{Re(l)}}$(analyzeHeapSnapshot,"analyzeHeapSnapshot"),A(analyzeHeapSnapshot,"analyzeHeapSnapshot"),p(analyzeHeapSnapshot,"analyzeHeapSnapshot");const V=p(r=>`${(r/_).toFixed(1)} MB`,"mb");export function renderHeapAnalysis(r){const s=[];if(s.push(`Heap snapshot ${r.file}`),s.push(` ${r.nodes.toLocaleString()} nodes, ${r.edges.toLocaleString()} edges, ${V(r.totalBytes)} \u2014 analysed in ${(r.ms/1e3).toFixed(1)}s`),s.push(""),r.closedGenerations.length){s.push("Closed generations still in memory \u2014 the shortest path that keeps each one:");for(const a of r.closedGenerations){s.push(` ${a.label} (${a.target}, retains ${V(a.retainedBytes)}):`);for(const i of a.path)s.push(` ${i}`)}}else s.push(r.closedGenerationsGone.length?`No closed generation is still in memory (${r.closedGenerationsGone.join(", ")} marked, all collected).`:"No closed generation is still in memory.");s.push(""),s.push("Largest retainers (retained size, by class):");for(const a of r.topRetained)s.push(` ${V(a.retainedBytes).padStart(10)} \xD7${String(a.count).padStart(7)} ${a.type}:${a.name}`);s.push(""),s.push("Where the bytes belong (by the nearest owning script \u2014 library, package, then its largest files):");for(const a of r.attribution){s.push(` ${V(a.bytes).padStart(10)} ${(a.share*100).toFixed(1).padStart(5)}% ${a.bucket}`);const i=a.files??[];if(!(i.length<2)){for(const l of i.slice(0,me))s.push(` ${"".padStart(18)}${V(l.bytes).padStart(10)} ${l.file}`);i.length>me&&s.push(` ${"".padStart(18)}${"".padStart(10)} \u2026 ${i.length-me} more`)}}return s}$(renderHeapAnalysis,"renderHeapAnalysis"),A(renderHeapAnalysis,"renderHeapAnalysis"),p(renderHeapAnalysis,"renderHeapAnalysis");
1
+ "use strict";var rt=Object.defineProperty;var m=(r,n)=>rt(r,"name",{value:n,configurable:!0});var lt=Object.defineProperty,p=m((r,n)=>lt(r,"name",{value:n,configurable:!0}),"h");import{closeSync as Ee,existsSync as ue,fstatSync as at,openSync as He,readSync as ft}from"node:fs";import{basename as Le,dirname as L,isAbsolute as ct,join as he,relative as Re,resolve as dt,sep as ee}from"node:path";import{fileURLToPath as ut}from"node:url";const C=1024*1024;export function estimateAnalysisBytes(r,n){return r.nodeCount*72+r.edgeCount*13+Math.round(n*.25)+64*C}m(estimateAnalysisBytes,"estimateAnalysisBytes"),p(estimateAnalysisBytes,"estimateAnalysisBytes");class Ne{static{m(this,"Le")}static{p(this,"ByteReader")}constructor(n){this.fd=n,this.buf=Buffer.allocUnsafe(32*C),this.len=0,this.pos=0,this.filePos=0,this.eof=!1}next(){if(this.pos>=this.len){if(this.eof)return-1;if(this.len=ft(this.fd,this.buf,0,this.buf.length,this.filePos),this.filePos+=this.len,this.pos=0,this.len===0)return this.eof=!0,-1}return this.buf[this.pos++]}skipPast(n){const l=[...n].map(a=>a.charCodeAt(0));let i=0;for(;;){const a=this.next();if(a<0)throw new Error(`not a V8 heap snapshot: no ${n}`);if(a===l[i]){if(i+=1,i===l.length)return}else i=a===l[0]?1:0}}ints(n,l){let i=0,a=0,B=!1;for(;i<n;){const b=this.next();if(b>=48&&b<=57)a=a*10+(b-48),B=!0;else if(B&&(l(i++,a),a=0,B=!1),b<0)break}}}function pe(r){let n="";for(;;){const a=r.next();if(a<0||n.length>1*C)throw new Error('not a V8 heap snapshot: no "nodes" array');if(n+=String.fromCharCode(a),n.endsWith('"nodes":['))break}const l=n.slice(n.indexOf('{"meta"'),n.lastIndexOf("},")+1),i=JSON.parse(l);return{nodeCount:i.node_count,edgeCount:i.edge_count,nodeFields:i.meta.node_fields,edgeFields:i.meta.edge_fields,nodeTypes:i.meta.node_types[0],edgeTypes:i.meta.edge_types[0]}}m(pe,"Ie"),p(pe,"readHeader");export function readSnapshotHeader(r){const n=He(r,"r");try{return pe(new Ne(n))}finally{Ee(n)}}m(readSnapshotHeader,"readSnapshotHeader"),p(readSnapshotHeader,"readSnapshotHeader");export class WorkspaceProjects{static{m(this,"WorkspaceProjects")}static{p(this,"WorkspaceProjects")}constructor(n){this.root=n,this.marked=new Map,this.workspaces=new Map}static ofBundle(n){return new WorkspaceProjects(n?ye(L(n),"nx.json"):void 0)}workspaceOf(n){return this.root&&(n===this.root||n.startsWith(this.root+ee))?this.root:this.root?void 0:ye(L(n),"nx.json",this.workspaces)}absolute(n){return this.root?dt(this.root,n):void 0}projectOf(n){const l=this.workspaceOf(n);if(!l)return;const i=Re(l,n).split(ee).join("/");if(!(!i||i.startsWith(".."))){for(let a=L(n);a.length>l.length&&a.startsWith(l+ee);a=L(a))if(this.isProjectRoot(a))return{root:Re(l,a).split(ee).join("/"),file:i};return{root:i.split("/").slice(0,Math.min(2,i.split("/").length-1)).join("/")||i,file:i}}}isProjectRoot(n){let l=this.marked.get(n);return l===void 0&&(l=ue(he(n,"project.json"))||ue(he(n,"package.json")),this.marked.set(n,l)),l}}function ye(r,n,l=new Map){for(let i=r;;i=L(i)){let a=l.get(i);if(a===void 0&&(a=ue(he(i,n)),l.set(i,a)),a)return i;if(L(i)===i)return}}m(ye,"Pe"),p(ye,"findUp");export function ownerOfUrl(r,n,l=WorkspaceProjects.ofBundle(n)){if(!r)return null;for(const b of["webpack-internal:///","webpack:///","webpack://"])if(r.startsWith(b)){const h=r.slice(b.length),R=h.indexOf("node_modules/");if(R>=0)return ge(h.slice(R+13));if(h.startsWith("./")){const c=l.absolute(h),U=c?l.projectOf(c):void 0;return U?{bucket:`bundle:${U.root}`,file:U.file}:{bucket:`bundle:${h.split("/").slice(1,3).join("/")}`,file:h.slice(2)}}return{bucket:`bundle:${h.split("/").slice(0,2).join("/")}`,file:h}}if(r.startsWith("node:"))return{bucket:`node:${r.slice(5).split("/").slice(0,2).join("/")}`,file:r.slice(5)};let i=r;if(r.startsWith("file://"))try{i=ut(r)}catch{i=r.slice(7)}if(n&&i===n)return{bucket:`bundle:<${Le(n)}>`};const a=i.lastIndexOf("/node_modules/");if(a>=0)return ge(i.slice(a+14));if(!ct(i))return null;const B=l.projectOf(i);return B?{bucket:`bundle:${B.root}`,file:B.file}:{bucket:`file:${Le(i)}`,file:i}}m(ownerOfUrl,"ownerOfUrl"),p(ownerOfUrl,"ownerOfUrl");export function bucketOfUrl(r,n,l){return ownerOfUrl(r,n,l)?.bucket??null}m(bucketOfUrl,"bucketOfUrl"),p(bucketOfUrl,"bucketOfUrl");function ge(r){return{bucket:`npm:${ze(r)}`,file:r}}m(ge,"Ge"),p(ge,"npmOwner");function ze(r){const n=r.split("/");return n[0]?.startsWith("@")?`${n[0]}/${n[1]??""}`:n[0]??"?"}m(ze,"at"),p(ze,"packageOf");const k=4294967295,ht=10,be=3;export function analyzeHeapSnapshot(r,n={}){const l=Date.now(),i=n.top??15,a=He(r,"r");try{const B=at(a).size,b=new Ne(a),h=pe(b),R=estimateAnalysisBytes(h,B);if(n.maxBytes!==void 0&&R>n.maxBytes)throw new Error(`this snapshot (${h.nodeCount.toLocaleString()} nodes, ${h.edgeCount.toLocaleString()} edges) needs about ${Math.round(R/C)} MB to analyse, over the ${Math.round(n.maxBytes/C)} MB cap \u2014 raise LENSMCP_HEAP_ANALYZE_MAX_MB`);const c=h.nodeCount,U=h.edgeCount,V=h.nodeFields.length,te=h.edgeFields.length,w=new Uint8Array(c),we=new Uint32Array(c),_=new Float64Array(c),$e=new Uint32Array(c),Ie=h.nodeFields.indexOf("type"),Ve=h.nodeFields.indexOf("name"),De=h.nodeFields.indexOf("self_size"),Je=h.nodeFields.indexOf("edge_count");b.ints(c*V,(e,t)=>{const s=e/V|0,o=e%V;o===Ie?w[s]=t:o===Ve?we[s]=t:o===De?_[s]=t:o===Je&&($e[s]=t)}),b.skipPast('"edges":[');const $=new Uint8Array(U),P=new Uint32Array(U),A=new Uint32Array(U),Xe=h.edgeFields.indexOf("type"),Ye=h.edgeFields.indexOf("name_or_index");b.ints(U*te,(e,t)=>{const s=e/te|0,o=e%te;o===Xe?$[s]=t:o===Ye?P[s]=t:A[s]=t/V}),b.skipPast('"strings":[');const j=[];for(;;){let e=b.next();for(;e===44||e===10||e===32||e===13;)e=b.next();if(e===93||e<0)break;if(e!==34)throw new Error(`not a V8 heap snapshot: bad string at #${j.length}`);const t=[];let s=!0;for(;e=b.next(),!(e<0);){if(e===92){const d=b.next();s&&t.push(e,d);continue}if(e===34)break;s&&(t.push(e),t.length>1200&&(s=!1))}let o;const f=Buffer.from(t).toString("utf8");try{o=JSON.parse(`"${f}"`)}catch{o=f}j.push(o.length>300?o.slice(0,300):o)}const T=p(e=>h.nodeTypes.indexOf(e),"T"),H=p(e=>h.edgeTypes.indexOf(e),"ET"),ne=T("object"),D=T("closure"),Ze=T("native"),qe=T("code"),me=T("string"),Ke=T("concatenated string"),Qe=T("sliced string"),se=H("element"),oe=H("hidden"),ke=H("weak"),et=H("shortcut"),xe=H("property"),Ae=H("internal"),g=new Uint32Array(c+1);for(let e=0,t=0;e<c;e++)g[e]=t,t+=$e[e],g[e+1]=t;const S=p(e=>j[we[e]]??"","name"),Oe=p(e=>$[e]===se||$[e]===oe?`[${P[e]}]`:j[P[e]]??"?","edgeName"),ie=p(e=>{if(e===0)return"(root)";let t=S(e).replace(/[\r\n\t]/g," ");return t.length>70&&(t=`${t.slice(0,70)}\u2026`),`${h.nodeTypes[w[e]]??"?"}:${t}`},"label"),re=p((e,t=0)=>{if(w[e]===me||t>8)return S(e);if(w[e]!==Ke&&w[e]!==Qe)return"";let s="",o="";for(let f=g[e];f<g[e+1];f++){const d=j[P[f]];d==="first"||d==="parent"?s=re(A[f],t+1):d==="second"&&(o=re(A[f],t+1))}return s+o},"stringValue"),x=0,J=p((e,t)=>$[t]!==ke&&!(e===x&&$[t]===et),"essential");let Se=0;for(let e=0;e<c;e++)Se+=_[e];const G=new Uint32Array(c),v=new Uint32Array(c).fill(k);let M=0;{const e=new Uint8Array(c),t=new Uint32Array(c),s=new Uint32Array(c);let o=0;for(t[0]=x,s[0]=g[x],e[x]=1;o>=0;){const f=t[o],d=s[o];if(d<g[f+1]){if(s[o]=d+1,!J(f,d))continue;const u=A[d];if(e[u])continue;e[u]=1,o++,t[o]=u,s[o]=g[u]}else v[f]=M,G[M++]=f,o--}}const E=new Uint32Array(c+1);for(let e=0;e<c;e++)if(v[e]!==k)for(let t=g[e];t<g[e+1];t++)J(e,t)&&(E[A[t]+1]+=1);for(let e=0;e<c;e++)E[e+1]+=E[e];const Be=new Uint32Array(E[c]);{const e=E.slice(0,c);for(let t=0;t<c;t++)if(v[t]!==k)for(let s=g[t];s<g[t+1];s++)J(t,s)&&(Be[e[A[s]]++]=t)}const W=new Uint32Array(M).fill(k);W[v[x]]=v[x];for(let e=!0;e;){e=!1;for(let t=M-2;t>=0;t--){const s=G[t];let o=k;for(let f=E[s];f<E[s+1];f++){const d=v[Be[f]];if(d===k||W[d]===k)continue;if(o===k){o=d;continue}let u=d,y=o;for(;u!==y;){for(;u<y;)u=W[u];for(;y<u;)y=W[y]}o=u}o!==k&&W[t]!==o&&(W[t]=o,e=!0)}}const N=new Float64Array(M);for(let e=0;e<M;e++)N[e]+=_[G[e]];for(let e=0;e<M-1;e++)N[W[e]]+=N[e];const Ue=p(e=>v[e]===k?0:N[v[e]],"R"),je=p(e=>G[W[v[e]]],"idom"),ve=p(e=>`${h.nodeTypes[w[e]]}:${S(e).slice(0,60)}`,"keyOf"),le=new Map;for(let e=0;e<M-1;e++){const t=G[e],s=w[t];if(s!==ne&&s!==D&&s!==Ze)continue;const o=ve(t);let f=je(t),d=!1;for(let y=0;y<50&&f!==x;y++){if(ve(f)===o){d=!0;break}f=je(f)}const u=le.get(o)??{type:h.nodeTypes[s]??"?",name:S(t).slice(0,60),count:0,selfBytes:0,retainedBytes:0};u.count+=1,u.selfBytes+=_[t],d||(u.retainedBytes+=N[e]),le.set(o,u)}const tt=[...le.values()].sort((e,t)=>t.retainedBytes-e.retainedBytes).slice(0,i),z=p((e,t)=>{for(let s=g[e];s<g[e+1];s++)if(!($[s]===se||$[s]===oe)&&j[P[s]]===t)return A[s];return-1},"edgeTo"),X=[],Me=new Map,nt=n.workspaceRoot?new WorkspaceProjects(n.workspaceRoot):WorkspaceProjects.ofBundle(n.bundlePath),We=new Map,Fe=p(e=>{let t=We.get(e);if(t===void 0){const s=ownerOfUrl(e,n.bundlePath,nt);if(!s)t=-1;else{const o=`${s.bucket}\0${s.file??""}`;t=Me.get(o),t===void 0&&(t=X.length,X.push(s),Me.set(o,t))}We.set(e,t)}return t},"ownerOf"),st=p(e=>e.startsWith("webpack")||e.startsWith("file://")||e.startsWith("/")||e.startsWith("node:"),"isUrl"),ot=p(e=>{const t=S(e);if(t)return t;for(let s=g[e];s<g[e+1];s++){if($[s]!==se&&$[s]!==oe&&$[s]!==Ae)continue;const o=A[s];if(w[o]===me&&st(S(o)))return S(o)}return""},"scriptUrl"),O=new Int32Array(c).fill(-1),Pe=new Map;for(let e=0;e<c;e++)if(w[e]===qe){const t=S(e);if(t.startsWith("webpack")||t.startsWith("/")||t.startsWith("node:")||t.startsWith("file://")){const s=Fe(t);s>=0&&(O[e]=s)}}else if(w[e]===D){const t=z(e,"shared");if(t<0)continue;let s=Pe.get(t);if(s===void 0){const o=z(t,"script"),f=o>=0?ot(o):"";s=f?Fe(f):-1,Pe.set(t,s)}s>=0&&(O[e]=s)}for(let e=0;e<c;e++){if(w[e]!==ne||S(e)==="system / Context")continue;const t=z(e,"map"),s=t>=0?z(t,"constructor"):-1;s>=0&&w[s]===D&&O[s]>=0&&(O[e]=O[s])}for(let e=0;e<c;e++){if(w[e]!==D||O[e]<0)continue;const t=z(e,"context");t>=0&&O[t]<0&&(O[t]=O[e])}const Y=new Int32Array(c).fill(-2);for(let e=M-1;e>=0;e--){const t=G[e];if(t===x){Y[t]=-1;continue}Y[t]=O[t]>=0?O[t]:Y[G[W[e]]]}const Z=new Float64Array(X.length);let ae=0,fe=0;for(let e=0;e<c;e++){const t=Y[e];t!==-2&&(t>=0?Z[t]+=_[e]:ae+=_[e],fe+=_[e])}const q=new Map;ae>0&&q.set("(unattributed)",{bytes:ae,files:[]}),X.forEach((e,t)=>{if(Z[t]===0)return;const s=q.get(e.bucket)??{bytes:0,files:[]};s.bytes+=Z[t],e.file&&s.files.push({file:e.file,bytes:Z[t]}),q.set(e.bucket,s)});const it=[...q.entries()].sort((e,t)=>t[1].bytes-e[1].bytes).slice(0,i).map(([e,{bytes:t,files:s}])=>({bucket:e,bytes:t,share:fe>0?t/fe:0,...s.length?{files:s.sort((o,f)=>f.bytes-o.bytes).slice(0,ht)}:{}})),Ce=[],_e=[],ce=[];for(let e=0;e<c;e++){if(w[e]!==ne||S(e)!=="LensmcpClosedGeneration")continue;let t="closed generation";const s=[];for(let o=g[e];o<g[e+1];o++){if($[o]!==xe)continue;const f=j[P[o]],d=A[o];if(f==="label"&&(t=re(d)||t),f==="refs")for(let u=g[d];u<g[d+1];u++){if($[u]!==xe)continue;const y=A[u];for(let F=g[y];F<g[y+1];F++)$[F]===ke&&j[P[F]]==="target"&&s.push({target:j[P[u]]??"?",node:A[F]})}}ce.push({label:t,targets:s})}if(ce.length){const e=new Uint32Array(c).fill(k),t=new Uint32Array(c).fill(k),s=new Uint32Array(c);let o=0,f=0;for(s[f++]=x,e[x]=x;o<f;){const d=s[o++];for(let u=g[d];u<g[d+1];u++){if(!J(d,u))continue;const y=A[u];e[y]===k&&(e[y]=d,t[y]=u,s[f++]=y)}}for(const d of ce){const u=d.targets.filter(y=>e[y.node]!==k);if(u.length===0){_e.push(d.label);continue}for(const y of u){const F=[];for(let K=y.node,Te=0;K!==x&&Te<64;Te++){const Q=e[K],de=t[K],Ge=Q===x?0:Ue(Q);F.push(`${ie(Q)}${Ge>=C?` (${(Ge/C).toFixed(1)} MB)`:""} -[${$[de]===Ae?`(${Oe(de)})`:Oe(de)}]->`),K=Q}F.reverse(),Ce.push({label:d.label,target:y.target,node:ie(y.node),retainedBytes:Ue(y.node),path:[...F.slice(-24),ie(y.node)]})}}}return{file:r,nodes:c,edges:U,totalBytes:Se,topRetained:tt,attribution:it,closedGenerations:Ce,closedGenerationsGone:_e,ms:Date.now()-l}}finally{Ee(a)}}m(analyzeHeapSnapshot,"analyzeHeapSnapshot"),p(analyzeHeapSnapshot,"analyzeHeapSnapshot");const I=p(r=>`${(r/C).toFixed(1)} MB`,"mb");export function renderHeapAnalysis(r){const n=[];if(n.push(`Heap snapshot ${r.file}`),n.push(` ${r.nodes.toLocaleString()} nodes, ${r.edges.toLocaleString()} edges, ${I(r.totalBytes)} \u2014 analysed in ${(r.ms/1e3).toFixed(1)}s`),n.push(""),r.closedGenerations.length){n.push("Closed generations still in memory \u2014 the shortest path that keeps each one:");for(const l of r.closedGenerations){n.push(` ${l.label} (${l.target}, retains ${I(l.retainedBytes)}):`);for(const i of l.path)n.push(` ${i}`)}}else n.push(r.closedGenerationsGone.length?`No closed generation is still in memory (${r.closedGenerationsGone.join(", ")} marked, all collected).`:"No closed generation is still in memory.");n.push(""),n.push("Largest retainers (retained size, by class):");for(const l of r.topRetained)n.push(` ${I(l.retainedBytes).padStart(10)} \xD7${String(l.count).padStart(7)} ${l.type}:${l.name}`);n.push(""),n.push("Where the bytes belong (by the nearest owning script \u2014 library, package, then its largest files):");for(const l of r.attribution){n.push(` ${I(l.bytes).padStart(10)} ${(l.share*100).toFixed(1).padStart(5)}% ${l.bucket}`);const i=l.files??[];if(!(i.length<2)){for(const a of i.slice(0,be))n.push(` ${"".padStart(18)}${I(a.bytes).padStart(10)} ${a.file}`);i.length>be&&n.push(` ${"".padStart(18)}${"".padStart(10)} \u2026 ${i.length-be} more`)}}return n}m(renderHeapAnalysis,"renderHeapAnalysis"),p(renderHeapAnalysis,"renderHeapAnalysis");
@@ -1 +1 @@
1
- "use strict";var i=Object.defineProperty;var n=(e,r)=>i(e,"name",{value:r,configurable:!0});var l=Object.defineProperty,t=n((e,r)=>l(e,"name",{value:r,configurable:!0}),"n"),f=Object.defineProperty,o=t((e,r)=>f(e,"name",{value:r,configurable:!0}),"t");import{lstatSync as y,chmodSync as d,mkdirSync as h,readFileSync as p,rmSync as m,writeFileSync as b}from"node:fs";import{tmpdir as A}from"node:os";import{join as u}from"node:path";const S=o(e=>e.replace(/[^A-Za-z0-9._-]/g,"_").slice(0,100)||"unknown","safeKey");export const memoryPathFor=o((e,r=A())=>u(r,"lensmcp-hook",`${S(e)}.digest`),"memoryPathFor");export function lastAnnounced(e,r){try{return p(memoryPathFor(e,r),"utf8")}catch{return}}n(lastAnnounced,"lastAnnounced"),t(lastAnnounced,"lastAnnounced"),o(lastAnnounced,"lastAnnounced");export function remember(e,r,a){const c=memoryPathFor(e,a);try{if(!r){m(c,{force:!0});return}s(u(c,"..")),m(c,{force:!0}),b(c,r,{flag:"wx",mode:384})}catch{}}n(remember,"remember"),t(remember,"remember"),o(remember,"remember");function s(e){try{h(e,{recursive:!0,mode:448})}catch{}try{const r=y(e);r.isDirectory()&&(r.mode&63)!==0&&d(e,448)}catch{}}n(s,"i"),t(s,"h"),o(s,"ensureOwnerOnlyDir");export function shouldAnnounce(e,r,a){return r?e?lastAnnounced(e,a)!==r:!0:!1}n(shouldAnnounce,"shouldAnnounce"),t(shouldAnnounce,"shouldAnnounce"),o(shouldAnnounce,"shouldAnnounce");
1
+ "use strict";var m=Object.defineProperty;var n=(e,r)=>m(e,"name",{value:r,configurable:!0});var u=Object.defineProperty,t=n((e,r)=>u(e,"name",{value:r,configurable:!0}),"t");import{lstatSync as y,chmodSync as f,mkdirSync as l,readFileSync as d,rmSync as a,writeFileSync as p}from"node:fs";import{tmpdir as h}from"node:os";import{join as s}from"node:path";const S=t(e=>e.replace(/[^A-Za-z0-9._-]/g,"_").slice(0,100)||"unknown","safeKey");export const memoryPathFor=t((e,r=h())=>s(r,"lensmcp-hook",`${S(e)}.digest`),"memoryPathFor");export function lastAnnounced(e,r){try{return d(memoryPathFor(e,r),"utf8")}catch{return}}n(lastAnnounced,"lastAnnounced"),t(lastAnnounced,"lastAnnounced");export function remember(e,r,c){const o=memoryPathFor(e,c);try{if(!r){a(o,{force:!0});return}i(s(o,"..")),a(o,{force:!0}),p(o,r,{flag:"wx",mode:384})}catch{}}n(remember,"remember"),t(remember,"remember");function i(e){try{l(e,{recursive:!0,mode:448})}catch{}try{const r=y(e);r.isDirectory()&&(r.mode&63)!==0&&f(e,448)}catch{}}n(i,"h"),t(i,"ensureOwnerOnlyDir");export function shouldAnnounce(e,r,c){return r?e?lastAnnounced(e,c)!==r:!0:!1}n(shouldAnnounce,"shouldAnnounce"),t(shouldAnnounce,"shouldAnnounce");
@@ -1,4 +1,4 @@
1
- "use strict";var Me=Object.defineProperty;var w=(c,d)=>Me(c,"name",{value:d,configurable:!0});var Fe=Object.defineProperty,$=w((c,d)=>Fe(c,"name",{value:d,configurable:!0}),"w"),qe=Object.defineProperty,f=$((c,d)=>qe(c,"name",{value:d,configurable:!0}),"h");import{spawn as Be,spawnSync as Ge}from"node:child_process";import{existsSync as K,mkdirSync as Ee,readFileSync as Je,realpathSync as We,rmSync as re,writeFileSync as ve}from"node:fs";import{basename as Ne,dirname as He,join as R,relative as Ke,resolve as Y}from"node:path";import{registrationState as Ue,refusalMessage as Pe}from"./gateway-registration.js";import{readRegistry as oe,redactUrl as Xe,registryPath as Qe,withRegistry as ae}from"./instance-registry.js";import{bootstrapCheckout as Ve,defaultRuntime as Ye,dropAll as Ze,provisionAll as et,readInstancesDecl as Re,resourceEnvFile as tt,writeResourceEnv as nt}from"./instance-resources.js";import{addWorktree as st,branchNameProblem as rt,claimCreate as ot,currentBranch as at,deleteBranch as it,ensureIgnored as ct,gitExec as dt,progressFile as Z,readProgress as Ae,removeWorktree as ut,resolveCommit as lt,settledProgress as pt,uncommittedChanges as Te,worktreesHome as ft,writeProgress as Ie}from"./instance-worktree.js";import{derivePorts as mt,INSTANCE_NAME_PATTERN as Le,instanceSockNs as ht,readLensConfig as ee,slugify as yt}from"./workspace-scope.js";export const INSTANCE_USAGE=`Usage:
1
+ "use strict";var De=Object.defineProperty;var w=(c,l)=>De(c,"name",{value:l,configurable:!0});var Be=Object.defineProperty,m=w((c,l)=>Be(c,"name",{value:l,configurable:!0}),"h");import{spawn as ze,spawnSync as qe}from"node:child_process";import{existsSync as N,mkdirSync as Ce,readFileSync as Fe,realpathSync as Ge,rmSync as te,writeFileSync as de}from"node:fs";import{basename as je,dirname as Je,join as R,relative as Se,resolve as X}from"node:path";import{registrationState as We,refusalMessage as Oe}from"./gateway-registration.js";import{readRegistry as ne,redactUrl as He,registryPath as Ue,withRegistry as se}from"./instance-registry.js";import{bootstrapCheckout as Xe,defaultRuntime as Ye,dropAll as Qe,provisionAll as Ve,readInstancesDecl as Ee,resourceEnvFile as Ze,writeResourceEnv as et}from"./instance-resources.js";import{addWorktree as tt,branchNameProblem as nt,claimCreate as st,currentBranch as rt,deleteBranch as ot,ensureIgnored as at,gitExec as it,progressFile as Y,readProgress as Ne,removeWorktree as ct,resolveCommit as dt,settledProgress as ut,uncommittedChanges as Pe,worktreesHome as lt,writeProgress as Re}from"./instance-worktree.js";import{derivePorts as pt,INSTANCE_NAME_PATTERN as Ke,instanceSockNs as mt,readLensConfig as Q,slugify as ft}from"./workspace-scope.js";export const INSTANCE_USAGE=`Usage:
2
2
  lensmcp instance create <name> [--branch <branch> | --detach] [--from <commit>] [--frozen] [--no-prepare] [--share-stores] [--json] [--cwd <dir>]
3
3
  Make a git worktree of this checkout and start it as an instance (what a coding agent's
4
4
  MCP worktree_create runs): on <branch> (default lensmcp/<name>, made from --from, default
@@ -20,11 +20,11 @@
20
20
  removes the git worktree \u2014 refused while it has uncommitted changes, unless --force;
21
21
  --delete-branch deletes a branch the lens made, once merged (--force: even unmerged).
22
22
  lensmcp instance prune [--dry-run]
23
- Remove every instance whose folder is gone, data included.`;export function worktreeInfo(c,d){const o=d(c,["rev-parse","--show-toplevel"]);if(!o)return;const r=d(c,["rev-parse","--path-format=absolute","--git-dir"]),e=d(c,["rev-parse","--path-format=absolute","--git-common-dir"]),E=!!r&&!!e&&Y(r)!==Y(e),h=E&&e&&Ne(e)===".git"?He(Y(e)):void 0;return{root:o,linked:E,...h?{mainRoot:h}:{}}}w(worktreeInfo,"worktreeInfo"),$(worktreeInfo,"worktreeInfo"),f(worktreeInfo,"worktreeInfo");export function nameFromFolder(c){return yt(Ne(c)).slice(0,20).replace(/-+$/,"")}w(nameFromFolder,"nameFromFolder"),$(nameFromFolder,"nameFromFolder"),f(nameFromFolder,"nameFromFolder");export function instanceConfig(c,d){const o=`${d.baseKey}-${d.name}`;return{...c,key:o,ports:mt(o),dashboardBasePath:"/"+o,sockNs:ht(o),instance:d}}w(instanceConfig,"instanceConfig"),$(instanceConfig,"instanceConfig"),f(instanceConfig,"instanceConfig");export function baseKeyOf(c,d){return c.instance?.baseKey?c.instance.baseKey:d&&K(R(d,".lensmcp","config.json"))?ee(d).key:c.key}w(baseKeyOf,"baseKeyOf"),$(baseKeyOf,"baseKeyOf"),f(baseKeyOf,"baseKeyOf");function J(c){if(!c||c.status!==200||!c.json||typeof c.json!="object")return[];const d=c.json.workspaces;return Array.isArray(d)?d:[]}w(J,"F"),$(J,"F"),f(J,"listed");export function resolveInstance(c,d,o){const r=c.filter(e=>typeof e.instance=="string");if(d){const e=r.find(P=>P.key===d);if(e)return e;const E=r.filter(P=>P.instance===d),h=E.find(P=>P.baseKey===(o.instance?.baseKey??o.key));if(h)return h;const[H,...de]=E;return H&&de.length===0?H:E.length>1?`'${d}' is an instance of ${E.map(P=>`'${P.baseKey}'`).join(" and ")} \u2014 name it by key: ${E.map(P=>P.key).join(", ")}.`:`no instance '${d}' is registered with the gateway${r.length?` (running: ${r.map(P=>P.key).join(", ")})`:""}.`}return o.instance?r.find(e=>e.key===o.key)??`this checkout's instance '${o.key}' is not registered with the gateway \u2014 \`lensmcp instance start\` here.`:"this checkout is not an instance \u2014 name one, or run `lensmcp instance list`."}w(resolveInstance,"resolveInstance"),$(resolveInstance,"resolveInstance"),f(resolveInstance,"resolveInstance");function D(c,d){for(const[o,r]of c.entries()){if(r===d)return c[o+1];if(r.startsWith(`${d}=`))return r.slice(d.length+1)}}w(D,"q"),$(D,"z"),f(D,"flag");function xe(c,d,o){const r=[];let e=!1;for(const E of c){if(e){e=!1;continue}if(d.includes(E)){e=!0;continue}d.some(h=>E.startsWith(`${h}=`))||o.includes(E)||r.push(E)}return r}w(xe,"Ae"),$(xe,"ft"),f(xe,"positionals");export async function runInstance(c,d,o,r,e){const E=c.indexOf("--"),h=E>=0?c.slice(0,E):c,H=E>=0?c.slice(E+1):[],de=["--cwd","--name","--apex","--branch","--from","--base"],[P,...U]=xe(h,de,["--json","--prepare","--no-prepare","--share-stores","--keep-data","--dry-run","--frozen","--live","--worktree","--delete-branch","--force","--detach"]),L={...process.env,...o.env??{}},B=o.registryFile??Qe(L),Se=f(n=>(o.resources??Ye)(n.filter(t=>!!t&&K(t))),"runtimeFor"),G=h.includes("--json"),A=Y(D(h,"--cwd")??d),M=o.gitExec??dt,ue=f((n,t)=>o.onStep?.(n,t),"step");if(E>=0&&(P??"").toLowerCase()!=="exec")return e(`\`--\` belongs to \`lensmcp instance exec\` only.
24
- ${INSTANCE_USAGE}`),{exitCode:2};switch((P??"").toLowerCase()){case"create":case"new":return pe(U[0]??D(h,"--name"));case"start":return le();case"list":case"ls":return he();case"status":return ye(U[0]);case"exec":return ke(U[0]);case"stop":return ge(U[0]);case"rm":case"remove":return we(U[0]);case"prune":return $e();default:return(P?e:r)(P?`Unknown instance command: ${P}
25
- ${INSTANCE_USAGE}`:INSTANCE_USAGE),{exitCode:P?2:0}}async function le(){const n=A,t=worktreeInfo(A,o.git),i=t?Ke(t.root,n):"",u=ee(n),s=D(h,"--name")??u.instance?.name??(t?.linked?nameFromFolder(t.root):void 0);if(!s)return e(`${n} is not a linked git worktree, so its instance has no name \u2014 pass \`--name <name>\`.`),{exitCode:2};if(!Le.test(s))return e(`'${s}' is not an instance name: one DNS label of at most 20 characters \u2014 lowercase letters, digits and inner hyphens.`),{exitCode:2};const p=D(h,"--apex")??u.instance?.apex,a=(t?.mainRoot?R(t.mainRoot,i):void 0)??u.instance?.mainRoot,y=h.includes("--frozen")?!0:h.includes("--live")?!1:u.instance?.frozen===!0,S={name:s,baseKey:baseKeyOf(u,a),...p?{apex:p.toLowerCase()}:{},...a?{mainRoot:a}:{},...y?{frozen:!0}:{}},k=instanceConfig(u,S),l=o.daemonRequest("GET","/list");if(l===null)return e("No gateway daemon is running. An instance is served by the main checkout's gateway \u2014"),e(`start it there first (\`lensmcp gateway start\`${a?` in ${a}`:""}), then run this again.`),{exitCode:1};const C=J(l),g=C.find(x=>x.key!==k.key&&x.root!==void 0&&ce(x.root,n));if(g?.instance)return e(`${n} is already served as instance '${g.instance}' (${g.key}). \`lensmcp instance stop\` first to rename it.`),{exitCode:1};if(g)return e(`${n} is already served by the gateway as '${g.key}'. An instance is a SECOND checkout \u2014 run this in a`),e("git worktree of it (`git worktree add <dir>`), or `lensmcp gateway stop` here first."),{exitCode:1};const N=Ue(C,k.key,n);if(N.kind==="other-checkout")return e(`'${k.key}' is already served from ${N.root}. Give this one another name: \`lensmcp instance start --name <name>\`.`),{exitCode:1};const b=a&&K(R(a,"nx.json"))?a:n,{decl:I,errors:m}=Re(b);if(m.length>0){e(`${R(b,"nx.json")} \u2192 lensmcp.instances is not usable:`);for(const x of m)e(` ${x}`);return{exitCode:2}}if(!I&&N.kind==="free"&&!h.includes("--share-stores"))return e(`${R(b,"nx.json")} declares no \`lensmcp.instances\`, so the instance would run on the main checkout's database and`),e("queues \u2014 whatever its .env points at: its workers would take main's jobs, its migrations would run on main's data."),e("Declare its resources (`lensmcp.instances.resources` \u2014 see `lensmcp instance --help`), or pass --share-stores."),{exitCode:1};let v;if(I){if(ue("provisioning",Object.keys(I.resources).length?`its data: ${Object.keys(I.resources).join(", ")}`:"bootstrapping the checkout"),a){const O=Ve(n,a,I.bootstrap);O.copied.length&&r(` copied \u2190 ${O.copied.join(", ")} (from ${a})`),O.cloned.length&&r(` cloned \u2190 ${O.cloned.join(", ")} (copy-on-write)`);for(const q of O.notes)r(` note: ${q}`)}const x={key:k.key,name:s,baseKey:S.baseKey,root:n,...a?{mainRoot:a}:{}};try{v=await ae(B,O=>et(I,x,O,Se([n,a]),L))}catch(O){return e(`could not give instance '${k.key}' its data: ${O.message}`),e("Whatever was already created is on record \u2014 `lensmcp instance rm` drops it."),{exitCode:1}}nt(n,v)}if(Ce(n,k),ue("registering","with the gateway"),N.kind==="free"){const x=o.daemonRequest("POST","/register",o.registrationBody(n,k.key));if(!x||x.status!==200)return e(`The gateway refused instance '${k.key}': ${Pe(x)??(x?JSON.stringify(x.json):"no response from the control socket")}`),{exitCode:1}}je(n,k.key);const j=Q(k.key),_={};for(const[x,O]of Object.entries(j?.env??{}))x.startsWith("LENSMCP_HOST_")&&(_[x.slice(13).toLowerCase()]=`https://${O}`);const W={name:s,key:k.key,baseKey:S.baseKey,root:n,...a?{mainRoot:a}:{},frozen:y,state:N.kind==="mine"?"already-running":"started",...j?.env.LENSMCP_APEX?{apex:j.env.LENSMCP_APEX}:{},hosts:_,dashboard:`https://lensmcp.local${k.dashboardBasePath}/`,resources:Object.keys(I?.resources??{}),created:v?.created??[],prepared:!1};if(r(`${N.kind==="mine"?"instance already running":"instance started"}: '${s}' of '${S.baseKey}' \u2014 key ${k.key}${y?" (frozen: compiled once, no watcher)":""}`),N.kind==="mine"&&u.instance?.frozen===!0!==y&&r(` note: it was already running ${u.instance?.frozen?"frozen":"live"} \u2014 \`lensmcp instance stop\` then \`start\` applies the change.`),j){r(` apex \u2192 ${j.env.LENSMCP_APEX??"?"}`);for(const[x,O]of Object.entries(j.env).filter(([q])=>q.startsWith("LENSMCP_HOST_")).sort())r(` ${x.slice(13).toLowerCase().padEnd(9)} \u2192 https://${O}`)}else r(" (the daemon did not report its hosts \u2014 it may predate instances, and serves this checkout under main's hosts)");if(r(` dashboard \u2192 https://lensmcp.local${k.dashboardBasePath}/`),v){for(const[x,O]of Object.entries(v.resolved))r(` ${x.padEnd(9)} = ${Xe(O)}`);v.created.length&&r(` created : ${v.created.join(", ")}`),N.kind==="mine"&&v.created.length&&r(" note: it was already running \u2014 `lensmcp instance stop` then `start` hands the new resources to its services.")}const F=I?.prepare;if(F&&!h.includes("--no-prepare")&&(h.includes("--prepare")||(v?.created.length??0)>0)){r(` prepare \u2192 ${F}`),ue("preparing",F);const x=(o.runPrepare??ie)(F,{cwd:n,env:{...L,...v?.resolved??{},...j?.env??{}}});if(x!==0)return e(`\`${F}\` exited ${x??"on a signal"}. The instance is up, but its data may not be ready \u2014 fix it and run \`lensmcp instance start --prepare\`.`),{exitCode:1,instance:W};W.prepared=!0}return r(" services start on their first request. `lensmcp instance exec -- <cmd>` runs a command with its variables;"),r(" `lensmcp instance stop` unregisters it, `lensmcp instance rm` also drops its data."),fe(k.key,W.prepared?"started again, prepared":"started again"),{exitCode:0,instance:W}}w(le,"me"),$(le,"xe"),f(le,"start");async function pe(n){const t=G?e:r;if(!n)return e(`Name the instance: \`lensmcp instance create <name>\`.
26
- ${INSTANCE_USAGE}`),{exitCode:2};if(!Le.test(n))return e(`'${n}' is not an instance name: one DNS label of at most 20 characters \u2014 lowercase letters, digits and inner hyphens.`),{exitCode:2};const i=worktreeInfo(A,o.git);if(!i)return e(`${A} is not in a git checkout \u2014 \`lensmcp instance create\` makes a git worktree of one.`),{exitCode:2};const u=i.linked?i.mainRoot:i.root;if(!u)return e(`${i.root} is a worktree whose main checkout git does not name (a bare repository?) \u2014 make the worktree yourself and \`lensmcp instance start\` in it.`),{exitCode:2};const s=Ke(i.root,A),p=R(u,s),a=baseKeyOf(ee(p),p),y=`${a}-${n}`,S=ot(Z(y,L));if("heldBy"in S)return e(`'${y}' is being created right now by another lensmcp (pid ${S.heldBy}). Wait for it \u2014 \`lensmcp instance list\` shows it \u2014 or pick another name.`),{exitCode:1};try{const{decl:k,errors:l}=Re(K(R(p,"nx.json"))?p:A);if(l.length>0){e(`${R(p,"nx.json")} \u2192 lensmcp.instances is not usable:`);for(const T of l)e(` ${T}`);return{exitCode:2}}if(!k&&!h.includes("--share-stores"))return e(`${R(p,"nx.json")} declares no \`lensmcp.instances\`, so a new instance would run on the main checkout's database and`),e("queues. Declare its resources (`lensmcp.instances.resources`), or pass --share-stores."),{exitCode:1};const C=ft(p,k?.worktrees,L),g=R(C,n),N=R(g,s);if(K(g))return e(`${g} already exists. \`lensmcp instance start\` in it serves it; or pick another name.`),{exitCode:1};const b=oe(B).instances[y];if(b)return e(`'${y}' is already on record for ${b.root}${K(b.root)?"":" (its folder is gone \u2014 `lensmcp instance prune` clears it)"}. Pick another name.`),{exitCode:1};const I=o.daemonRequest("GET","/list");if(I===null)return e("No gateway daemon is running. An instance is served by the main checkout's gateway \u2014"),e(`start it there first (\`lensmcp gateway start\` in ${p}), then run this again.`),{exitCode:1};if(J(I).some(T=>T.key===y))return e(`'${y}' is already served by the gateway. Pick another name.`),{exitCode:1};const m=h.includes("--detach")?void 0:D(h,"--branch")??`lensmcp/${n}`;if(m){const T=rt(u,m,M);if(T)return e(T),{exitCode:2}}const v=D(h,"--from");if(m&&v&&me(u,["show-ref","--verify","--quiet",`refs/heads/${m}`]))return e(`Branch '${m}' exists already, so it is checked out as it is \u2014 --from applies to a new branch. Drop --from, or name a new --branch.`),{exitCode:2};const j=lt(A,v??"HEAD",M);if("error"in j)return e(j.error),{exitCode:2};const _=ct(u,C,M);_&&t(` ignored : ${_} (added to .git/info/exclude \u2014 the worktrees stay out of main's git status)`);const W=Z(y,L),F=new Date().toISOString();let x={key:y,name:n,baseKey:a,root:N,state:"creating",detail:`git worktree add ${g}`,pid:process.pid,startedAt:F,updatedAt:F,...L.LENSMCP_CREATE_LOG?{log:L.LENSMCP_CREATE_LOG}:{}};const O=f(T=>{x={...x,...T,updatedAt:new Date().toISOString()};try{Ie(W,x)}catch{}},"record");O({});const q=st(u,g,{...m?{branch:m}:{},from:j.sha},M);if(!q.ok)return O({state:"failed",detail:q.error}),e(`git could not make the worktree: ${q.error}`),{exitCode:1};const be={path:g,...m?{branch:m}:{},createdBranch:q.createdBranch,from:j.sha,createdAt:F};O({worktree:be,detail:"worktree made"}),t(`worktree : ${g} \u2014 ${m?`branch ${m}${q.createdBranch?" (new)":""}`:"detached"} at ${j.sha.slice(0,12)}`);const _e={key:y,name:n,baseKey:a,root:N,...p!==N?{mainRoot:p}:{},createdAt:F,resources:{},worktree:be};await ae(B,T=>{T.instances[y]=_e});const ze=["--frozen","--live","--prepare","--no-prepare","--share-stores"].filter(T=>h.includes(T)),Oe=D(h,"--apex"),De=["start","--name",n,...Oe?["--apex",Oe]:[],...ze],V=await runInstance(De,N,{...o,...G&&!o.runPrepare?{runPrepare:f((T,se)=>ie(T,se,!0),"runPrepare")}:{},onStep:f((T,se)=>O({state:T,...se?{detail:se}:{}}),"onStep")},t,e),z=V.instance?{...V.instance,worktree:be}:void 0;return V.exitCode!==0?(O({state:"failed",detail:`${V.instance?"started, but `prepare` failed":"could not start"} \u2014 \`lensmcp instance rm ${n} --worktree\` takes it away`,...z?{result:z}:{}}),e(`The worktree is at ${g}. \`lensmcp instance start --prepare\` there retries; \`lensmcp instance rm ${n} --worktree\` takes it all away.`),G&&z&&r(JSON.stringify(z,null,2)),{exitCode:V.exitCode,...z?{instance:z}:{}}):(O({state:"ready",detail:"ready",...z?{result:z}:{}}),G&&r(JSON.stringify(z,null,2)),{exitCode:0,...z?{instance:z}:{}})}finally{S.release()}}w(pe,"fe"),$(pe,"Ce"),f(pe,"create");function fe(n,t){const i=Z(n,L),u=Ae(i);if(!(!u||u.state==="ready"||u.pid===process.pid))try{Ie(i,{...u,state:"ready",detail:t,updatedAt:new Date().toISOString()})}catch{}}w(fe,"he"),$(fe,"je"),f(fe,"settleCreate");function me(n,t){return M(n,t).ok}w(me,"ye"),$(me,"Se"),f(me,"gitExecOk");function he(){const n=o.daemonRequest("GET","/list"),t=D(h,"--base"),i=f(a=>!t||a===t,"ofBase"),u=J(n).filter(a=>typeof a.instance=="string"&&i(a.baseKey)),s=oe(B),p=Object.values(s.instances).filter(a=>!u.some(y=>y.key===a.key)&&i(a.baseKey));if(G){const a=f(l=>{if(!l||!K(l))return{};const C=Te(l,M),g=at(l,M);return{...g?{branch:g}:{},...C?{changes:C.length}:{}}},"gitFacts"),y=f(l=>{const C=Ae(Z(l,L));if(!C||C.state==="ready")return{};const g=pt(C);return{progress:{state:g.state,...g.detail?{detail:g.detail}:{},updatedAt:g.updatedAt,...g.log?{log:g.log}:{}}}},"unfinished"),S=f(l=>{const C={};for(const[g,N]of Object.entries(Q(l)?.env??{}))g.startsWith("LENSMCP_HOST_")&&(C[g.slice(13).toLowerCase()]=`https://${N}`);return Object.keys(C).length?{hosts:C}:{}},"hostsOf"),k=u.map(l=>({...l,...a(l.root),...S(l.key),...s.instances[l.key]?.worktree?{worktree:s.instances[l.key]?.worktree}:{},...y(l.key)}));return r(JSON.stringify({checkout:{root:A,...a(A)},instances:k,stopped:p.map(l=>({key:l.key,name:l.name,baseKey:l.baseKey,root:l.root,resources:Object.keys(l.resources),folderGone:!K(l.root),...a(l.root),...l.worktree?{worktree:l.worktree}:{},...y(l.key)}))},null,2)),{exitCode:0}}if(n===null&&r("(no gateway daemon is running)"),u.length===0&&p.length===0)return r("No instances. `lensmcp instance start` in a worktree serves one."),{exitCode:0};for(const a of u){const y=Object.keys(s.instances[a.key]?.resources??{});r(`${a.instance} (${a.key}, instance of ${a.baseKey}) ${a.apex??""}${a.frozen?" frozen":""} ${a.services??0} service(s)${y.length?` data: ${y.join(", ")}`:""} ${a.root??""}`)}for(const a of p){const y=!K(a.root);r(`${a.name} (${a.key}, instance of ${a.baseKey}) ${y?"FOLDER GONE \u2014 `lensmcp instance prune`":"stopped"} data: ${Object.keys(a.resources).join(", ")||"none"} ${a.root}`)}return{exitCode:0}}w(he,"ke"),$(he,"Oe"),f(he,"list");function X(n){const t=o.daemonRequest("GET","/list");if(t===null){e("No gateway daemon is running.");return}const i=resolveInstance(J(t),n,ee(A));if(typeof i=="string"){e(i);return}return i}w(X,"V"),$(X,"re"),f(X,"target");function ye(n){const t=X(n);if(!t)return{exitCode:1};const i=o.daemonRequest("GET","/status"),u=i?.status===200&&i.json&&typeof i.json=="object"?(i.json.services??[]).filter(s=>s.wsKey===t.key):[];if(G)return r(JSON.stringify({instance:t,services:u},null,2)),{exitCode:0};r(`${t.instance} (${t.key}, instance of ${t.baseKey}) \u2014 ${t.apex??"?"} ${t.root??""}`),u.length===0&&r(" no pod services");for(const s of u)r(` ${s.project.padEnd(24)} ${s.state.padEnd(9)} ${s.host?`https://${s.host}`:""}`);return{exitCode:0}}w(ye,"ge"),$(ye,"Ee"),f(ye,"status");async function ke(n){if(H.length===0)return e("Nothing to run: `lensmcp instance exec [<name>] -- <command> [args\u2026]`."),{exitCode:2};const t=X(n);if(!t)return{exitCode:1};const i=Q(t.key);if(!i)return e(`The gateway did not give the variables of '${t.key}'.`),{exitCode:1};const[u,...s]=H;return new Promise(p=>{const a=Be(u,s,{cwd:t.root??A,stdio:"inherit",env:{...process.env,...o.env??{},...i.env}});a.on("error",y=>{e(`could not run ${u}: ${y.message}`),p({exitCode:127})}),a.on("exit",(y,S)=>p({exitCode:y??(S?128:1)}))})}w(ke,"we"),$(ke,"Ne"),f(ke,"exec");function ge(n){const t=X(n);if(!t)return{exitCode:1};const i=o.daemonRequest("POST","/unregister",{wsKey:t.key,...t.root?{root:t.root}:{}});return!i||i.status!==200?(e(`could not stop '${t.key}': ${Pe(i)??(i?JSON.stringify(i.json):"no response from the control socket")}`),{exitCode:1}):(t.root&&re(R(t.root,".lensmcp","registered.json"),{force:!0}),r(`stopped '${t.key}': its hosts are gone and its services are stopping. \`lensmcp instance start\` in ${t.root??"it"} brings it back.`),{exitCode:0})}w(ge,"$e"),$(ge,"Pe"),f(ge,"stop");function te(n,t,i){const u=i.find(p=>p.key===n);if(!u)return!1;const s=o.daemonRequest("POST","/unregister",{wsKey:n,...u.root??t?{root:u.root??t}:{}});return!!s&&s.status===200}w(te,"ae"),$(te,"de"),f(te,"unregisterIfServed");async function ne(n,t,i=r,u){const s=await ae(B,p=>Ze(n,p,Se(t),L));s.dropped.length&&i(` dropped : ${s.dropped.join(", ")}`);for(const p of s.failed)e(` could not drop ${p.name}: ${p.error} \u2014 still on record; run this again once it can be reached`);return u&&Object.assign(u,{dropped:s.dropped,...s.failed.length?{dropFailed:s.failed}:{}}),s.failed.length===0}w(ne,"ie"),$(ne,"le"),f(ne,"dropData");async function we(n){const t=oe(B),i=J(o.daemonRequest("GET","/list")),u=[...i.filter(m=>typeof m.instance=="string"),...Object.values(t.instances).filter(m=>!i.some(v=>v.key===m.key)).map(m=>({key:m.key,root:m.root,instance:m.name,baseKey:m.baseKey}))],s=(n?void 0:u.find(m=>m.root!==void 0&&ce(m.root,A)))??resolveInstance(u,n,ee(A)),p={},a=f(m=>(G&&r(JSON.stringify({...p,exitCode:m},null,2)),{exitCode:m}),"finish");if(typeof s=="string")return e(s.replace("is registered with the gateway","is served or on record")),a(1);const y=D(h,"--base");if(y&&s.baseKey!==y)return e(`'${s.key}' is an instance of '${s.baseKey}', not of '${y}'.`),a(1);const S=s.key,k=t.instances[S],l=s.root??k?.root,C=G?e:r;Object.assign(p,{key:S,name:s.instance,...l?{root:l}:{}});const g=h.includes("--worktree"),N=h.includes("--force"),b=k?.worktree?.path??(l&&K(l)?worktreeInfo(l,o.git)?.root:void 0);if(g){const m=b&&K(b)?worktreeInfo(b,o.git):void 0;if(b&&K(b)&&!m?.linked)return e(`${b} is not a linked git worktree \u2014 not removing it (the lens removes only worktrees).`),a(1);if(b&&K(b)&&!N){const v=Te(b,M);if(v===void 0||v.length>0){p.uncommitted=v??["(git could not read its status)"],e(`${b} has uncommitted work \u2014 commit it (or stash it) first; --force throws it away:`);for(const j of(v??["(git could not read its status)"]).slice(0,20))e(` ${j}`);return(v?.length??0)>20&&e(` \u2026 and ${(v?.length??0)-20} more`),a(1)}}}C(`removing instance '${s.instance}' (${S})${l?` \u2014 ${l}`:""}`),te(S,l,i)&&(C(" stopped : its routes are gone, its services are stopping"),p.stopped=!0);let I=!0;if(h.includes("--keep-data")?(k&&Object.keys(k.resources).length&&C(` kept : ${Object.keys(k.resources).join(", ")} (on record \u2014 \`start\` reuses it, \`rm\` drops it)`),p.keptData=Object.keys(k?.resources??{})):I=await ne(S,[l,k?.mainRoot,A],C,p),l&&K(l)){const m=o.stopMcpServer?.(l,S);m&&C(` mcp : ${m}`),clearInstanceState(l,S)}if(re(Z(S,L),{force:!0}),g&&b&&K(b)){const m=k?.mainRoot??worktreeInfo(b,o.git)?.mainRoot??A,v=ut(m,b,N,M);v.ok?(C(` removed : the worktree ${b}`),p.worktreeRemoved=b,k?.worktree&&await ae(B,_=>{delete _.instances[S]?.worktree})):(e(` could not remove the worktree ${b}: ${v.err}`),p.worktreeError=v.err,I=!1);const j=k?.worktree?.branch;if(v.ok&&j&&h.includes("--delete-branch"))if(!k?.worktree?.createdBranch)C(` kept : branch ${j} (it existed before the lens checked it out)`),p.branchKept={branch:j,why:"not made by the lens"};else{const _=it(m,j,N,M);_.ok?(C(` deleted : branch ${j}`),p.branchDeleted=j):(C(` kept : branch ${j} \u2014 ${_.err.split(`
27
- `)[0]}`),p.branchKept={branch:j,why:_.err.split(`
28
- `)[0]})}else v.ok&&j&&(p.branchKept={branch:j,why:"not asked to delete it"})}else b&&K(b)&&(p.worktreeKept=b);return a(I?0:1)}w(we,"be"),$(we,"Re"),f(we,"rm");async function $e(){const n=oe(B),t=J(o.daemonRequest("GET","/list")),i=new Map;for(const s of Object.values(n.instances))K(s.root)||i.set(s.key,s.root);for(const s of t)s.instance&&s.root&&!K(s.root)&&i.set(s.key,s.root);if(i.size===0)return r("Nothing to prune: every instance on record still has its folder."),{exitCode:0};let u=!0;for(const[s,p]of i)r(`${h.includes("--dry-run")?"would remove":"removing"} '${s}' \u2014 ${p} is gone${n.instances[s]?`; data: ${Object.keys(n.instances[s].resources).join(", ")||"none"}`:""}`),!h.includes("--dry-run")&&(te(s,p,t)&&r(" stopped : its routes are gone"),n.instances[s]&&(u=await ne(s,[n.instances[s].mainRoot,A])&&u));return{exitCode:u?0:1}}w($e,"ve"),$($e,"Ke"),f($e,"prune");function Q(n){const t=o.daemonRequest("GET",`/instance-env?wsKey=${encodeURIComponent(n)}`);if(!t||t.status!==200||!t.json||typeof t.json!="object")return;const i=t.json.env;return i&&typeof i=="object"?{env:i}:void 0}w(Q,"Z"),$(Q,"oe"),f(Q,"instanceEnvOf")}w(runInstance,"runInstance"),$(runInstance,"runInstance"),f(runInstance,"runInstance");function ie(c,d,o=!1){return Ge(c,{cwd:d.cwd,env:d.env,shell:!0,stdio:o?["inherit",2,2]:"inherit"}).status}w(ie,"ue"),$(ie,"be"),f(ie,"runShell");export function clearInstanceState(c,d){re(R(c,".lensmcp","registered.json"),{force:!0}),re(tt(c),{force:!0});const o=R(c,".lensmcp","config.json");let r;try{r=JSON.parse(Je(o,"utf8"))}catch{return}if(r.key===d){for(const e of["key","ports","dashboardBasePath","sockNs","instance"])delete r[e];ve(o,JSON.stringify(r,null,2)+`
29
- `)}}w(clearInstanceState,"clearInstanceState"),$(clearInstanceState,"clearInstanceState"),f(clearInstanceState,"clearInstanceState");function ce(c,d){const o=f(r=>{try{return We(r)}catch{return Y(r)}},"canonical");return o(c)===o(d)}w(ce,"le"),$(ce,"ve"),f(ce,"sameDir");function Ce(c,d){const o=R(c,".lensmcp");K(o)||Ee(o,{recursive:!0}),ve(R(o,"config.json"),JSON.stringify(d,null,2)+`
30
- `)}w(Ce,"Te"),$(Ce,"ut"),f(Ce,"writeConfig");function je(c,d){Ee(R(c,".lensmcp"),{recursive:!0}),ve(R(c,".lensmcp","registered.json"),JSON.stringify({wsKey:d}))}w(je,"_e"),$(je,"pt"),f(je,"writeMarker");
23
+ Remove every instance whose folder is gone, data included.`;export function worktreeInfo(c,l){const o=l(c,["rev-parse","--show-toplevel"]);if(!o)return;const r=l(c,["rev-parse","--path-format=absolute","--git-dir"]),e=l(c,["rev-parse","--path-format=absolute","--git-common-dir"]),O=!!r&&!!e&&X(r)!==X(e),h=O&&e&&je(e)===".git"?Je(X(e)):void 0;return{root:o,linked:O,...h?{mainRoot:h}:{}}}w(worktreeInfo,"worktreeInfo"),m(worktreeInfo,"worktreeInfo");export function nameFromFolder(c){return ft(je(c)).slice(0,20).replace(/-+$/,"")}w(nameFromFolder,"nameFromFolder"),m(nameFromFolder,"nameFromFolder");export function instanceConfig(c,l){const o=`${l.baseKey}-${l.name}`;return{...c,key:o,ports:pt(o),dashboardBasePath:"/"+o,sockNs:mt(o),instance:l}}w(instanceConfig,"instanceConfig"),m(instanceConfig,"instanceConfig");export function baseKeyOf(c,l){return c.instance?.baseKey?c.instance.baseKey:l&&N(R(l,".lensmcp","config.json"))?Q(l).key:c.key}w(baseKeyOf,"baseKeyOf"),m(baseKeyOf,"baseKeyOf");function G(c){if(!c||c.status!==200||!c.json||typeof c.json!="object")return[];const l=c.json.workspaces;return Array.isArray(l)?l:[]}w(G,"J"),m(G,"listed");export function resolveInstance(c,l,o){const r=c.filter(e=>typeof e.instance=="string");if(l){const e=r.find(P=>P.key===l);if(e)return e;const O=r.filter(P=>P.instance===l),h=O.find(P=>P.baseKey===(o.instance?.baseKey??o.key));if(h)return h;const[W,...re]=O;return W&&re.length===0?W:O.length>1?`'${l}' is an instance of ${O.map(P=>`'${P.baseKey}'`).join(" and ")} \u2014 name it by key: ${O.map(P=>P.key).join(", ")}.`:`no instance '${l}' is registered with the gateway${r.length?` (running: ${r.map(P=>P.key).join(", ")})`:""}.`}return o.instance?r.find(e=>e.key===o.key)??`this checkout's instance '${o.key}' is not registered with the gateway \u2014 \`lensmcp instance start\` here.`:"this checkout is not an instance \u2014 name one, or run `lensmcp instance list`."}w(resolveInstance,"resolveInstance"),m(resolveInstance,"resolveInstance");function B(c,l){for(const[o,r]of c.entries()){if(r===l)return c[o+1];if(r.startsWith(`${l}=`))return r.slice(l.length+1)}}w(B,"z"),m(B,"flag");function Ae(c,l,o){const r=[];let e=!1;for(const O of c){if(e){e=!1;continue}if(l.includes(O)){e=!0;continue}l.some(h=>O.startsWith(`${h}=`))||o.includes(O)||r.push(O)}return r}w(Ae,"ft"),m(Ae,"positionals");export async function runInstance(c,l,o,r,e){const O=c.indexOf("--"),h=O>=0?c.slice(0,O):c,W=O>=0?c.slice(O+1):[],re=["--cwd","--name","--apex","--branch","--from","--base"],[P,...H]=Ae(h,re,["--json","--prepare","--no-prepare","--share-stores","--keep-data","--dry-run","--frozen","--live","--worktree","--delete-branch","--force","--detach"]),_={...process.env,...o.env??{}},q=o.registryFile??Ue(_),pe=m(n=>(o.resources??Ye)(n.filter(t=>!!t&&N(t))),"runtimeFor"),F=h.includes("--json"),K=X(B(h,"--cwd")??l),M=o.gitExec??it,oe=m((n,t)=>o.onStep?.(n,t),"step");if(O>=0&&(P??"").toLowerCase()!=="exec")return e(`\`--\` belongs to \`lensmcp instance exec\` only.
24
+ ${INSTANCE_USAGE}`),{exitCode:2};switch((P??"").toLowerCase()){case"create":case"new":return fe(H[0]??B(h,"--name"));case"start":return me();case"list":case"ls":return ke();case"status":return ge(H[0]);case"exec":return we(H[0]);case"stop":return $e(H[0]);case"rm":case"remove":return be(H[0]);case"prune":return ve();default:return(P?e:r)(P?`Unknown instance command: ${P}
25
+ ${INSTANCE_USAGE}`:INSTANCE_USAGE),{exitCode:P?2:0}}async function me(){const n=K,t=worktreeInfo(K,o.git),i=t?Se(t.root,n):"",d=Q(n),s=B(h,"--name")??d.instance?.name??(t?.linked?nameFromFolder(t.root):void 0);if(!s)return e(`${n} is not a linked git worktree, so its instance has no name \u2014 pass \`--name <name>\`.`),{exitCode:2};if(!Ke.test(s))return e(`'${s}' is not an instance name: one DNS label of at most 20 characters \u2014 lowercase letters, digits and inner hyphens.`),{exitCode:2};const p=B(h,"--apex")??d.instance?.apex,a=(t?.mainRoot?R(t.mainRoot,i):void 0)??d.instance?.mainRoot,y=h.includes("--frozen")?!0:h.includes("--live")?!1:d.instance?.frozen===!0,j={name:s,baseKey:baseKeyOf(d,a),...p?{apex:p.toLowerCase()}:{},...a?{mainRoot:a}:{},...y?{frozen:!0}:{}},k=instanceConfig(d,j),u=o.daemonRequest("GET","/list");if(u===null)return e("No gateway daemon is running. An instance is served by the main checkout's gateway \u2014"),e(`start it there first (\`lensmcp gateway start\`${a?` in ${a}`:""}), then run this again.`),{exitCode:1};const x=G(u),g=x.find(v=>v.key!==k.key&&v.root!==void 0&&le(v.root,n));if(g?.instance)return e(`${n} is already served as instance '${g.instance}' (${g.key}). \`lensmcp instance stop\` first to rename it.`),{exitCode:1};if(g)return e(`${n} is already served by the gateway as '${g.key}'. An instance is a SECOND checkout \u2014 run this in a`),e("git worktree of it (`git worktree add <dir>`), or `lensmcp gateway stop` here first."),{exitCode:1};const E=We(x,k.key,n);if(E.kind==="other-checkout")return e(`'${k.key}' is already served from ${E.root}. Give this one another name: \`lensmcp instance start --name <name>\`.`),{exitCode:1};const $=a&&N(R(a,"nx.json"))?a:n,{decl:T,errors:f}=Ee($);if(f.length>0){e(`${R($,"nx.json")} \u2192 lensmcp.instances is not usable:`);for(const v of f)e(` ${v}`);return{exitCode:2}}if(!T&&E.kind==="free"&&!h.includes("--share-stores"))return e(`${R($,"nx.json")} declares no \`lensmcp.instances\`, so the instance would run on the main checkout's database and`),e("queues \u2014 whatever its .env points at: its workers would take main's jobs, its migrations would run on main's data."),e("Declare its resources (`lensmcp.instances.resources` \u2014 see `lensmcp instance --help`), or pass --share-stores."),{exitCode:1};let b;if(T){if(oe("provisioning",Object.keys(T.resources).length?`its data: ${Object.keys(T.resources).join(", ")}`:"bootstrapping the checkout"),a){const S=Xe(n,a,T.bootstrap);S.copied.length&&r(` copied \u2190 ${S.copied.join(", ")} (from ${a})`),S.cloned.length&&r(` cloned \u2190 ${S.cloned.join(", ")} (copy-on-write)`);for(const z of S.notes)r(` note: ${z}`)}const v={key:k.key,name:s,baseKey:j.baseKey,root:n,...a?{mainRoot:a}:{}};try{b=await se(q,S=>Ve(T,v,S,pe([n,a]),_))}catch(S){return e(`could not give instance '${k.key}' its data: ${S.message}`),e("Whatever was already created is on record \u2014 `lensmcp instance rm` drops it."),{exitCode:1}}et(n,b)}if(Te(n,k),oe("registering","with the gateway"),E.kind==="free"){const v=o.daemonRequest("POST","/register",o.registrationBody(n,k.key));if(!v||v.status!==200)return e(`The gateway refused instance '${k.key}': ${Oe(v)??(v?JSON.stringify(v.json):"no response from the control socket")}`),{exitCode:1}}_e(n,k.key);const C=Z(k.key),I={};for(const[v,S]of Object.entries(C?.env??{}))v.startsWith("LENSMCP_HOST_")&&(I[v.slice(13).toLowerCase()]=`https://${S}`);const J={name:s,key:k.key,baseKey:j.baseKey,root:n,...a?{mainRoot:a}:{},frozen:y,state:E.kind==="mine"?"already-running":"started",...C?.env.LENSMCP_APEX?{apex:C.env.LENSMCP_APEX}:{},hosts:I,dashboard:`https://lensmcp.local${k.dashboardBasePath}/`,resources:Object.keys(T?.resources??{}),created:b?.created??[],prepared:!1};if(r(`${E.kind==="mine"?"instance already running":"instance started"}: '${s}' of '${j.baseKey}' \u2014 key ${k.key}${y?" (frozen: compiled once, no watcher)":""}`),E.kind==="mine"&&d.instance?.frozen===!0!==y&&r(` note: it was already running ${d.instance?.frozen?"frozen":"live"} \u2014 \`lensmcp instance stop\` then \`start\` applies the change.`),C){r(` apex \u2192 ${C.env.LENSMCP_APEX??"?"}`);for(const[v,S]of Object.entries(C.env).filter(([z])=>z.startsWith("LENSMCP_HOST_")).sort())r(` ${v.slice(13).toLowerCase().padEnd(9)} \u2192 https://${S}`)}else r(" (the daemon did not report its hosts \u2014 it may predate instances, and serves this checkout under main's hosts)");if(r(` dashboard \u2192 https://lensmcp.local${k.dashboardBasePath}/`),b){for(const[v,S]of Object.entries(b.resolved))r(` ${v.padEnd(9)} = ${He(S)}`);b.created.length&&r(` created : ${b.created.join(", ")}`),E.kind==="mine"&&b.created.length&&r(" note: it was already running \u2014 `lensmcp instance stop` then `start` hands the new resources to its services.")}const D=T?.prepare;if(D&&!h.includes("--no-prepare")&&(h.includes("--prepare")||(b?.created.length??0)>0)){r(` prepare \u2192 ${D}`),oe("preparing",D);const v=(o.runPrepare??ue)(D,{cwd:n,env:{..._,...b?.resolved??{},...C?.env??{}}});if(v!==0)return e(`\`${D}\` exited ${v??"on a signal"}. The instance is up, but its data may not be ready \u2014 fix it and run \`lensmcp instance start --prepare\`.`),{exitCode:1,instance:J};J.prepared=!0}return r(" its always-warm services start now, one at a time while the machine has memory to spare (LENSMCP_WARM_MIN_FREE_MB);"),r(" the rest on their first request, and each stops after 30 min unused. `lensmcp instance exec -- <cmd>` runs a command with its variables;"),r(" `lensmcp instance stop` unregisters it, `lensmcp instance rm` also drops its data."),he(k.key,J.prepared?"started again, prepared":"started again"),{exitCode:0,instance:J}}w(me,"xe"),m(me,"start");async function fe(n){const t=F?e:r;if(!n)return e(`Name the instance: \`lensmcp instance create <name>\`.
26
+ ${INSTANCE_USAGE}`),{exitCode:2};if(!Ke.test(n))return e(`'${n}' is not an instance name: one DNS label of at most 20 characters \u2014 lowercase letters, digits and inner hyphens.`),{exitCode:2};const i=worktreeInfo(K,o.git);if(!i)return e(`${K} is not in a git checkout \u2014 \`lensmcp instance create\` makes a git worktree of one.`),{exitCode:2};const d=i.linked?i.mainRoot:i.root;if(!d)return e(`${i.root} is a worktree whose main checkout git does not name (a bare repository?) \u2014 make the worktree yourself and \`lensmcp instance start\` in it.`),{exitCode:2};const s=Se(i.root,K),p=R(d,s),a=baseKeyOf(Q(p),p),y=`${a}-${n}`,j=st(Y(y,_));if("heldBy"in j)return e(`'${y}' is being created right now by another lensmcp (pid ${j.heldBy}). Wait for it \u2014 \`lensmcp instance list\` shows it \u2014 or pick another name.`),{exitCode:1};try{const{decl:k,errors:u}=Ee(N(R(p,"nx.json"))?p:K);if(u.length>0){e(`${R(p,"nx.json")} \u2192 lensmcp.instances is not usable:`);for(const A of u)e(` ${A}`);return{exitCode:2}}if(!k&&!h.includes("--share-stores"))return e(`${R(p,"nx.json")} declares no \`lensmcp.instances\`, so a new instance would run on the main checkout's database and`),e("queues. Declare its resources (`lensmcp.instances.resources`), or pass --share-stores."),{exitCode:1};const x=lt(p,k?.worktrees,_),g=R(x,n),E=R(g,s);if(N(g))return e(`${g} already exists. \`lensmcp instance start\` in it serves it; or pick another name.`),{exitCode:1};const $=ne(q).instances[y];if($)return e(`'${y}' is already on record for ${$.root}${N($.root)?"":" (its folder is gone \u2014 `lensmcp instance prune` clears it)"}. Pick another name.`),{exitCode:1};const T=o.daemonRequest("GET","/list");if(T===null)return e("No gateway daemon is running. An instance is served by the main checkout's gateway \u2014"),e(`start it there first (\`lensmcp gateway start\` in ${p}), then run this again.`),{exitCode:1};if(G(T).some(A=>A.key===y))return e(`'${y}' is already served by the gateway. Pick another name.`),{exitCode:1};const f=h.includes("--detach")?void 0:B(h,"--branch")??`lensmcp/${n}`;if(f){const A=nt(d,f,M);if(A)return e(A),{exitCode:2}}const b=B(h,"--from");if(f&&b&&ye(d,["show-ref","--verify","--quiet",`refs/heads/${f}`]))return e(`Branch '${f}' exists already, so it is checked out as it is \u2014 --from applies to a new branch. Drop --from, or name a new --branch.`),{exitCode:2};const C=dt(K,b??"HEAD",M);if("error"in C)return e(C.error),{exitCode:2};const I=at(d,x,M);I&&t(` ignored : ${I} (added to .git/info/exclude \u2014 the worktrees stay out of main's git status)`);const J=Y(y,_),D=new Date().toISOString();let v={key:y,name:n,baseKey:a,root:E,state:"creating",detail:`git worktree add ${g}`,pid:process.pid,startedAt:D,updatedAt:D,..._.LENSMCP_CREATE_LOG?{log:_.LENSMCP_CREATE_LOG}:{}};const S=m(A=>{v={...v,...A,updatedAt:new Date().toISOString()};try{Re(J,v)}catch{}},"record");S({});const z=tt(d,g,{...f?{branch:f}:{},from:C.sha},M);if(!z.ok)return S({state:"failed",detail:z.error}),e(`git could not make the worktree: ${z.error}`),{exitCode:1};const ce={path:g,...f?{branch:f}:{},createdBranch:z.createdBranch,from:C.sha,createdAt:D};S({worktree:ce,detail:"worktree made"}),t(`worktree : ${g} \u2014 ${f?`branch ${f}${z.createdBranch?" (new)":""}`:"detached"} at ${C.sha.slice(0,12)}`);const Ie={key:y,name:n,baseKey:a,root:E,...p!==E?{mainRoot:p}:{},createdAt:D,resources:{},worktree:ce};await se(q,A=>{A.instances[y]=Ie});const Le=["--frozen","--live","--prepare","--no-prepare","--share-stores"].filter(A=>h.includes(A)),xe=B(h,"--apex"),Me=["start","--name",n,...xe?["--apex",xe]:[],...Le],U=await runInstance(Me,E,{...o,...F&&!o.runPrepare?{runPrepare:m((A,ee)=>ue(A,ee,!0),"runPrepare")}:{},onStep:m((A,ee)=>S({state:A,...ee?{detail:ee}:{}}),"onStep")},t,e),L=U.instance?{...U.instance,worktree:ce}:void 0;return U.exitCode!==0?(S({state:"failed",detail:`${U.instance?"started, but `prepare` failed":"could not start"} \u2014 \`lensmcp instance rm ${n} --worktree\` takes it away`,...L?{result:L}:{}}),e(`The worktree is at ${g}. \`lensmcp instance start --prepare\` there retries; \`lensmcp instance rm ${n} --worktree\` takes it all away.`),F&&L&&r(JSON.stringify(L,null,2)),{exitCode:U.exitCode,...L?{instance:L}:{}}):(S({state:"ready",detail:"ready",...L?{result:L}:{}}),F&&r(JSON.stringify(L,null,2)),{exitCode:0,...L?{instance:L}:{}})}finally{j.release()}}w(fe,"Ce"),m(fe,"create");function he(n,t){const i=Y(n,_),d=Ne(i);if(!(!d||d.state==="ready"||d.pid===process.pid))try{Re(i,{...d,state:"ready",detail:t,updatedAt:new Date().toISOString()})}catch{}}w(he,"je"),m(he,"settleCreate");function ye(n,t){return M(n,t).ok}w(ye,"Se"),m(ye,"gitExecOk");function ke(){const n=o.daemonRequest("GET","/list"),t=B(h,"--base"),i=m(a=>!t||a===t,"ofBase"),d=G(n).filter(a=>typeof a.instance=="string"&&i(a.baseKey)),s=ne(q),p=Object.values(s.instances).filter(a=>!d.some(y=>y.key===a.key)&&i(a.baseKey));if(F){const a=m(u=>{if(!u||!N(u))return{};const x=Pe(u,M),g=rt(u,M);return{...g?{branch:g}:{},...x?{changes:x.length}:{}}},"gitFacts"),y=m(u=>{const x=Ne(Y(u,_));if(!x||x.state==="ready")return{};const g=ut(x);return{progress:{state:g.state,...g.detail?{detail:g.detail}:{},updatedAt:g.updatedAt,...g.log?{log:g.log}:{}}}},"unfinished"),j=m(u=>{const x={};for(const[g,E]of Object.entries(Z(u)?.env??{}))g.startsWith("LENSMCP_HOST_")&&(x[g.slice(13).toLowerCase()]=`https://${E}`);return Object.keys(x).length?{hosts:x}:{}},"hostsOf"),k=d.map(u=>({...u,...a(u.root),...j(u.key),...s.instances[u.key]?.worktree?{worktree:s.instances[u.key]?.worktree}:{},...y(u.key)}));return r(JSON.stringify({checkout:{root:K,...a(K)},instances:k,stopped:p.map(u=>({key:u.key,name:u.name,baseKey:u.baseKey,root:u.root,resources:Object.keys(u.resources),folderGone:!N(u.root),...a(u.root),...u.worktree?{worktree:u.worktree}:{},...y(u.key)}))},null,2)),{exitCode:0}}if(n===null&&r("(no gateway daemon is running)"),d.length===0&&p.length===0)return r("No instances. `lensmcp instance start` in a worktree serves one."),{exitCode:0};for(const a of d){const y=Object.keys(s.instances[a.key]?.resources??{});r(`${a.instance} (${a.key}, instance of ${a.baseKey}) ${a.apex??""}${a.frozen?" frozen":""} ${a.services??0} service(s)${y.length?` data: ${y.join(", ")}`:""} ${a.root??""}`)}for(const a of p){const y=!N(a.root);r(`${a.name} (${a.key}, instance of ${a.baseKey}) ${y?"FOLDER GONE \u2014 `lensmcp instance prune`":"stopped"} data: ${Object.keys(a.resources).join(", ")||"none"} ${a.root}`)}return{exitCode:0}}w(ke,"Oe"),m(ke,"list");function V(n){const t=o.daemonRequest("GET","/list");if(t===null){e("No gateway daemon is running.");return}const i=resolveInstance(G(t),n,Q(K));if(typeof i=="string"){e(i);return}return i}w(V,"re"),m(V,"target");function ge(n){const t=V(n);if(!t)return{exitCode:1};const i=o.daemonRequest("GET","/status"),d=i?.status===200&&i.json&&typeof i.json=="object"?(i.json.services??[]).filter(s=>s.wsKey===t.key):[];if(F)return r(JSON.stringify({instance:t,services:d},null,2)),{exitCode:0};r(`${t.instance} (${t.key}, instance of ${t.baseKey}) \u2014 ${t.apex??"?"} ${t.root??""}`),d.length===0&&r(" no pod services");for(const s of d)r(` ${s.project.padEnd(24)} ${s.state.padEnd(9)} ${s.host?`https://${s.host}`:""}`);return{exitCode:0}}w(ge,"Ee"),m(ge,"status");async function we(n){if(W.length===0)return e("Nothing to run: `lensmcp instance exec [<name>] -- <command> [args\u2026]`."),{exitCode:2};const t=V(n);if(!t)return{exitCode:1};const i=Z(t.key);if(!i)return e(`The gateway did not give the variables of '${t.key}'.`),{exitCode:1};const[d,...s]=W;return new Promise(p=>{const a=ze(d,s,{cwd:t.root??K,stdio:"inherit",env:{...process.env,...o.env??{},...i.env}});a.on("error",y=>{e(`could not run ${d}: ${y.message}`),p({exitCode:127})}),a.on("exit",(y,j)=>p({exitCode:y??(j?128:1)}))})}w(we,"Ne"),m(we,"exec");function $e(n){const t=V(n);if(!t)return{exitCode:1};const i=o.daemonRequest("POST","/unregister",{wsKey:t.key,...t.root?{root:t.root}:{}});return!i||i.status!==200?(e(`could not stop '${t.key}': ${Oe(i)??(i?JSON.stringify(i.json):"no response from the control socket")}`),{exitCode:1}):(t.root&&te(R(t.root,".lensmcp","registered.json"),{force:!0}),r(`stopped '${t.key}': its hosts are gone and its services are stopping. \`lensmcp instance start\` in ${t.root??"it"} brings it back.`),{exitCode:0})}w($e,"Re"),m($e,"stop");function ae(n,t,i){const d=i.find(p=>p.key===n);if(!d)return!1;const s=o.daemonRequest("POST","/unregister",{wsKey:n,...d.root??t?{root:d.root??t}:{}});return!!s&&s.status===200}w(ae,"de"),m(ae,"unregisterIfServed");async function ie(n,t,i=r,d){const s=await se(q,p=>Qe(n,p,pe(t),_));s.dropped.length&&i(` dropped : ${s.dropped.join(", ")}`);for(const p of s.failed)e(` could not drop ${p.name}: ${p.error} \u2014 still on record; run this again once it can be reached`);return d&&Object.assign(d,{dropped:s.dropped,...s.failed.length?{dropFailed:s.failed}:{}}),s.failed.length===0}w(ie,"le"),m(ie,"dropData");async function be(n){const t=ne(q),i=G(o.daemonRequest("GET","/list")),d=[...i.filter(f=>typeof f.instance=="string"),...Object.values(t.instances).filter(f=>!i.some(b=>b.key===f.key)).map(f=>({key:f.key,root:f.root,instance:f.name,baseKey:f.baseKey}))],s=(n?void 0:d.find(f=>f.root!==void 0&&le(f.root,K)))??resolveInstance(d,n,Q(K)),p={},a=m(f=>(F&&r(JSON.stringify({...p,exitCode:f},null,2)),{exitCode:f}),"finish");if(typeof s=="string")return e(s.replace("is registered with the gateway","is served or on record")),a(1);const y=B(h,"--base");if(y&&s.baseKey!==y)return e(`'${s.key}' is an instance of '${s.baseKey}', not of '${y}'.`),a(1);const j=s.key,k=t.instances[j],u=s.root??k?.root,x=F?e:r;Object.assign(p,{key:j,name:s.instance,...u?{root:u}:{}});const g=h.includes("--worktree"),E=h.includes("--force"),$=k?.worktree?.path??(u&&N(u)?worktreeInfo(u,o.git)?.root:void 0);if(g){const f=$&&N($)?worktreeInfo($,o.git):void 0;if($&&N($)&&!f?.linked)return e(`${$} is not a linked git worktree \u2014 not removing it (the lens removes only worktrees).`),a(1);if($&&N($)&&!E){const b=Pe($,M);if(b===void 0||b.length>0){p.uncommitted=b??["(git could not read its status)"],e(`${$} has uncommitted work \u2014 commit it (or stash it) first; --force throws it away:`);for(const C of(b??["(git could not read its status)"]).slice(0,20))e(` ${C}`);return(b?.length??0)>20&&e(` \u2026 and ${(b?.length??0)-20} more`),a(1)}}}x(`removing instance '${s.instance}' (${j})${u?` \u2014 ${u}`:""}`),ae(j,u,i)&&(x(" stopped : its routes are gone, its services are stopping"),p.stopped=!0);let T=!0;if(h.includes("--keep-data")?(k&&Object.keys(k.resources).length&&x(` kept : ${Object.keys(k.resources).join(", ")} (on record \u2014 \`start\` reuses it, \`rm\` drops it)`),p.keptData=Object.keys(k?.resources??{})):T=await ie(j,[u,k?.mainRoot,K],x,p),u&&N(u)){const f=o.stopMcpServer?.(u,j);f&&x(` mcp : ${f}`),clearInstanceState(u,j)}if(te(Y(j,_),{force:!0}),g&&$&&N($)){const f=k?.mainRoot??worktreeInfo($,o.git)?.mainRoot??K,b=ct(f,$,E,M);b.ok?(x(` removed : the worktree ${$}`),p.worktreeRemoved=$,k?.worktree&&await se(q,I=>{delete I.instances[j]?.worktree})):(e(` could not remove the worktree ${$}: ${b.err}`),p.worktreeError=b.err,T=!1);const C=k?.worktree?.branch;if(b.ok&&C&&h.includes("--delete-branch"))if(!k?.worktree?.createdBranch)x(` kept : branch ${C} (it existed before the lens checked it out)`),p.branchKept={branch:C,why:"not made by the lens"};else{const I=ot(f,C,E,M);I.ok?(x(` deleted : branch ${C}`),p.branchDeleted=C):(x(` kept : branch ${C} \u2014 ${I.err.split(`
27
+ `)[0]}`),p.branchKept={branch:C,why:I.err.split(`
28
+ `)[0]})}else b.ok&&C&&(p.branchKept={branch:C,why:"not asked to delete it"})}else $&&N($)&&(p.worktreeKept=$);return a(T?0:1)}w(be,"Pe"),m(be,"rm");async function ve(){const n=ne(q),t=G(o.daemonRequest("GET","/list")),i=new Map;for(const s of Object.values(n.instances))N(s.root)||i.set(s.key,s.root);for(const s of t)s.instance&&s.root&&!N(s.root)&&i.set(s.key,s.root);if(i.size===0)return r("Nothing to prune: every instance on record still has its folder."),{exitCode:0};let d=!0;for(const[s,p]of i)r(`${h.includes("--dry-run")?"would remove":"removing"} '${s}' \u2014 ${p} is gone${n.instances[s]?`; data: ${Object.keys(n.instances[s].resources).join(", ")||"none"}`:""}`),!h.includes("--dry-run")&&(ae(s,p,t)&&r(" stopped : its routes are gone"),n.instances[s]&&(d=await ie(s,[n.instances[s].mainRoot,K])&&d));return{exitCode:d?0:1}}w(ve,"Ke"),m(ve,"prune");function Z(n){const t=o.daemonRequest("GET",`/instance-env?wsKey=${encodeURIComponent(n)}`);if(!t||t.status!==200||!t.json||typeof t.json!="object")return;const i=t.json.env;return i&&typeof i=="object"?{env:i}:void 0}w(Z,"oe"),m(Z,"instanceEnvOf")}w(runInstance,"runInstance"),m(runInstance,"runInstance");function ue(c,l,o=!1){return qe(c,{cwd:l.cwd,env:l.env,shell:!0,stdio:o?["inherit",2,2]:"inherit"}).status}w(ue,"be"),m(ue,"runShell");export function clearInstanceState(c,l){te(R(c,".lensmcp","registered.json"),{force:!0}),te(Ze(c),{force:!0});const o=R(c,".lensmcp","config.json");let r;try{r=JSON.parse(Fe(o,"utf8"))}catch{return}if(r.key===l){for(const e of["key","ports","dashboardBasePath","sockNs","instance"])delete r[e];de(o,JSON.stringify(r,null,2)+`
29
+ `)}}w(clearInstanceState,"clearInstanceState"),m(clearInstanceState,"clearInstanceState");function le(c,l){const o=m(r=>{try{return Ge(r)}catch{return X(r)}},"canonical");return o(c)===o(l)}w(le,"ve"),m(le,"sameDir");function Te(c,l){const o=R(c,".lensmcp");N(o)||Ce(o,{recursive:!0}),de(R(o,"config.json"),JSON.stringify(l,null,2)+`
30
+ `)}w(Te,"ut"),m(Te,"writeConfig");function _e(c,l){Ce(R(c,".lensmcp"),{recursive:!0}),de(R(c,".lensmcp","registered.json"),JSON.stringify({wsKey:l}))}w(_e,"pt"),m(_e,"writeMarker");
@@ -1,2 +1,2 @@
1
- "use strict";var d=Object.defineProperty;var r=(e,t)=>d(e,"name",{value:t,configurable:!0});var h=Object.defineProperty,i=r((e,t)=>h(e,"name",{value:t,configurable:!0}),"e"),w=Object.defineProperty,s=i((e,t)=>w(e,"name",{value:t,configurable:!0}),"n");import{chmodSync as g,closeSync as S,existsSync as v,mkdirSync as m,openSync as x,readFileSync as R,renameSync as E,rmSync as p,statSync as P,writeFileSync as f}from"node:fs";import{homedir as b}from"node:os";import{dirname as l,join as $}from"node:path";export function registryPath(e=process.env){return $(e.LENSMCP_HOME||b(),".lensmcp","instances.json")}r(registryPath,"registryPath"),i(registryPath,"registryPath"),s(registryPath,"registryPath");export function readRegistry(e){try{const t=JSON.parse(R(e,"utf8"));if(t&&typeof t.instances=="object"&&t.instances)return{schemaVersion:1,instances:t.instances}}catch{}return{schemaVersion:1,instances:{}}}r(readRegistry,"readRegistry"),i(readRegistry,"readRegistry"),s(readRegistry,"readRegistry");function y(e,t){m(l(e),{recursive:!0,mode:448});const o=`${e}.${process.pid}.tmp`;f(o,JSON.stringify(t,null,2)+`
2
- `,{mode:384}),g(o,384),E(o,e)}r(y,"f"),i(y,"_"),s(y,"writeRegistry");const j=12e4,O=s(e=>new Promise(t=>setTimeout(t,e)),"sleep");export async function withRegistry(e,t,o=6e4){const c=`${e}.lock`;m(l(e),{recursive:!0,mode:448});const u=Date.now()+o;let a;for(;a===void 0;)try{a=x(c,"wx",384),f(a,String(process.pid))}catch(n){if(n.code!=="EEXIST")throw n;try{Date.now()-P(c).mtimeMs>j&&p(c,{force:!0})}catch{}if(Date.now()>u)throw new Error(`${c} is held by another lensmcp process \u2014 try again, or remove it if no lensmcp is running`,{cause:n});await O(100)}try{const n=readRegistry(e);try{return await t(n)}finally{y(e,n)}}finally{S(a),p(c,{force:!0})}}r(withRegistry,"withRegistry"),i(withRegistry,"withRegistry"),s(withRegistry,"withRegistry");export function redactUrl(e){try{const t=new URL(e);return t.password&&(t.password="***"),t.toString()}catch{return e.replace(/\/\/([^:/@]+):[^@]*@/,"//$1:***@")}}r(redactUrl,"redactUrl"),i(redactUrl,"redactUrl"),s(redactUrl,"redactUrl");export const rootExists=s(e=>v(e),"rootExists");
1
+ "use strict";var l=Object.defineProperty;var e=(r,t)=>l(r,"name",{value:t,configurable:!0});var d=Object.defineProperty,s=e((r,t)=>d(r,"name",{value:t,configurable:!0}),"n");import{chmodSync as w,closeSync as h,existsSync as S,mkdirSync as a,openSync as g,readFileSync as x,renameSync as v,rmSync as y,statSync as E,writeFileSync as m}from"node:fs";import{homedir as R}from"node:os";import{dirname as p,join as $}from"node:path";export function registryPath(r=process.env){return $(r.LENSMCP_HOME||R(),".lensmcp","instances.json")}e(registryPath,"registryPath"),s(registryPath,"registryPath");export function readRegistry(r){try{const t=JSON.parse(x(r,"utf8"));if(t&&typeof t.instances=="object"&&t.instances)return{schemaVersion:1,instances:t.instances}}catch{}return{schemaVersion:1,instances:{}}}e(readRegistry,"readRegistry"),s(readRegistry,"readRegistry");function f(r,t){a(p(r),{recursive:!0,mode:448});const o=`${r}.${process.pid}.tmp`;m(o,JSON.stringify(t,null,2)+`
2
+ `,{mode:384}),w(o,384),v(o,r)}e(f,"_"),s(f,"writeRegistry");const P=12e4,b=s(r=>new Promise(t=>setTimeout(t,r)),"sleep");export async function withRegistry(r,t,o=6e4){const i=`${r}.lock`;a(p(r),{recursive:!0,mode:448});const u=Date.now()+o;let c;for(;c===void 0;)try{c=g(i,"wx",384),m(c,String(process.pid))}catch(n){if(n.code!=="EEXIST")throw n;try{Date.now()-E(i).mtimeMs>P&&y(i,{force:!0})}catch{}if(Date.now()>u)throw new Error(`${i} is held by another lensmcp process \u2014 try again, or remove it if no lensmcp is running`,{cause:n});await b(100)}try{const n=readRegistry(r);try{return await t(n)}finally{f(r,n)}}finally{h(c),y(i,{force:!0})}}e(withRegistry,"withRegistry"),s(withRegistry,"withRegistry");export function redactUrl(r){try{const t=new URL(r);return t.password&&(t.password="***"),t.toString()}catch{return r.replace(/\/\/([^:/@]+):[^@]*@/,"//$1:***@")}}e(redactUrl,"redactUrl"),s(redactUrl,"redactUrl");export const rootExists=s(r=>S(r),"rootExists");
@@ -1,6 +1,6 @@
1
- "use strict";var L=Object.defineProperty;var f=(e,t)=>L(e,"name",{value:t,configurable:!0});var P=Object.defineProperty,h=f((e,t)=>P(e,"name",{value:t,configurable:!0}),"f"),T=Object.defineProperty,d=h((e,t)=>T(e,"name",{value:t,configurable:!0}),"u");import{spawnSync as A}from"node:child_process";import{chmodSync as j,copyFileSync as N,existsSync as g,lstatSync as U,mkdirSync as O,readFileSync as $,rmSync as z,writeFileSync as F}from"node:fs";import{createRequire as Z}from"node:module";import{dirname as _,isAbsolute as K,join as w,normalize as q}from"node:path";import{connectResp as M}from"./resp-client.js";const k=d(e=>!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.values(e).every(t=>typeof t=="string"),"isStringMap"),B=d(e=>typeof e=="string"&&e.length>0&&!K(e)&&!q(e).split(/[\\/]/).includes(".."),"isInsidePath");export function readInstancesDecl(e){let t;try{t=JSON.parse($(w(e,"nx.json"),"utf8"))}catch{return{errors:[]}}const r=t?.lensmcp?.instances;return r===void 0?{errors:[]}:validateInstancesDecl(r,storeUrls(t.lensmcp?.stores))}f(readInstancesDecl,"readInstancesDecl"),h(readInstancesDecl,"readInstancesDecl"),d(readInstancesDecl,"readInstancesDecl");export function storeUrls(e){const t={};if(!e||typeof e!="object"||Array.isArray(e))return t;for(const[r,n]of Object.entries(e)){const o=n??{};(o.kind==="postgres"||o.kind==="redis")&&typeof o.url=="string"&&o.url.trim()&&(t[r]={kind:o.kind,url:o.url.trim()})}return t}f(storeUrls,"storeUrls"),h(storeUrls,"storeUrls"),d(storeUrls,"storeUrls");export function validateInstancesDecl(e,t={}){const r=[];if(!e||typeof e!="object"||Array.isArray(e))return{errors:["`lensmcp.instances` must be an object"]};const n=e,o={},s=n.resources??{};if(!s||typeof s!="object"||Array.isArray(s))r.push("`resources` must be an object");else for(const[v,l]of Object.entries(s)){const p=`resources.${v}`;if(!/^[A-Za-z0-9_-]+$/.test(v)){r.push(`${p}: a resource name is letters, digits, '-' and '_'`);continue}if(!l||typeof l!="object"){r.push(`${p}: must be an object`);continue}let c=l;if(c.store!==void 0){const y=typeof c.store=="string"?t[c.store]:void 0;if(!y){r.push(`${p}.store: no store "${String(c.store)}" in lensmcp.stores${Object.keys(t).length?` (there are ${Object.keys(t).join(", ")})`:""}`);continue}if(c.kind!==void 0&&c.kind!==y.kind){r.push(`${p}.kind: "${String(c.kind)}", but store "${String(c.store)}" is ${y.kind}`);continue}c={...c,kind:y.kind,...y.kind==="postgres"?{admin:c.admin??y.url}:{server:c.server??y.url}}}c.env!==void 0&&!k(c.env)&&r.push(`${p}.env: must map names to strings`);const u=k(c.env)?c.env:void 0,m=d(y=>typeof c[y]=="string"&&c[y].length>0?c[y]:void 0,"str");if(c.kind==="postgres"){const y=m("admin");if(!y){r.push(`${p}.admin: the admin connection URL is required (e.g. "\${PG_URL}"), or a \`store\``);continue}o[v]={kind:"postgres",admin:y,...m("database")?{database:m("database")}:{},...m("template")?{template:m("template")}:{},...u?{env:u}:{}}}else if(c.kind==="redis"){const y=m("server");if(!y){r.push(`${p}.server: the server URL is required (e.g. "\${REDIS_URL}"), or a \`store\``);continue}c.isolate!==void 0&&c.isolate!=="db-index"&&r.push(`${p}.isolate: only "db-index" is supported`),o[v]={kind:"redis",server:y,...u?{env:u}:{}}}else if(c.kind==="command"){if(!m("create")&&!m("url")){r.push(`${p}: a command resource needs \`create\` or \`url\``);continue}o[v]={kind:"command",...m("create")?{create:m("create")}:{},...m("drop")?{drop:m("drop")}:{},...m("url")?{url:m("url")}:{},...u?{env:u}:{}}}else r.push(`${p}.kind: one of "postgres", "redis", "command"`)}n.env!==void 0&&!k(n.env)&&r.push("`env` must map names to strings"),n.prepare!==void 0&&typeof n.prepare!="string"&&r.push("`prepare` must be a command string"),n.worktrees!==void 0&&(typeof n.worktrees!="string"||!n.worktrees.trim())&&r.push("`worktrees` must be a folder path");const a=n.bootstrap??{},i=d(v=>{const l=a[v];return l===void 0?[]:!Array.isArray(l)||!l.every(B)?(r.push(`bootstrap.${v}: a list of paths inside the checkout`),[]):l},"list"),b={resources:o,env:k(n.env)?n.env:{},...typeof n.prepare=="string"&&n.prepare.trim()?{prepare:n.prepare}:{},bootstrap:{copy:i("copy"),clone:i("clone")},...typeof n.worktrees=="string"&&n.worktrees.trim()?{worktrees:n.worktrees.trim()}:{}};return r.length?{errors:r}:{decl:b,errors:r}}f(validateInstancesDecl,"validateInstancesDecl"),h(validateInstancesDecl,"validateInstancesDecl"),d(validateInstancesDecl,"validateInstancesDecl");export function parseDotenv(e,t={}){const r={},n=d(o=>o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(s,a)=>r[a]??t[a]??""),"expand");for(const o of e.split(/\r?\n/)){const s=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/.exec(o);if(!s)continue;const a=s[1],i=s[2];i.startsWith("'")&&i.indexOf("'",1)>0?r[a]=i.slice(1,i.indexOf("'",1)):i.startsWith('"')&&i.indexOf('"',1)>0?r[a]=n(i.slice(1,i.indexOf('"',1)).replace(/\\n/g,`
2
- `)):r[a]=n(i.replace(/\s+#.*$/,""))}return r}f(parseDotenv,"parseDotenv"),h(parseDotenv,"parseDotenv"),d(parseDotenv,"parseDotenv");function x(e,t){try{return parseDotenv($(e,"utf8"),t)}catch{return{}}}f(x,"j"),h(x,"Z"),d(x,"readDotenv");export function expansionScope(e,t){let r={};for(const o of[e.mainRoot,e.root])if(o)for(const s of[".env",".env.local"])r={...r,...x(w(o,s),{...r})};const n=Object.fromEntries(Object.entries(t).filter(o=>typeof o[1]=="string"));return{...r,...n,name:e.name,key:e.key,baseKey:e.baseKey,root:e.root,...e.mainRoot?{mainRoot:e.mainRoot}:{}}}f(expansionScope,"expansionScope"),h(expansionScope,"expansionScope"),d(expansionScope,"expansionScope");export function expandStrict(e,t,r){const n=[],o=e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(s,a)=>{const i=t[a];return(i===void 0||i==="")&&n.push(a),i??""});if(n.length)throw new Error(`${r}: ${n.map(s=>`\${${s}}`).join(", ")} ${n.length===1?"is":"are"} not set \u2014 in the environment, or the main checkout's .env / .env.local`);return o}f(expandStrict,"expandStrict"),h(expandStrict,"expandStrict"),d(expandStrict,"expandStrict");export function expandKnown(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(r,n)=>t[n]??r)}f(expandKnown,"expandKnown"),h(expandKnown,"expandKnown"),d(expandKnown,"expandKnown");export function defaultRuntime(e){return{async pg(t){let r;for(const o of e)try{r=Z(w(o,"package.json"))("pg");break}catch{}if(!r)throw new Error(`the postgres provider uses the project's own \`pg\` client, and none is installed in ${e.join(" or ")}`);const n=new r.Client({connectionString:t});return await n.connect(),n},resp:d(t=>M(t),"resp"),run(t,r){const n=A(t,{cwd:r.cwd,env:r.env,shell:!0,encoding:"utf8",timeout:6e5});return{status:n.status,stdout:n.stdout??"",stderr:n.stderr??(n.error?String(n.error):"")}}}}f(defaultRuntime,"defaultRuntime"),h(defaultRuntime,"defaultRuntime"),d(defaultRuntime,"defaultRuntime");const S=d(e=>`"${e}"`,"ident"),D=/^[A-Za-z0-9_][A-Za-z0-9_-]{0,62}$/,W=new Set(["postgres","template0","template1"]);export function withDatabase(e,t){const r=new URL(e);return r.pathname=`/${t}`,r.toString()}f(withDatabase,"withDatabase"),h(withDatabase,"withDatabase"),d(withDatabase,"withDatabase");const H=d(e=>{const t=new URL(e);return decodeURIComponent(t.pathname.replace(/^\//,""))||decodeURIComponent(t.username)},"databaseOf");export async function provisionPostgres(e,t,r,n,o){const s=expandStrict(e.admin,t,`${o}.admin`),a=expandStrict(e.database??"${name}_${baseKey}",t,`${o}.database`).replace(/-/g,"_");if(!D.test(a))throw new Error(`${o}: '${a}' is not a database name the lens creates (letters, digits, '_' \u2014 at most 63)`);if(W.has(a)||a===H(s))throw new Error(`${o}: '${a}' is the admin connection's own database (or a system one) \u2014 an instance needs a database of its own`);const i=e.template?expandStrict(e.template,t,`${o}.template`):void 0;if(i&&!D.test(i))throw new Error(`${o}: '${i}' is not a template name the lens uses`);const b=r?.kind==="postgres"&&r.database===a,v=await n.pg(s);let l=!1;try{const c=(await v.query("SELECT 1 FROM pg_database WHERE datname = $1",[a])).rows.length>0;if(c&&!b)throw new Error(`${o}: database '${a}' already exists and the lens did not create it for this instance \u2014 it is left alone. Drop it, or name the instance differently.`);if(!c){try{await v.query(`CREATE DATABASE ${S(a)}${i?` TEMPLATE ${S(i)}`:""}`)}catch(u){const m=u.code;throw i&&m==="55006"?new Error(`${o}: Postgres copies a template only while nobody is connected to it, and '${i}' has connections. Point \`template\` at a database kept for copying (filled once by \`prepare\`), not one a running service uses.`,{cause:u}):u}l=!0}}finally{await v.end().catch(()=>{})}const p={kind:"postgres",admin:s,database:a};return{url:withDatabase(s,a),record:p,created:l}}f(provisionPostgres,"provisionPostgres"),h(provisionPostgres,"provisionPostgres"),d(provisionPostgres,"provisionPostgres");export async function dropPostgres(e,t){const r=await t.pg(e.admin);try{try{await r.query(`DROP DATABASE IF EXISTS ${S(e.database)} WITH (FORCE)`)}catch(n){if(n.code!=="42601")throw n;await r.query("SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()",[e.database]),await r.query(`DROP DATABASE IF EXISTS ${S(e.database)}`)}}finally{await r.end().catch(()=>{})}}f(dropPostgres,"dropPostgres"),h(dropPostgres,"dropPostgres"),d(dropPostgres,"dropPostgres");export function redisServerId(e){const t=new URL(e);return`${t.hostname||"127.0.0.1"}:${t.port||"6379"}`}f(redisServerId,"redisServerId"),h(redisServerId,"redisServerId"),d(redisServerId,"redisServerId");export function withDbIndex(e,t){const r=new URL(e);return r.pathname=`/${t}`,r.toString()}f(withDbIndex,"withDbIndex"),h(withDbIndex,"withDbIndex"),d(withDbIndex,"withDbIndex");export async function provisionRedis(e,t,r,n,o,s,a){const i=expandStrict(e.server,t,`${a}.server`),b=redisServerId(i);if(r?.kind==="redis"&&redisServerId(r.server)===b)return{url:withDbIndex(i,r.db),record:{...r,server:i},created:!1};const v=Number(new URL(i).pathname.replace(/^\//,"")||0),l=new Set;for(const c of Object.values(o.instances))if(c.key!==s)for(const u of Object.values(c.resources))u.kind==="redis"&&redisServerId(u.server)===b&&l.add(u.db);const p=await n.resp(i);try{let c=16;try{const u=await p.command(["CONFIG","GET","databases"]),m=Array.isArray(u)?Number(u[1]):NaN;Number.isInteger(m)&&m>0&&(c=m)}catch{}for(let u=0;u<c;u++){if(u===v||l.has(u)||(await p.command(["SELECT",String(u)]),Number(await p.command(["DBSIZE"]))!==0))continue;const m={kind:"redis",server:i,db:u};return{url:withDbIndex(i,u),record:m,created:!0}}throw new Error(`${a}: no empty logical db is left on ${b} (${c} in all, ${l.size} given to instances, ${v} is the main checkout's) \u2014 raise \`databases\` in the server's config, or remove an instance`)}finally{p.close()}}f(provisionRedis,"provisionRedis"),h(provisionRedis,"provisionRedis"),d(provisionRedis,"provisionRedis");export async function flushRedis(e,t){const r=await t.resp(e.server);try{await r.command(["SELECT",String(e.db)]),await r.command(["FLUSHDB"])}finally{r.close()}}f(flushRedis,"flushRedis"),h(flushRedis,"flushRedis"),d(flushRedis,"flushRedis");export function provisionCommand(e,t,r,n,o,s,a){const i={LENSMCP_INSTANCE:o.name,LENSMCP_INSTANCE_KEY:o.key,LENSMCP_BASE_KEY:o.baseKey},b=e.url?expandStrict(e.url,t,`${a}.url`):"",v=e.drop?expandStrict(e.drop,t,`${a}.drop`):void 0,l={kind:"command",...v?{drop:v}:{},cwd:o.root,env:i};if(r?.kind==="command"||!e.create)return{url:b,record:l,created:!1};const p=expandStrict(e.create,t,`${a}.create`),c=n.run(p,{cwd:o.root,env:{...s,...i}});if(c.status!==0)throw new Error(`${a}: \`${e.create}\` exited ${c.status??"on a signal"}${c.stderr.trim()?` \u2014 ${c.stderr.trim().split(`
3
- `).slice(-3).join(" | ")}`:""}`);return{url:b,record:l,created:!0}}f(provisionCommand,"provisionCommand"),h(provisionCommand,"provisionCommand"),d(provisionCommand,"provisionCommand");export async function dropResource(e,t,r){if(e.kind==="postgres")return dropPostgres(e,t);if(e.kind==="redis")return flushRedis(e,t);if(!e.drop)return;const n=t.run(e.drop,{cwd:g(e.cwd)?e.cwd:process.cwd(),env:{...r,...e.env}});if(n.status!==0)throw new Error(`\`${e.drop}\` exited ${n.status??"on a signal"}`)}f(dropResource,"dropResource"),h(dropResource,"dropResource"),d(dropResource,"dropResource");export async function provisionAll(e,t,r,n,o){const s=r.instances[t.key];if(s&&s.root!==t.root&&g(s.root))throw new Error(`instance '${t.key}' already belongs to ${s.root} \u2014 give this checkout another name`);const a=s&&s.root===t.root?s:{key:t.key,name:t.name,baseKey:t.baseKey,root:t.root,...t.mainRoot?{mainRoot:t.mainRoot}:{},createdAt:new Date().toISOString(),resources:s?.resources??{}};r.instances[t.key]=a;const i=expansionScope(t,o),b={resolved:{},deferred:{},created:[],reused:[]};try{for(const[l,p]of Object.entries(e.resources)){const c=`lensmcp.instances.resources.${l}`,u=a.resources[l],m=p.kind==="postgres"?await provisionPostgres(p,i,u,n,c):p.kind==="redis"?await provisionRedis(p,i,u,n,r,t.key,c):provisionCommand(p,i,u,n,t,o,c);a.resources[l]=m.record,(m.created?b.created:b.reused).push(l);for(const[y,C]of Object.entries(p.env??{}))b.resolved[y]=expandStrict(C,{...i,url:m.url},`${c}.env.${y}`)}}catch(l){throw!s&&Object.keys(a.resources).length===0&&delete r.instances[t.key],l}const v={...i,...b.resolved};for(const[l,p]of Object.entries(e.env))b.deferred[l]=expandKnown(p,v);return b}f(provisionAll,"provisionAll"),h(provisionAll,"provisionAll"),d(provisionAll,"provisionAll");export async function dropAll(e,t,r,n){const o=t.instances[e],s={dropped:[],failed:[]};if(!o)return s;for(const[a,i]of Object.entries(o.resources))try{await dropResource(i,r,n),delete o.resources[a],s.dropped.push(a)}catch(b){s.failed.push({name:a,error:b.message})}return s.failed.length===0&&delete t.instances[e],s}f(dropAll,"dropAll"),h(dropAll,"dropAll"),d(dropAll,"dropAll");export function resourceEnvFile(e){return w(e,".lensmcp","instance.resources.env")}f(resourceEnvFile,"resourceEnvFile"),h(resourceEnvFile,"resourceEnvFile"),d(resourceEnvFile,"resourceEnvFile");function E(e,t,r){return!r&&!t.includes("'")&&!t.includes(`
4
- `)?`${e}='${t}'`:`${e}="${t.replace(/\n/g,"\\n")}"`}f(E,"S"),h(E,"R"),d(E,"envLine");export function writeResourceEnv(e,t){const r=["# Written by `lensmcp instance start` from nx.json \u2192 lensmcp.instances on every start. Put your own variables","# in instance.env beside it (they win over these).",...Object.entries(t.resolved).map(([o,s])=>E(o,s,!1)),...Object.entries(t.deferred).map(([o,s])=>E(o,s,!0))],n=resourceEnvFile(e);O(_(n),{recursive:!0}),F(n,r.join(`
1
+ "use strict";var C=Object.defineProperty;var f=(e,t)=>C(e,"name",{value:t,configurable:!0});var L=Object.defineProperty,d=f((e,t)=>L(e,"name",{value:t,configurable:!0}),"u");import{spawnSync as E}from"node:child_process";import{chmodSync as x,copyFileSync as T,existsSync as w,lstatSync as N,mkdirSync as A,readFileSync as b,rmSync as P,writeFileSync as U}from"node:fs";import{createRequire as z}from"node:module";import{dirname as R,isAbsolute as F,join as $,normalize as Z}from"node:path";import{connectResp as K}from"./resp-client.js";const g=d(e=>!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.values(e).every(t=>typeof t=="string"),"isStringMap"),q=d(e=>typeof e=="string"&&e.length>0&&!F(e)&&!Z(e).split(/[\\/]/).includes(".."),"isInsidePath");export function readInstancesDecl(e){let t;try{t=JSON.parse(b($(e,"nx.json"),"utf8"))}catch{return{errors:[]}}const r=t?.lensmcp?.instances;return r===void 0?{errors:[]}:validateInstancesDecl(r,storeUrls(t.lensmcp?.stores))}f(readInstancesDecl,"readInstancesDecl"),d(readInstancesDecl,"readInstancesDecl");export function storeUrls(e){const t={};if(!e||typeof e!="object"||Array.isArray(e))return t;for(const[r,n]of Object.entries(e)){const o=n??{};(o.kind==="postgres"||o.kind==="redis")&&typeof o.url=="string"&&o.url.trim()&&(t[r]={kind:o.kind,url:o.url.trim()})}return t}f(storeUrls,"storeUrls"),d(storeUrls,"storeUrls");export function validateInstancesDecl(e,t={}){const r=[];if(!e||typeof e!="object"||Array.isArray(e))return{errors:["`lensmcp.instances` must be an object"]};const n=e,o={},s=n.resources??{};if(!s||typeof s!="object"||Array.isArray(s))r.push("`resources` must be an object");else for(const[h,l]of Object.entries(s)){const p=`resources.${h}`;if(!/^[A-Za-z0-9_-]+$/.test(h)){r.push(`${p}: a resource name is letters, digits, '-' and '_'`);continue}if(!l||typeof l!="object"){r.push(`${p}: must be an object`);continue}let c=l;if(c.store!==void 0){const y=typeof c.store=="string"?t[c.store]:void 0;if(!y){r.push(`${p}.store: no store "${String(c.store)}" in lensmcp.stores${Object.keys(t).length?` (there are ${Object.keys(t).join(", ")})`:""}`);continue}if(c.kind!==void 0&&c.kind!==y.kind){r.push(`${p}.kind: "${String(c.kind)}", but store "${String(c.store)}" is ${y.kind}`);continue}c={...c,kind:y.kind,...y.kind==="postgres"?{admin:c.admin??y.url}:{server:c.server??y.url}}}c.env!==void 0&&!g(c.env)&&r.push(`${p}.env: must map names to strings`);const u=g(c.env)?c.env:void 0,m=d(y=>typeof c[y]=="string"&&c[y].length>0?c[y]:void 0,"str");if(c.kind==="postgres"){const y=m("admin");if(!y){r.push(`${p}.admin: the admin connection URL is required (e.g. "\${PG_URL}"), or a \`store\``);continue}o[h]={kind:"postgres",admin:y,...m("database")?{database:m("database")}:{},...m("template")?{template:m("template")}:{},...u?{env:u}:{}}}else if(c.kind==="redis"){const y=m("server");if(!y){r.push(`${p}.server: the server URL is required (e.g. "\${REDIS_URL}"), or a \`store\``);continue}c.isolate!==void 0&&c.isolate!=="db-index"&&r.push(`${p}.isolate: only "db-index" is supported`),o[h]={kind:"redis",server:y,...u?{env:u}:{}}}else if(c.kind==="command"){if(!m("create")&&!m("url")){r.push(`${p}: a command resource needs \`create\` or \`url\``);continue}o[h]={kind:"command",...m("create")?{create:m("create")}:{},...m("drop")?{drop:m("drop")}:{},...m("url")?{url:m("url")}:{},...u?{env:u}:{}}}else r.push(`${p}.kind: one of "postgres", "redis", "command"`)}n.env!==void 0&&!g(n.env)&&r.push("`env` must map names to strings"),n.prepare!==void 0&&typeof n.prepare!="string"&&r.push("`prepare` must be a command string"),n.worktrees!==void 0&&(typeof n.worktrees!="string"||!n.worktrees.trim())&&r.push("`worktrees` must be a folder path");const a=n.bootstrap??{},i=d(h=>{const l=a[h];return l===void 0?[]:!Array.isArray(l)||!l.every(q)?(r.push(`bootstrap.${h}: a list of paths inside the checkout`),[]):l},"list"),v={resources:o,env:g(n.env)?n.env:{},...typeof n.prepare=="string"&&n.prepare.trim()?{prepare:n.prepare}:{},bootstrap:{copy:i("copy"),clone:i("clone")},...typeof n.worktrees=="string"&&n.worktrees.trim()?{worktrees:n.worktrees.trim()}:{}};return r.length?{errors:r}:{decl:v,errors:r}}f(validateInstancesDecl,"validateInstancesDecl"),d(validateInstancesDecl,"validateInstancesDecl");export function parseDotenv(e,t={}){const r={},n=d(o=>o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(s,a)=>r[a]??t[a]??""),"expand");for(const o of e.split(/\r?\n/)){const s=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/.exec(o);if(!s)continue;const a=s[1],i=s[2];i.startsWith("'")&&i.indexOf("'",1)>0?r[a]=i.slice(1,i.indexOf("'",1)):i.startsWith('"')&&i.indexOf('"',1)>0?r[a]=n(i.slice(1,i.indexOf('"',1)).replace(/\\n/g,`
2
+ `)):r[a]=n(i.replace(/\s+#.*$/,""))}return r}f(parseDotenv,"parseDotenv"),d(parseDotenv,"parseDotenv");function j(e,t){try{return parseDotenv(b(e,"utf8"),t)}catch{return{}}}f(j,"Z"),d(j,"readDotenv");export function expansionScope(e,t){let r={};for(const o of[e.mainRoot,e.root])if(o)for(const s of[".env",".env.local"])r={...r,...j($(o,s),{...r})};const n=Object.fromEntries(Object.entries(t).filter(o=>typeof o[1]=="string"));return{...r,...n,name:e.name,key:e.key,baseKey:e.baseKey,root:e.root,...e.mainRoot?{mainRoot:e.mainRoot}:{}}}f(expansionScope,"expansionScope"),d(expansionScope,"expansionScope");export function expandStrict(e,t,r){const n=[],o=e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(s,a)=>{const i=t[a];return(i===void 0||i==="")&&n.push(a),i??""});if(n.length)throw new Error(`${r}: ${n.map(s=>`\${${s}}`).join(", ")} ${n.length===1?"is":"are"} not set \u2014 in the environment, or the main checkout's .env / .env.local`);return o}f(expandStrict,"expandStrict"),d(expandStrict,"expandStrict");export function expandKnown(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(r,n)=>t[n]??r)}f(expandKnown,"expandKnown"),d(expandKnown,"expandKnown");export function defaultRuntime(e){return{async pg(t){let r;for(const o of e)try{r=z($(o,"package.json"))("pg");break}catch{}if(!r)throw new Error(`the postgres provider uses the project's own \`pg\` client, and none is installed in ${e.join(" or ")}`);const n=new r.Client({connectionString:t});return await n.connect(),n},resp:d(t=>K(t),"resp"),run(t,r){const n=E(t,{cwd:r.cwd,env:r.env,shell:!0,encoding:"utf8",timeout:6e5});return{status:n.status,stdout:n.stdout??"",stderr:n.stderr??(n.error?String(n.error):"")}}}}f(defaultRuntime,"defaultRuntime"),d(defaultRuntime,"defaultRuntime");const k=d(e=>`"${e}"`,"ident"),_=/^[A-Za-z0-9_][A-Za-z0-9_-]{0,62}$/,M=new Set(["postgres","template0","template1"]);export function withDatabase(e,t){const r=new URL(e);return r.pathname=`/${t}`,r.toString()}f(withDatabase,"withDatabase"),d(withDatabase,"withDatabase");const B=d(e=>{const t=new URL(e);return decodeURIComponent(t.pathname.replace(/^\//,""))||decodeURIComponent(t.username)},"databaseOf");export async function provisionPostgres(e,t,r,n,o){const s=expandStrict(e.admin,t,`${o}.admin`),a=expandStrict(e.database??"${name}_${baseKey}",t,`${o}.database`).replace(/-/g,"_");if(!_.test(a))throw new Error(`${o}: '${a}' is not a database name the lens creates (letters, digits, '_' \u2014 at most 63)`);if(M.has(a)||a===B(s))throw new Error(`${o}: '${a}' is the admin connection's own database (or a system one) \u2014 an instance needs a database of its own`);const i=e.template?expandStrict(e.template,t,`${o}.template`):void 0;if(i&&!_.test(i))throw new Error(`${o}: '${i}' is not a template name the lens uses`);const v=r?.kind==="postgres"&&r.database===a,h=await n.pg(s);let l=!1;try{const c=(await h.query("SELECT 1 FROM pg_database WHERE datname = $1",[a])).rows.length>0;if(c&&!v)throw new Error(`${o}: database '${a}' already exists and the lens did not create it for this instance \u2014 it is left alone. Drop it, or name the instance differently.`);if(!c){try{await h.query(`CREATE DATABASE ${k(a)}${i?` TEMPLATE ${k(i)}`:""}`)}catch(u){const m=u.code;throw i&&m==="55006"?new Error(`${o}: Postgres copies a template only while nobody is connected to it, and '${i}' has connections. Point \`template\` at a database kept for copying (filled once by \`prepare\`), not one a running service uses.`,{cause:u}):u}l=!0}}finally{await h.end().catch(()=>{})}const p={kind:"postgres",admin:s,database:a};return{url:withDatabase(s,a),record:p,created:l}}f(provisionPostgres,"provisionPostgres"),d(provisionPostgres,"provisionPostgres");export async function dropPostgres(e,t){const r=await t.pg(e.admin);try{try{await r.query(`DROP DATABASE IF EXISTS ${k(e.database)} WITH (FORCE)`)}catch(n){if(n.code!=="42601")throw n;await r.query("SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()",[e.database]),await r.query(`DROP DATABASE IF EXISTS ${k(e.database)}`)}}finally{await r.end().catch(()=>{})}}f(dropPostgres,"dropPostgres"),d(dropPostgres,"dropPostgres");export function redisServerId(e){const t=new URL(e);return`${t.hostname||"127.0.0.1"}:${t.port||"6379"}`}f(redisServerId,"redisServerId"),d(redisServerId,"redisServerId");export function withDbIndex(e,t){const r=new URL(e);return r.pathname=`/${t}`,r.toString()}f(withDbIndex,"withDbIndex"),d(withDbIndex,"withDbIndex");export async function provisionRedis(e,t,r,n,o,s,a){const i=expandStrict(e.server,t,`${a}.server`),v=redisServerId(i);if(r?.kind==="redis"&&redisServerId(r.server)===v)return{url:withDbIndex(i,r.db),record:{...r,server:i},created:!1};const h=Number(new URL(i).pathname.replace(/^\//,"")||0),l=new Set;for(const c of Object.values(o.instances))if(c.key!==s)for(const u of Object.values(c.resources))u.kind==="redis"&&redisServerId(u.server)===v&&l.add(u.db);const p=await n.resp(i);try{let c=16;try{const u=await p.command(["CONFIG","GET","databases"]),m=Array.isArray(u)?Number(u[1]):NaN;Number.isInteger(m)&&m>0&&(c=m)}catch{}for(let u=0;u<c;u++){if(u===h||l.has(u)||(await p.command(["SELECT",String(u)]),Number(await p.command(["DBSIZE"]))!==0))continue;const m={kind:"redis",server:i,db:u};return{url:withDbIndex(i,u),record:m,created:!0}}throw new Error(`${a}: no empty logical db is left on ${v} (${c} in all, ${l.size} given to instances, ${h} is the main checkout's) \u2014 raise \`databases\` in the server's config, or remove an instance`)}finally{p.close()}}f(provisionRedis,"provisionRedis"),d(provisionRedis,"provisionRedis");export async function flushRedis(e,t){const r=await t.resp(e.server);try{await r.command(["SELECT",String(e.db)]),await r.command(["FLUSHDB"])}finally{r.close()}}f(flushRedis,"flushRedis"),d(flushRedis,"flushRedis");export function provisionCommand(e,t,r,n,o,s,a){const i={LENSMCP_INSTANCE:o.name,LENSMCP_INSTANCE_KEY:o.key,LENSMCP_BASE_KEY:o.baseKey},v=e.url?expandStrict(e.url,t,`${a}.url`):"",h=e.drop?expandStrict(e.drop,t,`${a}.drop`):void 0,l={kind:"command",...h?{drop:h}:{},cwd:o.root,env:i};if(r?.kind==="command"||!e.create)return{url:v,record:l,created:!1};const p=expandStrict(e.create,t,`${a}.create`),c=n.run(p,{cwd:o.root,env:{...s,...i}});if(c.status!==0)throw new Error(`${a}: \`${e.create}\` exited ${c.status??"on a signal"}${c.stderr.trim()?` \u2014 ${c.stderr.trim().split(`
3
+ `).slice(-3).join(" | ")}`:""}`);return{url:v,record:l,created:!0}}f(provisionCommand,"provisionCommand"),d(provisionCommand,"provisionCommand");export async function dropResource(e,t,r){if(e.kind==="postgres")return dropPostgres(e,t);if(e.kind==="redis")return flushRedis(e,t);if(!e.drop)return;const n=t.run(e.drop,{cwd:w(e.cwd)?e.cwd:process.cwd(),env:{...r,...e.env}});if(n.status!==0)throw new Error(`\`${e.drop}\` exited ${n.status??"on a signal"}`)}f(dropResource,"dropResource"),d(dropResource,"dropResource");export async function provisionAll(e,t,r,n,o){const s=r.instances[t.key];if(s&&s.root!==t.root&&w(s.root))throw new Error(`instance '${t.key}' already belongs to ${s.root} \u2014 give this checkout another name`);const a=s&&s.root===t.root?s:{key:t.key,name:t.name,baseKey:t.baseKey,root:t.root,...t.mainRoot?{mainRoot:t.mainRoot}:{},createdAt:new Date().toISOString(),resources:s?.resources??{}};r.instances[t.key]=a;const i=expansionScope(t,o),v={resolved:{},deferred:{},created:[],reused:[]};try{for(const[l,p]of Object.entries(e.resources)){const c=`lensmcp.instances.resources.${l}`,u=a.resources[l],m=p.kind==="postgres"?await provisionPostgres(p,i,u,n,c):p.kind==="redis"?await provisionRedis(p,i,u,n,r,t.key,c):provisionCommand(p,i,u,n,t,o,c);a.resources[l]=m.record,(m.created?v.created:v.reused).push(l);for(const[y,D]of Object.entries(p.env??{}))v.resolved[y]=expandStrict(D,{...i,url:m.url},`${c}.env.${y}`)}}catch(l){throw!s&&Object.keys(a.resources).length===0&&delete r.instances[t.key],l}const h={...i,...v.resolved};for(const[l,p]of Object.entries(e.env))v.deferred[l]=expandKnown(p,h);return v}f(provisionAll,"provisionAll"),d(provisionAll,"provisionAll");export async function dropAll(e,t,r,n){const o=t.instances[e],s={dropped:[],failed:[]};if(!o)return s;for(const[a,i]of Object.entries(o.resources))try{await dropResource(i,r,n),delete o.resources[a],s.dropped.push(a)}catch(v){s.failed.push({name:a,error:v.message})}return s.failed.length===0&&delete t.instances[e],s}f(dropAll,"dropAll"),d(dropAll,"dropAll");export function resourceEnvFile(e){return $(e,".lensmcp","instance.resources.env")}f(resourceEnvFile,"resourceEnvFile"),d(resourceEnvFile,"resourceEnvFile");function S(e,t,r){return!r&&!t.includes("'")&&!t.includes(`
4
+ `)?`${e}='${t}'`:`${e}="${t.replace(/\n/g,"\\n")}"`}f(S,"R"),d(S,"envLine");export function writeResourceEnv(e,t){const r=["# Written by `lensmcp instance start` from nx.json \u2192 lensmcp.instances on every start. Put your own variables","# in instance.env beside it (they win over these).",...Object.entries(t.resolved).map(([o,s])=>S(o,s,!1)),...Object.entries(t.deferred).map(([o,s])=>S(o,s,!0))],n=resourceEnvFile(e);A(R(n),{recursive:!0}),U(n,r.join(`
5
5
  `)+`
6
- `,{mode:384}),j(n,384)}f(writeResourceEnv,"writeResourceEnv"),h(writeResourceEnv,"writeResourceEnv"),d(writeResourceEnv,"writeResourceEnv");const I=d(e=>{try{return U(e),!0}catch{return!1}},"present");export function bootstrapCheckout(e,t,r,n=R){const o={copied:[],cloned:[],notes:[]};for(const s of r.copy){const a=w(t,s),i=w(e,s);if(!I(i)){if(!g(a)){o.notes.push(`${s}: not in the main checkout \u2014 nothing to copy`);continue}O(_(i),{recursive:!0}),N(a,i),j(i,384),o.copied.push(s)}}for(const s of r.clone){const a=w(t,s),i=w(e,s);if(!I(i)){if(!g(a)){o.notes.push(`${s}: not in the main checkout \u2014 nothing to clone`);continue}if(!n(a,i)){o.notes.push(`${s}: the copy-on-write clone failed \u2014 install it yourself`);continue}z(w(i,".cache"),{recursive:!0,force:!0}),o.cloned.push(s)}}if(o.cloned.includes("node_modules")){const s=["yarn.lock","package-lock.json","pnpm-lock.yaml"].find(i=>g(w(e,i))),a=s&&g(w(t,s))&&$(w(e,s)).equals($(w(t,s)));s&&!a&&o.notes.push(`${s} differs from the main checkout's \u2014 the cloned node_modules is main's; run the install in this checkout`)}return o}f(bootstrapCheckout,"bootstrapCheckout"),h(bootstrapCheckout,"bootstrapCheckout"),d(bootstrapCheckout,"bootstrapCheckout");function R(e,t){const r=process.platform==="darwin"?["-cR",e,t]:["-R","--reflink=auto",e,t];return A("cp",r,{stdio:"ignore"}).status===0}f(R,"I"),h(R,"K"),d(R,"cloneTree");
6
+ `,{mode:384}),x(n,384)}f(writeResourceEnv,"writeResourceEnv"),d(writeResourceEnv,"writeResourceEnv");const O=d(e=>{try{return N(e),!0}catch{return!1}},"present");export function bootstrapCheckout(e,t,r,n=I){const o={copied:[],cloned:[],notes:[]};for(const s of r.copy){const a=$(t,s),i=$(e,s);if(!O(i)){if(!w(a)){o.notes.push(`${s}: not in the main checkout \u2014 nothing to copy`);continue}A(R(i),{recursive:!0}),T(a,i),x(i,384),o.copied.push(s)}}for(const s of r.clone){const a=$(t,s),i=$(e,s);if(!O(i)){if(!w(a)){o.notes.push(`${s}: not in the main checkout \u2014 nothing to clone`);continue}if(!n(a,i)){o.notes.push(`${s}: the copy-on-write clone failed \u2014 install it yourself`);continue}P($(i,".cache"),{recursive:!0,force:!0}),o.cloned.push(s)}}if(o.cloned.includes("node_modules")){const s=["yarn.lock","package-lock.json","pnpm-lock.yaml"].find(i=>w($(e,i))),a=s&&w($(t,s))&&b($(e,s)).equals(b($(t,s)));s&&!a&&o.notes.push(`${s} differs from the main checkout's \u2014 the cloned node_modules is main's; run the install in this checkout`)}return o}f(bootstrapCheckout,"bootstrapCheckout"),d(bootstrapCheckout,"bootstrapCheckout");function I(e,t){const r=process.platform==="darwin"?["-cR",e,t]:["-R","--reflink=auto",e,t];return E("cp",r,{stdio:"ignore"}).status===0}f(I,"K"),d(I,"cloneTree");
@@ -1,8 +1,8 @@
1
- "use strict";var x=Object.defineProperty;var s=(r,e)=>x(r,"name",{value:e,configurable:!0});var b=Object.defineProperty,c=s((r,e)=>b(r,"name",{value:e,configurable:!0}),"s"),w=Object.defineProperty,i=c((r,e)=>w(r,"name",{value:e,configurable:!0}),"o");import{spawnSync as $}from"node:child_process";import{appendFileSync as E,closeSync as P,existsSync as S,mkdirSync as f,openSync as W,readFileSync as l,renameSync as B,rmSync as h,statSync as C,writeFileSync as g}from"node:fs";import{homedir as k}from"node:os";import{dirname as p,isAbsolute as y,join as m,relative as N,resolve as v,sep as F}from"node:path";export function gitExec(r,e,o=12e4){const t=$("git",e,{cwd:r,encoding:"utf8",timeout:o,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}});return{ok:t.status===0,out:typeof t.stdout=="string"?t.stdout.trim():"",err:(typeof t.stderr=="string"?t.stderr.trim():"")||(t.error?t.error.message:t.status===null?"git was killed":"")}}s(gitExec,"gitExec"),c(gitExec,"gitExec"),i(gitExec,"gitExec");export function branchNameProblem(r,e,o=gitExec){if(!e||e.startsWith("-"))return`'${e}' is not a branch name`;if(!o(r,["check-ref-format","--branch",e]).ok)return`'${e}' is not a valid branch name (git check-ref-format)`}s(branchNameProblem,"branchNameProblem"),c(branchNameProblem,"branchNameProblem"),i(branchNameProblem,"branchNameProblem");export function resolveCommit(r,e,o=gitExec){if(!e||e.startsWith("-"))return{error:`'${e}' is not a commit`};const t=o(r,["rev-parse","--verify","--quiet","--end-of-options",`${e}^{commit}`]);return t.ok&&/^[0-9a-f]{40,64}$/.test(t.out)?{sha:t.out}:{error:`'${e}' names no commit in ${r}`}}s(resolveCommit,"resolveCommit"),c(resolveCommit,"resolveCommit"),i(resolveCommit,"resolveCommit");export function branchExists(r,e,o=gitExec){return o(r,["show-ref","--verify","--quiet",`refs/heads/${e}`]).ok}s(branchExists,"branchExists"),c(branchExists,"branchExists"),i(branchExists,"branchExists");export function worktreesHome(r,e,o=process.env){if(e){const t=o.HOME||k(),n=e==="~"?t:e.startsWith("~/")?m(t,e.slice(2)):e;return y(n)?v(n):v(r,n)}return m(r,".lensmcp","worktrees")}s(worktreesHome,"worktreesHome"),c(worktreesHome,"worktreesHome"),i(worktreesHome,"worktreesHome");export function ensureIgnored(r,e,o=gitExec){const t=N(r,e);if(!t||t.startsWith("..")||y(t)||o(r,["check-ignore","-q","--no-index","--end-of-options",m(t,"probe")]).ok)return;const n=o(r,["rev-parse","--path-format=absolute","--git-common-dir"]);if(!n.ok||!n.out)return;const a=m(n.out,"info","exclude"),u=`/${t.split(F).join("/")}/`;f(p(a),{recursive:!0});let d="";try{d=l(a,"utf8")}catch{}if(!d.split(`
2
- `).includes(u))return E(a,`${d&&!d.endsWith(`
1
+ "use strict";var x=Object.defineProperty;var s=(t,e)=>x(t,"name",{value:e,configurable:!0});var v=Object.defineProperty,i=s((t,e)=>v(t,"name",{value:e,configurable:!0}),"o");import{spawnSync as b}from"node:child_process";import{appendFileSync as w,closeSync as $,existsSync as S,mkdirSync as f,openSync as E,readFileSync as p,renameSync as P,rmSync as m,statSync as N,writeFileSync as h}from"node:fs";import{homedir as k}from"node:os";import{dirname as l,isAbsolute as g,join as d,relative as W,resolve as y,sep as B}from"node:path";export function gitExec(t,e,o=12e4){const r=b("git",e,{cwd:t,encoding:"utf8",timeout:o,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}});return{ok:r.status===0,out:typeof r.stdout=="string"?r.stdout.trim():"",err:(typeof r.stderr=="string"?r.stderr.trim():"")||(r.error?r.error.message:r.status===null?"git was killed":"")}}s(gitExec,"gitExec"),i(gitExec,"gitExec");export function branchNameProblem(t,e,o=gitExec){if(!e||e.startsWith("-"))return`'${e}' is not a branch name`;if(!o(t,["check-ref-format","--branch",e]).ok)return`'${e}' is not a valid branch name (git check-ref-format)`}s(branchNameProblem,"branchNameProblem"),i(branchNameProblem,"branchNameProblem");export function resolveCommit(t,e,o=gitExec){if(!e||e.startsWith("-"))return{error:`'${e}' is not a commit`};const r=o(t,["rev-parse","--verify","--quiet","--end-of-options",`${e}^{commit}`]);return r.ok&&/^[0-9a-f]{40,64}$/.test(r.out)?{sha:r.out}:{error:`'${e}' names no commit in ${t}`}}s(resolveCommit,"resolveCommit"),i(resolveCommit,"resolveCommit");export function branchExists(t,e,o=gitExec){return o(t,["show-ref","--verify","--quiet",`refs/heads/${e}`]).ok}s(branchExists,"branchExists"),i(branchExists,"branchExists");export function worktreesHome(t,e,o=process.env){if(e){const r=o.HOME||k(),n=e==="~"?r:e.startsWith("~/")?d(r,e.slice(2)):e;return g(n)?y(n):y(t,n)}return d(t,".lensmcp","worktrees")}s(worktreesHome,"worktreesHome"),i(worktreesHome,"worktreesHome");export function ensureIgnored(t,e,o=gitExec){const r=W(t,e);if(!r||r.startsWith("..")||g(r)||o(t,["check-ignore","-q","--no-index","--end-of-options",d(r,"probe")]).ok)return;const n=o(t,["rev-parse","--path-format=absolute","--git-common-dir"]);if(!n.ok||!n.out)return;const c=d(n.out,"info","exclude"),a=`/${r.split(B).join("/")}/`;f(l(c),{recursive:!0});let u="";try{u=p(c,"utf8")}catch{}if(!u.split(`
2
+ `).includes(a))return w(c,`${u&&!u.endsWith(`
3
3
  `)?`
4
4
  `:""}# lensmcp instance create: its worktrees
5
- ${u}
6
- `),u}s(ensureIgnored,"ensureIgnored"),c(ensureIgnored,"ensureIgnored"),i(ensureIgnored,"ensureIgnored");export function addWorktree(r,e,o,t=gitExec){f(p(e),{recursive:!0});let n,a=!1;o.branch?branchExists(r,o.branch,t)?n=["worktree","add","--end-of-options",e,o.branch]:(n=["worktree","add","-b",o.branch,"--end-of-options",e,o.from],a=!0):n=["worktree","add","--detach","--end-of-options",e,o.from];const u=t(r,n);return u.ok?{ok:!0,createdBranch:a}:{ok:!1,error:u.err||`git ${n.join(" ")} failed`}}s(addWorktree,"addWorktree"),c(addWorktree,"addWorktree"),i(addWorktree,"addWorktree");export function uncommittedChanges(r,e=gitExec){const o=e(r,["status","--porcelain","--untracked-files=all"]);if(o.ok)return o.out?o.out.split(`
7
- `).map(t=>t.trimEnd()).filter(Boolean):[]}s(uncommittedChanges,"uncommittedChanges"),c(uncommittedChanges,"uncommittedChanges"),i(uncommittedChanges,"uncommittedChanges");export function currentBranch(r,e=gitExec){const o=e(r,["symbolic-ref","--quiet","--short","HEAD"]);return o.ok&&o.out?o.out:void 0}s(currentBranch,"currentBranch"),c(currentBranch,"currentBranch"),i(currentBranch,"currentBranch");export function removeWorktree(r,e,o,t=gitExec){const n=t(r,["worktree","remove",...o?["--force"]:[],"--end-of-options",e]);return n.ok&&t(r,["worktree","prune"]),n}s(removeWorktree,"removeWorktree"),c(removeWorktree,"removeWorktree"),i(removeWorktree,"removeWorktree");export function deleteBranch(r,e,o,t=gitExec){return t(r,["branch",o?"-D":"-d","--end-of-options",e])}s(deleteBranch,"deleteBranch"),c(deleteBranch,"deleteBranch"),i(deleteBranch,"deleteBranch");export function progressFile(r,e=process.env){return m(e.LENSMCP_HOME||k(),".lensmcp","worktrees",`${r}.json`)}s(progressFile,"progressFile"),c(progressFile,"progressFile"),i(progressFile,"progressFile");export function writeProgress(r,e){f(p(r),{recursive:!0,mode:448});const o=`${r}.${process.pid}.tmp`;g(o,JSON.stringify(e,null,2)+`
8
- `,{mode:384}),B(o,r)}s(writeProgress,"writeProgress"),c(writeProgress,"writeProgress"),i(writeProgress,"writeProgress");export function readProgress(r){try{const e=JSON.parse(l(r,"utf8"));return e&&typeof e.key=="string"&&typeof e.state=="string"?e:void 0}catch{return}}s(readProgress,"readProgress"),c(readProgress,"readProgress"),i(readProgress,"readProgress");export function settledProgress(r,e=pidAlive){return r.state==="ready"||r.state==="failed"||e(r.pid)?r:{...r,state:"failed",detail:`the create (pid ${r.pid}) ended during '${r.state}' without finishing${r.log?` \u2014 see ${r.log}`:""}`}}s(settledProgress,"settledProgress"),c(settledProgress,"settledProgress"),i(settledProgress,"settledProgress");export function pidAlive(r){try{return process.kill(r,0),!0}catch(e){return e.code==="EPERM"}}s(pidAlive,"pidAlive"),c(pidAlive,"pidAlive"),i(pidAlive,"pidAlive");const M=1e4;export function claimCreate(r,e=process.pid,o=pidAlive){const t=`${r}.claim`;f(p(t),{recursive:!0,mode:448});for(let n=0;n<3;n++)try{const a=W(t,"wx",384);try{g(a,String(e))}finally{P(a)}return{release:i(()=>{try{l(t,"utf8")===String(e)&&h(t,{force:!0})}catch{}},"release")}}catch(a){if(a.code!=="EEXIST")throw a;let u=0,d=0;try{u=Number(l(t,"utf8")),d=Date.now()-C(t).mtimeMs}catch{continue}if(Number.isInteger(u)&&u>0?o(u):d<M)return{heldBy:u};h(t,{force:!0})}return{heldBy:0}}s(claimCreate,"claimCreate"),c(claimCreate,"claimCreate"),i(claimCreate,"claimCreate");export const worktreeFolderExists=i(r=>S(r),"worktreeFolderExists");
5
+ ${a}
6
+ `),a}s(ensureIgnored,"ensureIgnored"),i(ensureIgnored,"ensureIgnored");export function addWorktree(t,e,o,r=gitExec){f(l(e),{recursive:!0});let n,c=!1;o.branch?branchExists(t,o.branch,r)?n=["worktree","add","--end-of-options",e,o.branch]:(n=["worktree","add","-b",o.branch,"--end-of-options",e,o.from],c=!0):n=["worktree","add","--detach","--end-of-options",e,o.from];const a=r(t,n);return a.ok?{ok:!0,createdBranch:c}:{ok:!1,error:a.err||`git ${n.join(" ")} failed`}}s(addWorktree,"addWorktree"),i(addWorktree,"addWorktree");export function uncommittedChanges(t,e=gitExec){const o=e(t,["status","--porcelain","--untracked-files=all"]);if(o.ok)return o.out?o.out.split(`
7
+ `).map(r=>r.trimEnd()).filter(Boolean):[]}s(uncommittedChanges,"uncommittedChanges"),i(uncommittedChanges,"uncommittedChanges");export function currentBranch(t,e=gitExec){const o=e(t,["symbolic-ref","--quiet","--short","HEAD"]);return o.ok&&o.out?o.out:void 0}s(currentBranch,"currentBranch"),i(currentBranch,"currentBranch");export function removeWorktree(t,e,o,r=gitExec){const n=r(t,["worktree","remove",...o?["--force"]:[],"--end-of-options",e]);return n.ok&&r(t,["worktree","prune"]),n}s(removeWorktree,"removeWorktree"),i(removeWorktree,"removeWorktree");export function deleteBranch(t,e,o,r=gitExec){return r(t,["branch",o?"-D":"-d","--end-of-options",e])}s(deleteBranch,"deleteBranch"),i(deleteBranch,"deleteBranch");export function progressFile(t,e=process.env){return d(e.LENSMCP_HOME||k(),".lensmcp","worktrees",`${t}.json`)}s(progressFile,"progressFile"),i(progressFile,"progressFile");export function writeProgress(t,e){f(l(t),{recursive:!0,mode:448});const o=`${t}.${process.pid}.tmp`;h(o,JSON.stringify(e,null,2)+`
8
+ `,{mode:384}),P(o,t)}s(writeProgress,"writeProgress"),i(writeProgress,"writeProgress");export function readProgress(t){try{const e=JSON.parse(p(t,"utf8"));return e&&typeof e.key=="string"&&typeof e.state=="string"?e:void 0}catch{return}}s(readProgress,"readProgress"),i(readProgress,"readProgress");export function settledProgress(t,e=pidAlive){return t.state==="ready"||t.state==="failed"||e(t.pid)?t:{...t,state:"failed",detail:`the create (pid ${t.pid}) ended during '${t.state}' without finishing${t.log?` \u2014 see ${t.log}`:""}`}}s(settledProgress,"settledProgress"),i(settledProgress,"settledProgress");export function pidAlive(t){try{return process.kill(t,0),!0}catch(e){return e.code==="EPERM"}}s(pidAlive,"pidAlive"),i(pidAlive,"pidAlive");const M=1e4;export function claimCreate(t,e=process.pid,o=pidAlive){const r=`${t}.claim`;f(l(r),{recursive:!0,mode:448});for(let n=0;n<3;n++)try{const c=E(r,"wx",384);try{h(c,String(e))}finally{$(c)}return{release:i(()=>{try{p(r,"utf8")===String(e)&&m(r,{force:!0})}catch{}},"release")}}catch(c){if(c.code!=="EEXIST")throw c;let a=0,u=0;try{a=Number(p(r,"utf8")),u=Date.now()-N(r).mtimeMs}catch{continue}if(Number.isInteger(a)&&a>0?o(a):u<M)return{heldBy:a};m(r,{force:!0})}return{heldBy:0}}s(claimCreate,"claimCreate"),i(claimCreate,"claimCreate");export const worktreeFolderExists=i(t=>S(t),"worktreeFolderExists");
@@ -1,2 +1,2 @@
1
- "use strict";var d=Object.defineProperty;var o=(r,t)=>d(r,"name",{value:t,configurable:!0});var l=Object.defineProperty,a=o((r,t)=>l(r,"name",{value:t,configurable:!0}),"o"),p=Object.defineProperty,g=a((r,t)=>p(r,"name",{value:t,configurable:!0}),"o");import{spawnSync as v}from"node:child_process";import{existsSync as f,readFileSync as w}from"node:fs";import{join as u}from"node:path";export const LENS_SHARED_DIRS=["sql-review","route-review","flow-review","ui-review","cache-review","queue-review"];export function lensIgnoreVerdict(r){const t=g(e=>{const n=v("git",["check-ignore","-q","--no-index",e],{cwd:r,timeout:3e3,stdio:"ignore"});return n.status===0?!0:n.status===1?!1:void 0},"ignored"),s=t(".lensmcp/events.jsonl");if(s!==void 0)return{runtimeIgnored:s,sharedIgnored:LENS_SHARED_DIRS.filter(e=>t(`.lensmcp/${e}/instructions.md`)===!0),by:"git"};const i=f(u(r,".gitignore"))?w(u(r,".gitignore"),"utf8").split(`
2
- `).map(e=>e.trim()):[],c=i.some(e=>/^(\/|\*\*\/)?\.lensmcp\/?$/.test(e)),m=i.some(e=>/^(\/|\*\*\/)?\.lensmcp\/\*$/.test(e));return{runtimeIgnored:c||m,sharedIgnored:c?[...LENS_SHARED_DIRS]:LENS_SHARED_DIRS.filter(e=>m&&!i.some(n=>new RegExp(`^!(/|\\*\\*/)?\\.lensmcp/${e}/?$`).test(n))),by:"gitignore"}}o(lensIgnoreVerdict,"lensIgnoreVerdict"),a(lensIgnoreVerdict,"lensIgnoreVerdict"),g(lensIgnoreVerdict,"lensIgnoreVerdict");
1
+ "use strict";var d=Object.defineProperty;var o=(r,t)=>d(r,"name",{value:t,configurable:!0});var a=Object.defineProperty,g=o((r,t)=>a(r,"name",{value:t,configurable:!0}),"o");import{spawnSync as l}from"node:child_process";import{existsSync as p,readFileSync as v}from"node:fs";import{join as u}from"node:path";export const LENS_SHARED_DIRS=["sql-review","route-review","flow-review","ui-review","cache-review","queue-review"];export function lensIgnoreVerdict(r){const t=g(e=>{const i=l("git",["check-ignore","-q","--no-index",e],{cwd:r,timeout:3e3,stdio:"ignore"});return i.status===0?!0:i.status===1?!1:void 0},"ignored"),s=t(".lensmcp/events.jsonl");if(s!==void 0)return{runtimeIgnored:s,sharedIgnored:LENS_SHARED_DIRS.filter(e=>t(`.lensmcp/${e}/instructions.md`)===!0),by:"git"};const n=p(u(r,".gitignore"))?v(u(r,".gitignore"),"utf8").split(`
2
+ `).map(e=>e.trim()):[],c=n.some(e=>/^(\/|\*\*\/)?\.lensmcp\/?$/.test(e)),m=n.some(e=>/^(\/|\*\*\/)?\.lensmcp\/\*$/.test(e));return{runtimeIgnored:c||m,sharedIgnored:c?[...LENS_SHARED_DIRS]:LENS_SHARED_DIRS.filter(e=>m&&!n.some(i=>new RegExp(`^!(/|\\*\\*/)?\\.lensmcp/${e}/?$`).test(i))),by:"gitignore"}}o(lensIgnoreVerdict,"lensIgnoreVerdict"),g(lensIgnoreVerdict,"lensIgnoreVerdict");
package/lib/lint-args.js CHANGED
@@ -1 +1 @@
1
- "use strict";var u=Object.defineProperty;var c=(t,e)=>u(t,"name",{value:e,configurable:!0});var d=Object.defineProperty,a=c((t,e)=>d(t,"name",{value:e,configurable:!0}),"c"),f=Object.defineProperty,g=a((t,e)=>f(t,"name",{value:e,configurable:!0}),"o");export function splitLintArgs(t){const e=t.indexOf("--"),s=e===-1?t:t.slice(0,e),o=e===-1?[]:t.slice(e),l=[];let r;for(let n=0;n<s.length;n++){const i=s[n];i==="--cwd"?r=s[++n]:i.startsWith("--cwd=")?r=i.slice(6):l.push(i)}return{...r?{cwd:r}:{},runnerArgs:[...l,...o]}}c(splitLintArgs,"splitLintArgs"),a(splitLintArgs,"splitLintArgs"),g(splitLintArgs,"splitLintArgs");
1
+ "use strict";var u=Object.defineProperty;var c=(e,r)=>u(e,"name",{value:r,configurable:!0});var a=Object.defineProperty,d=c((e,r)=>a(e,"name",{value:r,configurable:!0}),"o");export function splitLintArgs(e){const r=e.indexOf("--"),i=r===-1?e:e.slice(0,r),o=r===-1?[]:e.slice(r),l=[];let s;for(let t=0;t<i.length;t++){const n=i[t];n==="--cwd"?s=i[++t]:n.startsWith("--cwd=")?s=n.slice(6):l.push(n)}return{...s?{cwd:s}:{},runnerArgs:[...l,...o]}}c(splitLintArgs,"splitLintArgs"),d(splitLintArgs,"splitLintArgs");
@@ -1 +1 @@
1
- "use strict";var n=Object.defineProperty;var e=(o,l)=>n(o,"name",{value:l,configurable:!0});var r=Object.defineProperty,t=e((o,l)=>r(o,"name",{value:l,configurable:!0}),"e"),s=Object.defineProperty,a=t((o,l)=>s(o,"name",{value:l,configurable:!0}),"l");export const LOGS_NOT_FOLLOWED_HINT="lensmcp logs: output is not a terminal \u2014 printed the lines held and stopped. Pass --follow to keep streaming.";export function logsFollow(o){return o.noFollow?{follow:!1}:o.follow||o.isTTY||o.color?{follow:!0}:{follow:!1,hint:LOGS_NOT_FOLLOWED_HINT}}e(logsFollow,"logsFollow"),t(logsFollow,"logsFollow"),a(logsFollow,"logsFollow");
1
+ "use strict";var t=Object.defineProperty;var e=(o,l)=>t(o,"name",{value:l,configurable:!0});var n=Object.defineProperty,r=e((o,l)=>n(o,"name",{value:l,configurable:!0}),"l");export const LOGS_NOT_FOLLOWED_HINT="lensmcp logs: output is not a terminal \u2014 printed the lines held and stopped. Pass --follow to keep streaming.";export function logsFollow(o){return o.noFollow?{follow:!1}:o.follow||o.isTTY||o.color?{follow:!0}:{follow:!1,hint:LOGS_NOT_FOLLOWED_HINT}}e(logsFollow,"logsFollow"),r(logsFollow,"logsFollow");
package/lib/mcp-mode.js CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";var M=Object.defineProperty;var t=(e,o)=>M(e,"name",{value:o,configurable:!0});var m=Object.defineProperty,n=t((e,o)=>m(e,"name",{value:o,configurable:!0}),"t"),u=Object.defineProperty,c=n((e,o)=>u(e,"name",{value:o,configurable:!0}),"t");export const DEFAULT_MCP_MODE="shared",SHARED_MCP_ENTRY_PATH="/mcp",SHARED_MCP_BIND_ADDRESS="127.0.0.1";export function isMcpMode(e){return e==="embedded"||e==="shared"}t(isMcpMode,"isMcpMode"),n(isMcpMode,"isMcpMode"),c(isMcpMode,"isMcpMode");export function sharedMcpUrl(e,o=SHARED_MCP_BIND_ADDRESS){return`http://${o}:${e}${SHARED_MCP_ENTRY_PATH}`}t(sharedMcpUrl,"sharedMcpUrl"),n(sharedMcpUrl,"sharedMcpUrl"),c(sharedMcpUrl,"sharedMcpUrl");export function resolveMcpMode(e={}){return resolveMcpModeWithSource(e).mode}t(resolveMcpMode,"resolveMcpMode"),n(resolveMcpMode,"resolveMcpMode"),c(resolveMcpMode,"resolveMcpMode");export function resolveMcpModeWithSource(e={}){const o=[["flag",e.flag],["env",e.env],["config",e.config]];for(const[d,r]of o)if(isMcpMode(r))return{mode:r,source:d};return{mode:DEFAULT_MCP_MODE,source:"default"}}t(resolveMcpModeWithSource,"resolveMcpModeWithSource"),n(resolveMcpModeWithSource,"resolveMcpModeWithSource"),c(resolveMcpModeWithSource,"resolveMcpModeWithSource");export const MCP_MODE_SOURCE_LABELS={flag:"--mcp",env:"LENSMCP_MCP_MODE",config:".lensmcp/config.json mcp.mode",default:"the default"};export function mcpModeSwitchHint(e){return e.mode==="embedded"?e.source==="env"?"the default is one shared server per workspace: unset LENSMCP_MCP_MODE":"the default is one shared server per workspace: `lensmcp setup --mcp shared`":e.source==="env"?"one server per agent session instead: LENSMCP_MCP_MODE=embedded":"one server per agent session instead: `lensmcp setup --mcp embedded`"}t(mcpModeSwitchHint,"mcpModeSwitchHint"),n(mcpModeSwitchHint,"mcpModeSwitchHint"),c(mcpModeSwitchHint,"mcpModeSwitchHint");function i(e){if(!e||!e.trim())return{};try{const o=JSON.parse(e);return o&&typeof o=="object"&&!Array.isArray(o)?o:{}}catch{return{}}}t(i,"i"),n(i,"p"),c(i,"parseObject");export const MCP_MODE_CHOSEN_BY_USER="user";export function applyConfigMcpMode(e,o){const d=i(e),r=d.mcp,s={mode:o,modeSource:MCP_MODE_CHOSEN_BY_USER},a=r&&typeof r=="object"&&!Array.isArray(r)?{...r,...s}:s,p=JSON.stringify({...d,mcp:a},null,2)+`
2
- `;return{json:p,changed:p!==e}}t(applyConfigMcpMode,"applyConfigMcpMode"),n(applyConfigMcpMode,"applyConfigMcpMode"),c(applyConfigMcpMode,"applyConfigMcpMode");export function migrateUnchosenMcpPin(e,o){const d={json:e??"",changed:!1,migrated:!1},r=i(e),s=r.mcp;if(!s||typeof s!="object"||Array.isArray(s))return d;const{mode:a,...p}=s;return a!=="embedded"||p.modeSource!==void 0||p.modeMigrated!==void 0?d:{json:JSON.stringify({...r,mcp:{...p,modeMigrated:{from:"embedded",at:o}}},null,2)+`
3
- `,changed:!0,migrated:!0}}t(migrateUnchosenMcpPin,"migrateUnchosenMcpPin"),n(migrateUnchosenMcpPin,"migrateUnchosenMcpPin"),c(migrateUnchosenMcpPin,"migrateUnchosenMcpPin");export const MCP_PIN_MIGRATION_NOTICE='moved mcp.mode "embedded" in .lensmcp/config.json \u2014 an older `lensmcp setup` wrote it, nobody chose it \u2014 to the default, shared; to keep embedded: `lensmcp setup --mcp embedded`';
1
+ "use strict";var a=Object.defineProperty;var t=(e,o)=>a(e,"name",{value:o,configurable:!0});var m=Object.defineProperty,n=t((e,o)=>m(e,"name",{value:o,configurable:!0}),"t");export const DEFAULT_MCP_MODE="shared",SHARED_MCP_ENTRY_PATH="/mcp",SHARED_MCP_BIND_ADDRESS="127.0.0.1";export function isMcpMode(e){return e==="embedded"||e==="shared"}t(isMcpMode,"isMcpMode"),n(isMcpMode,"isMcpMode");export function sharedMcpUrl(e,o=SHARED_MCP_BIND_ADDRESS){return`http://${o}:${e}${SHARED_MCP_ENTRY_PATH}`}t(sharedMcpUrl,"sharedMcpUrl"),n(sharedMcpUrl,"sharedMcpUrl");export function resolveMcpMode(e={}){return resolveMcpModeWithSource(e).mode}t(resolveMcpMode,"resolveMcpMode"),n(resolveMcpMode,"resolveMcpMode");export function resolveMcpModeWithSource(e={}){const o=[["flag",e.flag],["env",e.env],["config",e.config]];for(const[c,r]of o)if(isMcpMode(r))return{mode:r,source:c};return{mode:DEFAULT_MCP_MODE,source:"default"}}t(resolveMcpModeWithSource,"resolveMcpModeWithSource"),n(resolveMcpModeWithSource,"resolveMcpModeWithSource");export const MCP_MODE_SOURCE_LABELS={flag:"--mcp",env:"LENSMCP_MCP_MODE",config:".lensmcp/config.json mcp.mode",default:"the default"};export function mcpModeSwitchHint(e){return e.mode==="embedded"?e.source==="env"?"the default is one shared server per workspace: unset LENSMCP_MCP_MODE":"the default is one shared server per workspace: `lensmcp setup --mcp shared`":e.source==="env"?"one server per agent session instead: LENSMCP_MCP_MODE=embedded":"one server per agent session instead: `lensmcp setup --mcp embedded`"}t(mcpModeSwitchHint,"mcpModeSwitchHint"),n(mcpModeSwitchHint,"mcpModeSwitchHint");function i(e){if(!e||!e.trim())return{};try{const o=JSON.parse(e);return o&&typeof o=="object"&&!Array.isArray(o)?o:{}}catch{return{}}}t(i,"p"),n(i,"parseObject");export const MCP_MODE_CHOSEN_BY_USER="user";export function applyConfigMcpMode(e,o){const c=i(e),r=c.mcp,d={mode:o,modeSource:MCP_MODE_CHOSEN_BY_USER},p=r&&typeof r=="object"&&!Array.isArray(r)?{...r,...d}:d,s=JSON.stringify({...c,mcp:p},null,2)+`
2
+ `;return{json:s,changed:s!==e}}t(applyConfigMcpMode,"applyConfigMcpMode"),n(applyConfigMcpMode,"applyConfigMcpMode");export function migrateUnchosenMcpPin(e,o){const c={json:e??"",changed:!1,migrated:!1},r=i(e),d=r.mcp;if(!d||typeof d!="object"||Array.isArray(d))return c;const{mode:p,...s}=d;return p!=="embedded"||s.modeSource!==void 0||s.modeMigrated!==void 0?c:{json:JSON.stringify({...r,mcp:{...s,modeMigrated:{from:"embedded",at:o}}},null,2)+`
3
+ `,changed:!0,migrated:!0}}t(migrateUnchosenMcpPin,"migrateUnchosenMcpPin"),n(migrateUnchosenMcpPin,"migrateUnchosenMcpPin");export const MCP_PIN_MIGRATION_NOTICE='moved mcp.mode "embedded" in .lensmcp/config.json \u2014 an older `lensmcp setup` wrote it, nobody chose it \u2014 to the default, shared; to keep embedded: `lensmcp setup --mcp embedded`';