lensmcp 1.25.18 → 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 (54) hide show
  1. package/bin.js +1 -1
  2. package/bundled/dashboard-ui/app.js +52 -52
  3. package/bundled/dashboard.js +233 -233
  4. package/bundled/main.js +1 -1
  5. package/lib/agent-asked.js +4 -4
  6. package/lib/agent-plugins.js +2 -2
  7. package/lib/bridge-origins.js +1 -1
  8. package/lib/call-command.js +2 -2
  9. package/lib/cli-help.js +3 -3
  10. package/lib/cli.js +12 -12
  11. package/lib/dashboard-login.d.ts +9 -2
  12. package/lib/dashboard-login.js +3 -3
  13. package/lib/dismiss-command.js +2 -2
  14. package/lib/duplicate-registration.js +1 -1
  15. package/lib/forward-signals.js +1 -1
  16. package/lib/gateway-registration.js +1 -1
  17. package/lib/guest-graph.js +4 -4
  18. package/lib/heap-analyzer-main.js +1 -1
  19. package/lib/heap-analyzer.js +1 -1
  20. package/lib/hook-memory.js +1 -1
  21. package/lib/instance-command.js +9 -9
  22. package/lib/instance-registry.js +2 -2
  23. package/lib/instance-resources.js +5 -5
  24. package/lib/instance-worktree.js +6 -6
  25. package/lib/lens-ignore.js +2 -2
  26. package/lib/lint-args.js +1 -1
  27. package/lib/logs-follow.js +1 -1
  28. package/lib/mcp-mode.js +3 -3
  29. package/lib/mcp-restart.js +1 -1
  30. package/lib/mcp-sessions.js +2 -2
  31. package/lib/mcp-token.js +3 -3
  32. package/lib/mcp-wiring.js +2 -2
  33. package/lib/mem-command.js +3 -3
  34. package/lib/perf-rules-check.js +4 -4
  35. package/lib/plugin-version.js +3 -3
  36. package/lib/pod-source-maps.js +1 -1
  37. package/lib/process-identity.js +1 -1
  38. package/lib/process-ownership.js +2 -2
  39. package/lib/project-files.js +1 -1
  40. package/lib/recycle-policy.js +1 -1
  41. package/lib/resp-client.js +5 -5
  42. package/lib/restart-command.js +2 -2
  43. package/lib/server-bundle.js +2 -2
  44. package/lib/status-client.js +2 -2
  45. package/lib/status-policy.js +2 -2
  46. package/lib/sweep.js +1 -1
  47. package/lib/upgrade.js +2 -2
  48. package/lib/workspace-scope.js +2 -2
  49. package/package.json +4 -4
  50. package/plugin/.claude-plugin/plugin.json +1 -1
  51. package/plugin/skills/dashboard/SKILL.md +2 -1
  52. package/plugin/skills/worktrees/SKILL.md +2 -1
  53. package/plugins/lensmcp/.codex-plugin/plugin.json +1 -1
  54. package/plugins/lensmcp/skills/lensmcp-dashboard/SKILL.md +2 -1
