@lensmcp/core 1.23.9 → 1.23.11

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.
@@ -37,7 +37,7 @@ export declare function trimFlowEvent(event: BaseEvent, opts?: FlowShapeOptions)
37
37
  parentRequestId?: string | undefined;
38
38
  requestId?: string | undefined;
39
39
  role?: string | undefined;
40
- source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai";
40
+ source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai" | "lens";
41
41
  category: "db" | "memory" | "visual" | "security" | "ai" | "build" | "lint" | "typecheck" | "test" | "runtime" | "render" | "trace" | "state" | "network" | "backend" | "performance" | "deps" | "cluster";
42
42
  severity: "error" | "debug" | "info" | "warning" | "fatal";
43
43
  title: string;
@@ -74,7 +74,7 @@ export declare function buildFlowDetail(rawEvents: BaseEvent[], opts?: FlowShape
74
74
  parentRequestId?: string | undefined;
75
75
  requestId?: string | undefined;
76
76
  role?: string | undefined;
77
- source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai";
77
+ source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai" | "lens";
78
78
  category: "db" | "memory" | "visual" | "security" | "ai" | "build" | "lint" | "typecheck" | "test" | "runtime" | "render" | "trace" | "state" | "network" | "backend" | "performance" | "deps" | "cluster";
79
79
  severity: "error" | "debug" | "info" | "warning" | "fatal";
80
80
  title: string;
@@ -0,0 +1,20 @@
1
+ import { type BaseEvent, type ErrorDismissalDraft } from '@lensmcp/protocol-types';
2
+ /**
3
+ * Events the lens writes about itself — today, a dismissed error and its undo — and the one way
4
+ * they reach the bus.
5
+ *
6
+ * Three processes can dismiss: the dashboard (a click), the MCP server (an agent's tool call, or
7
+ * the CLI through it). None of them changes its own memory. Each appends to the bus FILE and hears
8
+ * it back through the ingest that tails the file, like any other producer's event — so every
9
+ * process folds the same thing, in the same order, and a restart replays it.
10
+ */
11
+ /** The bus file a lens process reads and writes: `LENSMCP_EVENT_FILE`, else this workspace's own. */
12
+ export declare function lensEventFile(env?: Record<string, string | undefined>, cwd?: string): string;
13
+ /** Stamped AT `until`: the reader clamps a dismissal to its own timestamp, so the two must agree. */
14
+ export declare function dismissalEvent(draft: ErrorDismissalDraft, sessionId: string): BaseEvent;
15
+ export declare function restoralEvent(groupId: string, sessionId: string, at: number): BaseEvent;
16
+ /**
17
+ * Append events to the bus file. Throws when the write fails: the caller is answering a person or
18
+ * an agent, and "dismissed" must not be a guess.
19
+ */
20
+ export declare function appendBusEvents(eventFile: string, events: readonly BaseEvent[]): void;
@@ -0,0 +1,2 @@
1
+ "use strict";var p=Object.defineProperty;var t=(n,e)=>p(n,"name",{value:e,configurable:!0});var E=Object.defineProperty,r=t((n,e)=>E(n,"name",{value:e,configurable:!0}),"o");import{appendFileSync as m,closeSync as d,mkdirSync as S,openSync as v,renameSync as y,statSync as f,unlinkSync as I}from"node:fs";import{dirname as N,join as _}from"node:path";import{ERROR_DISMISSED as o,ERROR_RESTORED as a,LENS_EVENT_SOURCE as g}from"@lensmcp/protocol-types";import{rotateBusFile as R}from"./bus-rotation.js";import{ulid as b}from"./ulid.js";export function lensEventFile(n=process.env,e=process.cwd()){return n.LENSMCP_EVENT_FILE??_(e,".lensmcp","events.jsonl")}t(lensEventFile,"lensEventFile"),r(lensEventFile,"lensEventFile");const c=r((n,e,s,i,l)=>({id:b(),sessionId:n,timestamp:e,source:g,category:"runtime",severity:"info",context:{sessionId:n},fingerprint:s,title:i,raw:l}),"lensEvent");export function dismissalEvent(n,e){return c(e,n.until,`${o}:${n.groupId}`,`error dismissed: ${n.title??n.groupId}`,{kind:o,groupId:n.groupId,until:n.until,eventIds:n.eventIds,...n.by?{by:n.by}:{},...n.reason?{reason:n.reason}:{},...n.title?{title:n.title}:{}})}t(dismissalEvent,"dismissalEvent"),r(dismissalEvent,"dismissalEvent");export function restoralEvent(n,e,s){return c(e,s,`${a}:${n}`,"error restored",{kind:a,groupId:n})}t(restoralEvent,"restoralEvent"),r(restoralEvent,"restoralEvent");const u=r((n,e,s)=>{const i=Number(process.env[n]);return Number.isFinite(i)&&s(i)?i:e},"envNumber");export function appendBusEvents(n,e){e.length!==0&&(S(N(n),{recursive:!0}),R(n,{maxBytes:u("LENSMCP_EVENT_MAX_BYTES",50*1024*1024,s=>s>0),maxFiles:u("LENSMCP_EVENT_MAX_FILES",5,s=>s>=1&&s<=20),fs:{statSync:f,renameSync:y,unlinkSync:I,openSync:v,closeSync:d}}),m(n,e.map(s=>JSON.stringify(s)+`
2
+ `).join("")))}t(appendBusEvents,"appendBusEvents"),r(appendBusEvents,"appendBusEvents");
package/lib/redact.d.ts CHANGED
@@ -117,24 +117,4 @@ export declare function clip(value: string, max: number): string;
117
117
  export declare function safeText(value: string | undefined, max?: number): string | undefined;
118
118
  /** Redact then bound — the standard treatment for a captured title. */
119
119
  export declare function safeTitle(value: string): string;
120
- /**
121
- * Scrub credentials out of every string leaf of an arbitrary value.
122
- *
123
- * Needed for `console` arguments, which are the one captured payload that is
124
- * genuinely unstructured — `console.log('auth', { token })` is ordinary
125
- * debugging code, and the whole point of that change is that those payloads
126
- * now reach a transcript. It is also what covers a structured `raw`: the
127
- * gateway's request event carries the URL at `raw.url` AND again at
128
- * `raw.steps[].url`, and walking every string leaf catches BOTH plus whatever
129
- * URL-bearing field a future event type adds — which naming the fields
130
- * one-by-one would not. Bounded on depth and array length so a pathological
131
- * object cannot make redaction the slow part of a page's logging.
132
- *
133
- * Values are returned by reference when nothing changed, so the common case
134
- * (no credential anywhere) allocates nothing.
135
- *
136
- * `maxDepth` defaults to the producer-side limit. The BUS redactor raises it to match the clamp's
137
- * depth, because anything the clamp keeps is something a consumer will see — a credential sitting
138
- * between the two limits survived redaction on every path (issues/codex-security/43).
139
- */
140
120
  export declare function redactDeep(value: unknown, depth?: number, maxDepth?: number): unknown;
package/lib/redact.js CHANGED
@@ -1 +1 @@
1
- "use strict";var f=Object.defineProperty;var n=(e,r)=>f(e,"name",{value:r,configurable:!0});var d=Object.defineProperty,a=n((e,r)=>d(e,"name",{value:r,configurable:!0}),"n");export const REDACTED="REDACTED",MAX_TITLE_CHARS=300,MAX_MESSAGE_CHARS=4096,MAX_URL_CHARS=1024;const g=["token","secret","password","passwd","apikey","credential","assertion","signature"],m=new Set(["key","auth","authorization","jwt","code","sig","pwd","pass","session","sid","bearer","otp","cookie","set-cookie"]),x=/^(?:(?:prompt|completion|total|input|output|cache|cached|cacheread|cachewrite|reasoning|thinking|max|min|remaining|used|billed)tokens|tokens?(?:count|used|limit|remaining))$/;export function isSecretParam(e){const r=e.toLowerCase();if(x.test(r.replace(/[-_.]+/g,"")))return!1;if(g.some(t=>r.includes(t)))return!0;for(const t of r.split(/[-_.]+/))if(t&&m.has(t))return!0;return!1}n(isSecretParam,"isSecretParam"),a(isSecretParam,"isSecretParam");const A=/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@\s]*@/i,$=/([?&#])([^=&#\s]+)=([^&#\s]*)/g;export function redactUrlParams(e){return e&&e.replace(A,`$1${REDACTED}@`).replace($,(r,t,i)=>isSecretParam(i)?`${t}${i}=${REDACTED}`:r)}n(redactUrlParams,"redactUrlParams"),a(redactUrlParams,"redactUrlParams");export function redactUrl(e){return e&&clip(redactUrlParams(e),1024)}n(redactUrl,"redactUrl"),a(redactUrl,"redactUrl");const b=/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]*/g,h=/\b(bearer|basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi,_=/\b(authorization|x-api-key|api-key|cookie|set-cookie|proxy-authorization)\b(\s*[:=]\s*)(["']?)((?:(?:bearer|basic)\s+)?[^\s"',;]{4,})\3/gi;export function redactText(e){return redactUrlParams(e).replace(_,(r,t,i,c)=>`${t}${i}${c}${REDACTED}${c}`).replace(b,REDACTED).replace(h,(r,t)=>`${t} ${REDACTED}`)}n(redactText,"redactText"),a(redactText,"redactText");export function clip(e,r){return e.length<=r?e:`${e.slice(0,r)}\u2026[lensmcp truncated: ${e.length-r} more chars]`}n(clip,"clip"),a(clip,"clip");export function safeText(e,r=4096){if(e!==void 0)return clip(redactText(e),r)}n(safeText,"safeText"),a(safeText,"safeText");export function safeTitle(e){return clip(redactText(e),300)}n(safeTitle,"safeTitle"),a(safeTitle,"safeTitle");const k=6,y=64;export function redactDeep(e,r=0,t=k){if(typeof e=="string")return redactText(e);if(e===null||typeof e!="object"||r>=t)return e;if(Array.isArray(e)){let u=!1;const o=e.map((s,l)=>{if(l>=y)return s;const p=redactDeep(s,r+1,t);return p!==s&&(u=!0),p});return u?o:e}let i=!1;const c={};for(const[u,o]of Object.entries(e)){const s=isSecretParam(u)&&o!==void 0&&o!==null?REDACTED:redactDeep(o,r+1,t);s!==o&&(i=!0),c[u]=s}return i?c:e}n(redactDeep,"redactDeep"),a(redactDeep,"redactDeep");
1
+ "use strict";var f=Object.defineProperty;var n=(e,r)=>f(e,"name",{value:r,configurable:!0});var d=Object.defineProperty,o=n((e,r)=>d(e,"name",{value:r,configurable:!0}),"r");export const REDACTED="REDACTED",MAX_TITLE_CHARS=300,MAX_MESSAGE_CHARS=4096,MAX_URL_CHARS=1024;const g=["token","secret","password","passwd","apikey","credential","assertion","signature"],x=new Set(["key","auth","authorization","jwt","code","sig","pwd","pass","session","sid","bearer","otp","cookie","set-cookie"]),$=/^(?:(?:prompt|completion|total|input|output|cache|cached|cacheread|cachewrite|reasoning|thinking|max|min|remaining|used|billed)tokens|tokens?(?:count|used|limit|remaining))$/;export function isSecretParam(e){const r=e.toLowerCase();if($.test(r.replace(/[-_.]+/g,"")))return!1;if(g.some(t=>r.includes(t)))return!0;for(const t of r.split(/[-_.]+/))if(t&&x.has(t))return!0;return!1}n(isSecretParam,"isSecretParam"),o(isSecretParam,"isSecretParam");const m=/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@\s]*@/i,A=/([?&#])([^=&#\s]+)=([^&#\s]*)/g;export function redactUrlParams(e){return e&&e.replace(m,`$1${REDACTED}@`).replace(A,(r,t,i)=>isSecretParam(i)?`${t}${i}=${REDACTED}`:r)}n(redactUrlParams,"redactUrlParams"),o(redactUrlParams,"redactUrlParams");export function redactUrl(e){return e&&clip(redactUrlParams(e),1024)}n(redactUrl,"redactUrl"),o(redactUrl,"redactUrl");const b=/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]*/g,h=/\b(bearer|basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi,k=/\b(authorization|x-api-key|api-key|cookie|set-cookie|proxy-authorization)\b(\s*[:=]\s*)(["']?)((?:(?:bearer|basic)\s+)?[^\s"',;]{4,})\3/gi;export function redactText(e){return redactUrlParams(e).replace(k,(r,t,i,u)=>`${t}${i}${u}${REDACTED}${u}`).replace(b,REDACTED).replace(h,(r,t)=>`${t} ${REDACTED}`)}n(redactText,"redactText"),o(redactText,"redactText");export function clip(e,r){return e.length<=r?e:`${e.slice(0,r)}\u2026[lensmcp truncated: ${e.length-r} more chars]`}n(clip,"clip"),o(clip,"clip");export function safeText(e,r=4096){if(e!==void 0)return clip(redactText(e),r)}n(safeText,"safeText"),o(safeText,"safeText");export function safeTitle(e){return clip(redactText(e),300)}n(safeTitle,"safeTitle"),o(safeTitle,"safeTitle");const y=6,T=64,_=/^TS\d{1,5}$/,S=o((e,r)=>e==="code"&&typeof r=="string"&&_.test(r),"isDiagnosticCode");export function redactDeep(e,r=0,t=y){if(typeof e=="string")return redactText(e);if(e===null||typeof e!="object"||r>=t)return e;if(Array.isArray(e)){let s=!1;const a=e.map((c,l)=>{if(l>=T)return c;const p=redactDeep(c,r+1,t);return p!==c&&(s=!0),p});return s?a:e}let i=!1;const u={};for(const[s,a]of Object.entries(e)){const c=isSecretParam(s)&&a!==void 0&&a!==null&&!S(s,a)?REDACTED:redactDeep(a,r+1,t);c!==a&&(i=!0),u[s]=c}return i?u:e}n(redactDeep,"redactDeep"),o(redactDeep,"redactDeep");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/core",
3
- "version": "1.23.9",
3
+ "version": "1.23.11",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -22,6 +22,11 @@
22
22
  "import": "./lib/bus-rotation.js",
23
23
  "default": "./lib/bus-rotation.js"
24
24
  },
25
+ "./lens-events": {
26
+ "types": "./lib/lens-events.d.ts",
27
+ "import": "./lib/lens-events.js",
28
+ "default": "./lib/lens-events.js"
29
+ },
25
30
  "./ai-content": {
26
31
  "types": "./lib/ai-content.d.ts",
27
32
  "import": "./lib/ai-content.js",
@@ -29,7 +34,7 @@
29
34
  }
30
35
  },
31
36
  "dependencies": {
32
- "@lensmcp/protocol-types": "1.23.9",
37
+ "@lensmcp/protocol-types": "1.23.11",
33
38
  "tslib": "^2.3.0"
34
39
  },
35
40
  "license": "Apache-2.0",