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.
- package/bin.js +1 -1
- package/bundled/dashboard-ui/app.js +52 -52
- package/bundled/dashboard.js +233 -233
- package/bundled/main.js +1 -1
- package/lib/agent-asked.js +4 -4
- package/lib/agent-plugins.js +2 -2
- package/lib/bridge-origins.js +1 -1
- package/lib/call-command.js +2 -2
- package/lib/cli-help.js +3 -3
- package/lib/cli.js +12 -12
- package/lib/dashboard-login.d.ts +9 -2
- package/lib/dashboard-login.js +3 -3
- package/lib/dismiss-command.js +2 -2
- package/lib/duplicate-registration.js +1 -1
- package/lib/forward-signals.js +1 -1
- package/lib/gateway-registration.js +1 -1
- package/lib/guest-graph.js +4 -4
- package/lib/heap-analyzer-main.js +1 -1
- package/lib/heap-analyzer.js +1 -1
- package/lib/hook-memory.js +1 -1
- package/lib/instance-command.js +9 -9
- package/lib/instance-registry.js +2 -2
- package/lib/instance-resources.js +5 -5
- package/lib/instance-worktree.js +6 -6
- package/lib/lens-ignore.js +2 -2
- package/lib/lint-args.js +1 -1
- package/lib/logs-follow.js +1 -1
- package/lib/mcp-mode.js +3 -3
- package/lib/mcp-restart.js +1 -1
- package/lib/mcp-sessions.js +2 -2
- package/lib/mcp-token.js +3 -3
- package/lib/mcp-wiring.js +2 -2
- package/lib/mem-command.js +3 -3
- package/lib/perf-rules-check.js +4 -4
- package/lib/plugin-version.js +3 -3
- package/lib/pod-source-maps.js +1 -1
- package/lib/process-identity.js +1 -1
- package/lib/process-ownership.js +2 -2
- package/lib/project-files.js +1 -1
- package/lib/recycle-policy.js +1 -1
- package/lib/resp-client.js +5 -5
- package/lib/restart-command.js +2 -2
- package/lib/server-bundle.js +2 -2
- package/lib/status-client.js +2 -2
- package/lib/status-policy.js +2 -2
- package/lib/sweep.js +1 -1
- package/lib/upgrade.js +2 -2
- package/lib/workspace-scope.js +2 -2
- package/package.json +4 -4
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/skills/dashboard/SKILL.md +2 -1
- package/plugin/skills/worktrees/SKILL.md +2 -1
- package/plugins/lensmcp/.codex-plugin/plugin.json +1 -1
- package/plugins/lensmcp/skills/lensmcp-dashboard/SKILL.md +2 -1
package/lib/upgrade.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var
|
|
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")
|
|
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");
|
package/lib/workspace-scope.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var m=Object.defineProperty;var r=(e,n)=>m(e,"name",{value:n,configurable:!0});var
|
|
2
|
-
`;return(!
|
|
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.
|
|
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.
|
|
21
|
-
"@lensmcp/cluster": "1.25.
|
|
22
|
-
"@lensmcp/nx-plugin": "1.25.
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
@@ -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
|
|
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.
|