package/lib/upgrade.js CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";var x=Object.defineProperty;var i=(e,t)=>x(e,"name",{value:t,configurable:!0});var $=Object.defineProperty,c=i((e,t)=>$(e,"name",{value:t,configurable:!0}),"i"),b=Object.defineProperty,p=c((e,t)=>b(e,"name",{value:t,configurable:!0}),"c");import{spawnSync as w}from"node:child_process";import{existsSync as y,readFileSync as f}from"node:fs";import{homedir as v}from"node:os";import{join as g}from"node:path";export const UPGRADE_SECTIONS=["dependencies","devDependencies","optionalDependencies","resolutions","overrides"];export function isLensmcpPackage(e){return e==="lensmcp"||e.startsWith("@lensmcp/")}i(isLensmcpPackage,"isLensmcpPackage"),c(isLensmcpPackage,"isLensmcpPackage"),p(isLensmcpPackage,"isLensmcpPackage");export function readConnectedWorkspaces(e={}){const t=e.home??process.env.LENSMCP_HOME??v(),n=e.exists??y,r=e.readFile??(u=>f(u,"utf8"));let s;try{s=JSON.parse(r(g(t,".lensmcp","workspaces.json")))}catch{return[]}if(!Array.isArray(s))return[];const a=new Set,d=[];for(const u of s){if(!u||typeof u!="object")continue;const{key:o,root:l}=u;typeof o!="string"||typeof l!="string"||l.length===0||a.has(l)||n(g(l,"package.json"))&&(a.add(l),d.push({key:o,root:l}))}return d}i(readConnectedWorkspaces,"readConnectedWorkspaces"),c(readConnectedWorkspaces,"readConnectedWorkspaces"),p(readConnectedWorkspaces,"readConnectedWorkspaces");export function upgradeTargets(e,t,n){const r=[],s=[],a=new Set;for(const d of[...e?[e]:[],...t])a.has(d.root)||(a.add(d.root),(n(d.root)?s:r).push(d));return{targets:r,instances:s}}i(upgradeTargets,"upgradeTargets"),c(upgradeTargets,"upgradeTargets"),p(upgradeTargets,"upgradeTargets");export function versionPrefix(e){const t=/^([~^]?)(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(e.trim());return t?t[1]:void 0}i(versionPrefix,"versionPrefix"),c(versionPrefix,"versionPrefix"),p(versionPrefix,"versionPrefix");function m(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}i(m,"m"),c(m,"h"),p(m,"escapeRegExp");export function rewriteLensmcpDeps(e,t){let n;try{n=JSON.parse(e)}catch{return{text:e,changes:[],skipped:[]}}const r=[],s=[];for(const d of UPGRADE_SECTIONS){const u=n[d];if(!(!u||typeof u!="object"))for(const[o,l]of Object.entries(u)){if(typeof l!="string"||!isLensmcpPackage(o))continue;const h=versionPrefix(l);if(h===void 0){s.push({name:o,section:d,spec:l,reason:"non-version-spec"});continue}const k=`${h}${t}`;if(k===l){s.push({name:o,section:d,spec:l,reason:"already-current"});continue}r.push({name:o,section:d,from:l,to:k})}}let a=e;for(const d of r){const u=new RegExp(`("${m(d.name)}"\\s*:\\s*)"${m(d.from)}"`,"g");a=a.replace(u,`$1"${d.to}"`)}return{text:a,changes:r,skipped:s}}i(rewriteLensmcpDeps,"rewriteLensmcpDeps"),c(rewriteLensmcpDeps,"rewriteLensmcpDeps"),p(rewriteLensmcpDeps,"rewriteLensmcpDeps");export function detectPackageManager(e,t=y,n=r=>f(r,"utf8")){let r;try{const a=JSON.parse(n(g(e,"package.json")));typeof a.packageManager=="string"&&(r=a.packageManager.split("@")[0])}catch{}const s=p(a=>({name:a,install:["install"]}),"manager");return r==="yarn"||r==="npm"||r==="pnpm"||r==="bun"?s(r):t(g(e,"yarn.lock"))?s("yarn"):t(g(e,"pnpm-lock.yaml"))?s("pnpm"):t(g(e,"bun.lockb"))?s("bun"):s("npm")}i(detectPackageManager,"detectPackageManager"),c(detectPackageManager,"detectPackageManager"),p(detectPackageManager,"detectPackageManager");export function detectGlobalInstall(e,t=n=>f(n,"utf8")){const n=e("npm",["root","-g"]);if(!n||n.code!==0||!n.stdout)return;const r=n.stdout.trim();if(r)try{const s=JSON.parse(t(g(r,"lensmcp","package.json")));return typeof s.version=="string"?{version:s.version,root:r}:void 0}catch{return}}i(detectGlobalInstall,"detectGlobalInstall"),c(detectGlobalInstall,"detectGlobalInstall"),p(detectGlobalInstall,"detectGlobalInstall");export function registryAnswer(e,t){if(!e)return"unknown";const n=(e.stdout??"").trim();return e.code===0?n.split(`
1
+ "use strict";var w=Object.defineProperty;var i=(e,t)=>w(e,"name",{value:t,configurable:!0});var x=Object.defineProperty,c=i((e,t)=>x(e,"name",{value:t,configurable:!0}),"c");import{spawnSync as k}from"node:child_process";import{existsSync as g,readFileSync as f}from"node:fs";import{homedir as $}from"node:os";import{join as l}from"node:path";export const UPGRADE_SECTIONS=["dependencies","devDependencies","optionalDependencies","resolutions","overrides"];export function isLensmcpPackage(e){return e==="lensmcp"||e.startsWith("@lensmcp/")}i(isLensmcpPackage,"isLensmcpPackage"),c(isLensmcpPackage,"isLensmcpPackage");export function readConnectedWorkspaces(e={}){const t=e.home??process.env.LENSMCP_HOME??$(),n=e.exists??g,r=e.readFile??(d=>f(d,"utf8"));let o;try{o=JSON.parse(r(l(t,".lensmcp","workspaces.json")))}catch{return[]}if(!Array.isArray(o))return[];const a=new Set,p=[];for(const d of o){if(!d||typeof d!="object")continue;const{key:s,root:u}=d;typeof s!="string"||typeof u!="string"||u.length===0||a.has(u)||n(l(u,"package.json"))&&(a.add(u),p.push({key:s,root:u}))}return p}i(readConnectedWorkspaces,"readConnectedWorkspaces"),c(readConnectedWorkspaces,"readConnectedWorkspaces");export function upgradeTargets(e,t,n){const r=[],o=[],a=new Set;for(const p of[...e?[e]:[],...t])a.has(p.root)||(a.add(p.root),(n(p.root)?o:r).push(p));return{targets:r,instances:o}}i(upgradeTargets,"upgradeTargets"),c(upgradeTargets,"upgradeTargets");export function versionPrefix(e){const t=/^([~^]?)(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(e.trim());return t?t[1]:void 0}i(versionPrefix,"versionPrefix"),c(versionPrefix,"versionPrefix");function m(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}i(m,"h"),c(m,"escapeRegExp");export function rewriteLensmcpDeps(e,t){let n;try{n=JSON.parse(e)}catch{return{text:e,changes:[],skipped:[]}}const r=[],o=[];for(const p of UPGRADE_SECTIONS){const d=n[p];if(!(!d||typeof d!="object"))for(const[s,u]of Object.entries(d)){if(typeof u!="string"||!isLensmcpPackage(s))continue;const y=versionPrefix(u);if(y===void 0){o.push({name:s,section:p,spec:u,reason:"non-version-spec"});continue}const h=`${y}${t}`;if(h===u){o.push({name:s,section:p,spec:u,reason:"already-current"});continue}r.push({name:s,section:p,from:u,to:h})}}let a=e;for(const p of r){const d=new RegExp(`("${m(p.name)}"\\s*:\\s*)"${m(p.from)}"`,"g");a=a.replace(d,`$1"${p.to}"`)}return{text:a,changes:r,skipped:o}}i(rewriteLensmcpDeps,"rewriteLensmcpDeps"),c(rewriteLensmcpDeps,"rewriteLensmcpDeps");export function detectPackageManager(e,t=g,n=r=>f(r,"utf8")){let r;try{const a=JSON.parse(n(l(e,"package.json")));typeof a.packageManager=="string"&&(r=a.packageManager.split("@")[0])}catch{}const o=c(a=>({name:a,install:["install"]}),"manager");return r==="yarn"||r==="npm"||r==="pnpm"||r==="bun"?o(r):t(l(e,"yarn.lock"))?o("yarn"):t(l(e,"pnpm-lock.yaml"))?o("pnpm"):t(l(e,"bun.lockb"))?o("bun"):o("npm")}i(detectPackageManager,"detectPackageManager"),c(detectPackageManager,"detectPackageManager");export function detectGlobalInstall(e,t=n=>f(n,"utf8")){const n=e("npm",["root","-g"]);if(!n||n.code!==0||!n.stdout)return;const r=n.stdout.trim();if(r)try{const o=JSON.parse(t(l(r,"lensmcp","package.json")));return typeof o.version=="string"?{version:o.version,root:r}:void 0}catch{return}}i(detectGlobalInstall,"detectGlobalInstall"),c(detectGlobalInstall,"detectGlobalInstall");export function registryAnswer(e,t){if(!e)return"unknown";const n=(e.stdout??"").trim();return e.code===0?n.split(`
2
2
  `).some(r=>r.trim()===t)?"published":n===""?"absent":"unknown":/\bE404\b|\bETARGET\b|No match found/i.test(`${e.stderr??""}
3
- ${n}`)?"absent":"unknown"}i(registryAnswer,"registryAnswer"),c(registryAnswer,"registryAnswer"),p(registryAnswer,"registryAnswer");export function lensPackagesIn(e){const t=new Set,n=/(?<![\w-])(@lensmcp\/[a-z0-9][a-z0-9-]*)(?=["'@:\s/])/g,r=/(?:(?<=node_modules\/)|(?<![\w@/.-]))(lensmcp)(?=["'@:\s])/g;for(const s of e){for(const a of s.matchAll(n))t.add(a[1]);for(const a of s.matchAll(r))t.add(a[1])}return[...t].sort()}i(lensPackagesIn,"lensPackagesIn"),c(lensPackagesIn,"lensPackagesIn"),p(lensPackagesIn,"lensPackagesIn");export function missingFromRegistry(e,t,n){return e.filter(r=>registryAnswer(n(r),t)==="absent")}i(missingFromRegistry,"missingFromRegistry"),c(missingFromRegistry,"missingFromRegistry"),p(missingFromRegistry,"missingFromRegistry");export function installedCliFor(e,t){const n=g(e,"node_modules","lensmcp"),r=g(n,"bin.js");try{return JSON.parse(f(g(n,"package.json"),"utf8")).version===t&&y(r)?r:void 0}catch{return}}i(installedCliFor,"installedCliFor"),c(installedCliFor,"installedCliFor"),p(installedCliFor,"installedCliFor");export function restartGatewayWith(e,t,n){return w(process.execPath,[e,"gateway","restart"],{cwd:t,env:n,stdio:"inherit"}).status??1}i(restartGatewayWith,"restartGatewayWith"),c(restartGatewayWith,"restartGatewayWith"),p(restartGatewayWith,"restartGatewayWith");export function installLanded(e,t){return e===t}i(installLanded,"installLanded"),c(installLanded,"installLanded"),p(installLanded,"installLanded");export function needsInstall(e){return e.rewritten||e.installedVersion!==e.targetVersion}i(needsInstall,"needsInstall"),c(needsInstall,"needsInstall"),p(needsInstall,"needsInstall");export function daemonVerdict(e){if(e.reported===e.target)return{ok:!0,line:` daemon \u2192 now running ${e.reported} \u2713`};const t=e.ownerInstalled!==void 0&&e.ownerInstalled!==e.target?`its workspace's node_modules holds ${e.ownerInstalled}, so the install did not land \u2014 run it${e.ownerRoot?` in ${e.ownerRoot}`:""}, then \`lensmcp upgrade ${e.target}\` again`:"it restarted onto files that are not the target \u2014 check `lensmcp gateway status`";return{ok:!1,line:` daemon \u2192 runs ${e.reported}, not ${e.target}: ${t}.`}}i(daemonVerdict,"daemonVerdict"),c(daemonVerdict,"daemonVerdict"),p(daemonVerdict,"daemonVerdict");export function setupReminder(e){if(!e.installedVersion||e.setupVersion===e.installedVersion)return;const t=e.setupVersion?`last set up for ${e.setupVersion}`:"not set up yet";return` setup \u2192 '${e.key}' is ${t}, and ${e.installedVersion} is installed: run \`lensmcp setup\` in ${e.root} \u2014 the lens tools are gated until it does.`}i(setupReminder,"setupReminder"),c(setupReminder,"setupReminder"),p(setupReminder,"setupReminder");export function planRestart(e){const t=new Map(e.known.map(o=>[o.key,o.root]));for(const o of e.upgraded)t.set(o.key,o.root);const n=new Set(e.upgraded.map(o=>o.key)),r=new Set(e.registeredKeys),s=e.daemonWsKey!==void 0&&e.daemonVersion!==void 0&&e.targetVersion!==void 0&&e.daemonVersion!==e.targetVersion;if(e.upgraded.length===0&&!s)return{steps:[],note:"nothing was upgraded"};if(!e.daemonWsKey)return{steps:[],note:"no gateway daemon is running \u2014 the next `lensmcp gateway start` picks up the new version"};const a=e.upgraded.find(o=>o.key===e.daemonWsKey),d=a?.root??t.get(e.daemonWsKey),u=[];if(a||s&&d){u.push({key:e.daemonWsKey,root:d,action:"restart",reason:a?"upgraded":"stale-daemon"});for(const o of e.registeredKeys){if(o===e.daemonWsKey)continue;const l=t.get(o);l&&u.push({key:o,root:l,action:"reregister",reason:n.has(o)?"upgraded":"rehost"})}return{steps:u}}if(s&&!d)return{steps:[],note:`the daemon ('${e.daemonWsKey}') runs ${e.daemonVersion} but its root is unknown \u2014 restart it with \`lensmcp gateway restart\` in its workspace`};for(const o of e.upgraded)r.has(o.key)&&u.push({key:o.key,root:o.root,action:"reregister",reason:"upgraded"});return u.length===0?{steps:[],note:`the running daemon ('${e.daemonWsKey}') hosts none of the upgraded workspaces`}:{steps:u}}i(planRestart,"planRestart"),c(planRestart,"planRestart"),p(planRestart,"planRestart");export function setupAfterUpgrade(e){const t=setupReminder(e);return t?e.skip||!e.bin||!installLanded(e.installedVersion,e.targetVersion)?{action:"remind",line:t}:{action:"run",bin:e.bin}:{action:"current"}}i(setupAfterUpgrade,"setupAfterUpgrade"),c(setupAfterUpgrade,"setupAfterUpgrade"),p(setupAfterUpgrade,"setupAfterUpgrade");export function setupWith(e,t,n){return w(process.execPath,[e,"setup","--no-recycle"],{cwd:t,env:n,stdio:"inherit"}).status??1}i(setupWith,"setupWith"),c(setupWith,"setupWith"),p(setupWith,"setupWith");
3
+ ${n}`)?"absent":"unknown"}i(registryAnswer,"registryAnswer"),c(registryAnswer,"registryAnswer");export function lensPackagesIn(e){const t=new Set,n=/(?<![\w-])(@lensmcp\/[a-z0-9][a-z0-9-]*)(?=["'@:\s/])/g,r=/(?:(?<=node_modules\/)|(?<![\w@/.-]))(lensmcp)(?=["'@:\s])/g;for(const o of e){for(const a of o.matchAll(n))t.add(a[1]);for(const a of o.matchAll(r))t.add(a[1])}return[...t].sort()}i(lensPackagesIn,"lensPackagesIn"),c(lensPackagesIn,"lensPackagesIn");export function missingFromRegistry(e,t,n){return e.filter(r=>registryAnswer(n(r),t)==="absent")}i(missingFromRegistry,"missingFromRegistry"),c(missingFromRegistry,"missingFromRegistry");export function installedCliFor(e,t){const n=l(e,"node_modules","lensmcp"),r=l(n,"bin.js");try{return JSON.parse(f(l(n,"package.json"),"utf8")).version===t&&g(r)?r:void 0}catch{return}}i(installedCliFor,"installedCliFor"),c(installedCliFor,"installedCliFor");export function restartGatewayWith(e,t,n){return k(process.execPath,[e,"gateway","restart"],{cwd:t,env:n,stdio:"inherit"}).status??1}i(restartGatewayWith,"restartGatewayWith"),c(restartGatewayWith,"restartGatewayWith");export function installLanded(e,t){return e===t}i(installLanded,"installLanded"),c(installLanded,"installLanded");export function needsInstall(e){return e.rewritten||e.installedVersion!==e.targetVersion}i(needsInstall,"needsInstall"),c(needsInstall,"needsInstall");export function daemonVerdict(e){if(e.reported===e.target)return{ok:!0,line:` daemon \u2192 now running ${e.reported} \u2713`};const t=e.ownerInstalled!==void 0&&e.ownerInstalled!==e.target?`its workspace's node_modules holds ${e.ownerInstalled}, so the install did not land \u2014 run it${e.ownerRoot?` in ${e.ownerRoot}`:""}, then \`lensmcp upgrade ${e.target}\` again`:"it restarted onto files that are not the target \u2014 check `lensmcp gateway status`";return{ok:!1,line:` daemon \u2192 runs ${e.reported}, not ${e.target}: ${t}.`}}i(daemonVerdict,"daemonVerdict"),c(daemonVerdict,"daemonVerdict");export function setupReminder(e){if(!e.installedVersion||e.setupVersion===e.installedVersion)return;const t=e.setupVersion?`last set up for ${e.setupVersion}`:"not set up yet";return` setup \u2192 '${e.key}' is ${t}, and ${e.installedVersion} is installed: run \`lensmcp setup\` in ${e.root} \u2014 the lens tools are gated until it does.`}i(setupReminder,"setupReminder"),c(setupReminder,"setupReminder");export function planRestart(e){const t=new Map(e.known.map(s=>[s.key,s.root]));for(const s of e.upgraded)t.set(s.key,s.root);const n=new Set(e.upgraded.map(s=>s.key)),r=new Set(e.registeredKeys),o=e.daemonWsKey!==void 0&&e.daemonVersion!==void 0&&e.targetVersion!==void 0&&e.daemonVersion!==e.targetVersion;if(e.upgraded.length===0&&!o)return{steps:[],note:"nothing was upgraded"};if(!e.daemonWsKey)return{steps:[],note:"no gateway daemon is running \u2014 the next `lensmcp gateway start` picks up the new version"};const a=e.upgraded.find(s=>s.key===e.daemonWsKey),p=a?.root??t.get(e.daemonWsKey),d=[];if(a||o&&p){d.push({key:e.daemonWsKey,root:p,action:"restart",reason:a?"upgraded":"stale-daemon"});for(const s of e.registeredKeys){if(s===e.daemonWsKey)continue;const u=t.get(s);u&&d.push({key:s,root:u,action:"reregister",reason:n.has(s)?"upgraded":"rehost"})}return{steps:d}}if(o&&!p)return{steps:[],note:`the daemon ('${e.daemonWsKey}') runs ${e.daemonVersion} but its root is unknown \u2014 restart it with \`lensmcp gateway restart\` in its workspace`};for(const s of e.upgraded)r.has(s.key)&&d.push({key:s.key,root:s.root,action:"reregister",reason:"upgraded"});return d.length===0?{steps:[],note:`the running daemon ('${e.daemonWsKey}') hosts none of the upgraded workspaces`}:{steps:d}}i(planRestart,"planRestart"),c(planRestart,"planRestart");export function setupAfterUpgrade(e){const t=setupReminder(e);return t?e.skip||!e.bin||!installLanded(e.installedVersion,e.targetVersion)?{action:"remind",line:t}:{action:"run",bin:e.bin}:{action:"current"}}i(setupAfterUpgrade,"setupAfterUpgrade"),c(setupAfterUpgrade,"setupAfterUpgrade");export function setupWith(e,t,n){return k(process.execPath,[e,"setup","--no-recycle"],{cwd:t,env:n,stdio:"inherit"}).status??1}i(setupWith,"setupWith"),c(setupWith,"setupWith");
@@ -1,2 +1,2 @@
1
- "use strict";var m=Object.defineProperty;var r=(e,n)=>m(e,"name",{value:n,configurable:!0});var l=Object.defineProperty,s=r((e,n)=>l(e,"name",{value:n,configurable:!0}),"r"),y=Object.defineProperty,o=s((e,n)=>y(e,"name",{value:n,configurable:!0}),"r");import{existsSync as d,mkdirSync as h,readFileSync as g,writeFileSync as k}from"node:fs";import{basename as b,join as c}from"node:path";export const INSTANCE_NAME_PATTERN=/^[a-z0-9](?:[a-z0-9-]{0,18}[a-z0-9])?$/;export function instanceSockNs(e){let n=2166136261;for(let t=0;t<e.length;t++)n^=e.charCodeAt(t),n=Math.imul(n,16777619);return`i-${(n>>>0&16777215).toString(16).padStart(6,"0")}`}r(instanceSockNs,"instanceSockNs"),s(instanceSockNs,"instanceSockNs"),o(instanceSockNs,"instanceSockNs");function p(e,n){let t=2166136261;for(let a=0;a<e.length;a++)t^=e.charCodeAt(a),t=Math.imul(t,16777619);return Math.abs(t|0)%n}r(p,"d"),s(p,"l"),o(p,"hashToRange");export function slugify(e){return e.toLowerCase().replace(/^@[^/]+\//,"").replace(/[^a-z0-9]+/g,"-").replace(/(^-|-$)/g,"")||"workspace"}r(slugify,"slugify"),s(slugify,"slugify"),o(slugify,"slugify");export function resolveWorkspaceKey(e){const n=i(c(e,"nx.json"));if(n?.lensmcp?.key)return slugify(n.lensmcp.key);const t=i(c(e,"package.json"));return t?.name?slugify(t.name):n?.name?slugify(n.name):slugify(b(e))}r(resolveWorkspaceKey,"resolveWorkspaceKey"),s(resolveWorkspaceKey,"resolveWorkspaceKey"),o(resolveWorkspaceKey,"resolveWorkspaceKey");const f={dashboard:4321,mcpHttp:4500,bridge:5747};export function derivePorts(e){const n=p(e,200);return{dashboard:f.dashboard+n,mcpHttp:f.mcpHttp+n,bridge:f.bridge+n}}r(derivePorts,"derivePorts"),s(derivePorts,"derivePorts"),o(derivePorts,"derivePorts");export function podNamespace(e){return typeof e.sockNs=="string"&&/^[a-z0-9][a-z0-9-]{0,31}$/.test(e.sockNs)?e.sockNs:isInstanceConfig(e)?instanceSockNs(e.key):e.key}r(podNamespace,"podNamespace"),s(podNamespace,"podNamespace"),o(podNamespace,"podNamespace");export function isInstanceConfig(e){const n=e.instance;return typeof n?.name=="string"&&INSTANCE_NAME_PATTERN.test(n.name)&&typeof n.baseKey=="string"&&n.baseKey.length>0&&e.key===`${n.baseKey}-${n.name}`}r(isInstanceConfig,"isInstanceConfig"),s(isInstanceConfig,"isInstanceConfig"),o(isInstanceConfig,"isInstanceConfig");export function deriveConfig(e){const n=resolveWorkspaceKey(e);return{schemaVersion:1,key:n,ports:derivePorts(n),dashboardBasePath:"/"+n}}r(deriveConfig,"deriveConfig"),s(deriveConfig,"deriveConfig"),o(deriveConfig,"deriveConfig");export function readLensConfig(e){const n=deriveConfig(e),t=i(c(e,".lensmcp","config.json"));if(!t)return n;const a=t.key?slugify(t.key):n.key;return{...t,schemaVersion:1,key:a,ports:{...n.ports,...t.ports??{}},dashboardBasePath:t.dashboardBasePath??"/"+a,...t.mcp?{mcp:{...t.mcp}}:{}}}r(readLensConfig,"readLensConfig"),s(readLensConfig,"readLensConfig"),o(readLensConfig,"readLensConfig");export function ensureLensConfig(e){const n=readLensConfig(e),t=c(e,".lensmcp");d(t)||h(t,{recursive:!0});const a=c(t,"config.json"),u=JSON.stringify(n,null,2)+`
2
- `;return(!d(a)||g(a,"utf8")!==u)&&k(a,u),n}r(ensureLensConfig,"ensureLensConfig"),s(ensureLensConfig,"ensureLensConfig"),o(ensureLensConfig,"ensureLensConfig");function i(e){try{return JSON.parse(g(e,"utf8"))}catch{return}}r(i,"c"),s(i,"c"),o(i,"readJson");
1
+ "use strict";var m=Object.defineProperty;var r=(e,n)=>m(e,"name",{value:n,configurable:!0});var g=Object.defineProperty,s=r((e,n)=>g(e,"name",{value:n,configurable:!0}),"r");import{existsSync as u,mkdirSync as l,readFileSync as f,writeFileSync as y}from"node:fs";import{basename as h,join as a}from"node:path";export const INSTANCE_NAME_PATTERN=/^[a-z0-9](?:[a-z0-9-]{0,18}[a-z0-9])?$/;export function instanceSockNs(e){let n=2166136261;for(let t=0;t<e.length;t++)n^=e.charCodeAt(t),n=Math.imul(n,16777619);return`i-${(n>>>0&16777215).toString(16).padStart(6,"0")}`}r(instanceSockNs,"instanceSockNs"),s(instanceSockNs,"instanceSockNs");function d(e,n){let t=2166136261;for(let o=0;o<e.length;o++)t^=e.charCodeAt(o),t=Math.imul(t,16777619);return Math.abs(t|0)%n}r(d,"l"),s(d,"hashToRange");export function slugify(e){return e.toLowerCase().replace(/^@[^/]+\//,"").replace(/[^a-z0-9]+/g,"-").replace(/(^-|-$)/g,"")||"workspace"}r(slugify,"slugify"),s(slugify,"slugify");export function resolveWorkspaceKey(e){const n=c(a(e,"nx.json"));if(n?.lensmcp?.key)return slugify(n.lensmcp.key);const t=c(a(e,"package.json"));return t?.name?slugify(t.name):n?.name?slugify(n.name):slugify(h(e))}r(resolveWorkspaceKey,"resolveWorkspaceKey"),s(resolveWorkspaceKey,"resolveWorkspaceKey");const i={dashboard:4321,mcpHttp:4500,bridge:5747};export function derivePorts(e){const n=d(e,200);return{dashboard:i.dashboard+n,mcpHttp:i.mcpHttp+n,bridge:i.bridge+n}}r(derivePorts,"derivePorts"),s(derivePorts,"derivePorts");export function podNamespace(e){return typeof e.sockNs=="string"&&/^[a-z0-9][a-z0-9-]{0,31}$/.test(e.sockNs)?e.sockNs:isInstanceConfig(e)?instanceSockNs(e.key):e.key}r(podNamespace,"podNamespace"),s(podNamespace,"podNamespace");export function isInstanceConfig(e){const n=e.instance;return typeof n?.name=="string"&&INSTANCE_NAME_PATTERN.test(n.name)&&typeof n.baseKey=="string"&&n.baseKey.length>0&&e.key===`${n.baseKey}-${n.name}`}r(isInstanceConfig,"isInstanceConfig"),s(isInstanceConfig,"isInstanceConfig");export function deriveConfig(e){const n=resolveWorkspaceKey(e);return{schemaVersion:1,key:n,ports:derivePorts(n),dashboardBasePath:"/"+n}}r(deriveConfig,"deriveConfig"),s(deriveConfig,"deriveConfig");export function readLensConfig(e){const n=deriveConfig(e),t=c(a(e,".lensmcp","config.json"));if(!t)return n;const o=t.key?slugify(t.key):n.key;return{...t,schemaVersion:1,key:o,ports:{...n.ports,...t.ports??{}},dashboardBasePath:t.dashboardBasePath??"/"+o,...t.mcp?{mcp:{...t.mcp}}:{}}}r(readLensConfig,"readLensConfig"),s(readLensConfig,"readLensConfig");export function ensureLensConfig(e){const n=readLensConfig(e),t=a(e,".lensmcp");u(t)||l(t,{recursive:!0});const o=a(t,"config.json"),p=JSON.stringify(n,null,2)+`
2
+ `;return(!u(o)||f(o,"utf8")!==p)&&y(o,p),n}r(ensureLensConfig,"ensureLensConfig"),s(ensureLensConfig,"ensureLensConfig");function c(e){try{return JSON.parse(f(e,"utf8"))}catch{return}}r(c,"c"),s(c,"readJson");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lensmcp",
3
- "version": "1.25.18",
3
+ "version": "1.25.21",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -17,9 +17,9 @@
17
17
  }
18
18
  },
19
19
  "dependencies": {
20
- "@frontmcp/sdk": "^1.10.3",
21
- "@lensmcp/cluster": "1.25.18",
22
- "@lensmcp/nx-plugin": "1.25.18",
20
+ "@frontmcp/sdk": "^1.10.10",
21
+ "@lensmcp/cluster": "1.25.21",
22
+ "@lensmcp/nx-plugin": "1.25.21",
23
23
  "reflect-metadata": "^0.2.2",
24
24
  "tslib": "^2.3.0",
25
25
  "vectoriadb": "^2.2.0"
@@ -2,7 +2,7 @@
2
2
  "name": "lensmcp",
3
3
  "displayName": "LensMCP",
4
4
  "description": "The observability lens for coding agents. One command brings up the dev cluster gateway (every project.json `cluster` decl → its host on :443), the per-project lens dashboard at https://lensmcp.local/<project>/, and the MCP server your agent connects to — scoped automatically to whatever project you opened Claude Code in.",
5
- "version": "1.25.18",
5
+ "version": "1.25.21",
6
6
  "author": {
7
7
  "name": "David Antoon",
8
8
  "email": "davidmantoon@gmail.com"
@@ -13,7 +13,8 @@ Run the open script with the Bash tool:
13
13
  It reads the project's mount path from `.lensmcp/config.json` and opens
14
14
  `https://lensmcp.local/<key>/` — the human view of the lens (the same event stream the
15
15
  MCP server reads) — through the one-time sign-in link `lensmcp gateway status` mints, since
16
- the dashboard asks every caller for a credential. The browser then stays signed in. Five
16
+ the dashboard asks every caller for a credential. The browser then stays signed in — to every
17
+ workspace's and worktree's dashboard on that host. Five
17
18
  screens, each answering one question:
18
19
 
19
20
  - **Overview** — is anything wrong right now? (errors first, then health numbers, the
@@ -41,7 +41,8 @@ session's lens onto it, so every lens tool answers about the worktree's app.
41
41
  `root` and start every shell command with `cd <root> &&`.)
42
42
  - A command that needs the worktree's database, queues or hosts — tests against the DB, a script,
43
43
  a migration: `cd <root> && npx lensmcp instance exec -- <command>`.
44
- - Open the app at the `hosts` in the result. Services start on their first request.
44
+ - Open the app at the `hosts` in the result. Its always-warm services start as the worktree comes up, one at a
45
+ time while the machine has memory to spare; the rest (and any held back) start on their first request.
45
46
  5. **Verify with the lens**, exactly as in main: `observe_current_status`, `observe_errors`, flows —
46
47
  they describe the worktree's app now. `worktree_list` → `active` says which checkout the lens reads.
47
48
  6. **Commit** on the worktree's branch: `git -C <root> add … && git -C <root> commit …`. Tell the
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lensmcp",
3
- "version": "1.25.18",
3
+ "version": "1.25.21",
4
4
  "description": "Observe a running Nx workspace from Codex with runtime flows, build health, cluster failures, and a live dashboard.",
5
5
  "author": {
6
6
  "name": "David Antoon",
@@ -13,7 +13,8 @@ node node_modules/lensmcp/bin.js gateway status --cwd .
13
13
 
14
14
  The dashboard asks every caller for a credential, so the bare
15
15
  `https://lensmcp.local/<project-key>/` URL lands on its sign-in page. Open the printed
16
- `sign in →` link instead (one use, ten minutes; the browser then stays signed in) with the
16
+ `sign in →` link instead (one use, ten minutes; the browser then stays signed in — to every
17
+ workspace's and worktree's dashboard on that host, one sign-in for all) with the
17
18
  available browser tool, or give it to the user when browser opening is unavailable — the
18
19
  `dashboardLoginUrl` field of `gateway status --json` is the same link. If the gateway is
19
20
  not running, use the `lensmcp-start` workflow first.