@lensmcp/node-instrumentation 1.25.37 → 1.25.39

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/lib/tap-ai.js CHANGED
@@ -1 +1 @@
1
- "use strict";var E=Object.defineProperty;var u=(e,t)=>E(e,"name",{value:t,configurable:!0});var R=Object.defineProperty,c=u((e,t)=>R(e,"name",{value:t,configurable:!0}),"c"),x=Object.defineProperty,d=c((e,t)=>x(e,"name",{value:t,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.aiCaptureMode=aiCaptureMode,exports.flushAiTapForTests=flushAiTapForTests,exports.resetAiTapForTests=resetAiTapForTests,exports.tapAi=tapAi;const emit_1=require("./emit"),flow_context_1=require("./flow-context"),ai_providers_1=require("./ai-providers"),ai_store_1=require("./ai-store");function aiCaptureMode(e=process.env){const t=(e.LENSMCP_AI_CAPTURE??"").trim().toLowerCase();return t==="content"?"content":t==="metadata"||t==="1"||t==="true"||t==="on"?"metadata":"off"}u(aiCaptureMode,"aiCaptureMode"),c(aiCaptureMode,"aiCaptureMode"),d(aiCaptureMode,"aiCaptureMode");const MAX_REQUEST_PARSE_BYTES=2*1024*1024,MAX_RESPONSE_PARSE_BYTES=8*1024*1024,MAX_STREAM_BYTES=8*1024*1024,MAX_STREAM_MS=300*1e3,MAX_ENDPOINT_CHARS=256;function locate(e){try{const t=new URL(typeof e=="string"?e:e instanceof URL?e.href:e.url);return{host:t.hostname,port:t.port,pathname:t.pathname}}catch{return}}u(locate,"locate"),c(locate,"locate"),d(locate,"locate");const methodOf=d((e,t)=>{const r=typeof e=="object"&&e!==null&&!(e instanceof URL)?e.method:void 0;return String(t?.method??r??"GET").toUpperCase()},"methodOf"),decode=d(e=>({bytes:e.byteLength,...e.byteLength<=MAX_REQUEST_PARSE_BYTES?{text:Buffer.from(e.buffer,e.byteOffset,e.byteLength).toString("utf8")}:{}}),"decode");function takeRequestBody(e,t){const r=t?.body;if(typeof r=="string")return{text:r,bytes:Buffer.byteLength(r)};if(r instanceof ArrayBuffer)return decode(new Uint8Array(r));if(ArrayBuffer.isView(r))return decode(new Uint8Array(r.buffer,r.byteOffset,r.byteLength));if(typeof Blob<"u"&&r instanceof Blob)return{bytes:r.size,...r.size<=MAX_REQUEST_PARSE_BYTES?{pending:r.text().catch(()=>{})}:{}};if(r==null&&typeof e=="object"&&e!==null&&!(e instanceof URL)){const n=e;if(!n.bodyUsed&&n.body)try{return{pending:n.clone().text().catch(()=>{})}}catch{return{}}}return{}}u(takeRequestBody,"takeRequestBody"),c(takeRequestBody,"takeRequestBody"),d(takeRequestBody,"takeRequestBody");const sum=d(e=>e.reduce((t,r)=>t+r,0),"sum");function parseJson(e){if(e)try{return JSON.parse(e)}catch{return}}u(parseJson,"parseJson"),c(parseJson,"parseJson"),d(parseJson,"parseJson");function headerOf(e,t){try{return e?.headers?.get?.(t)??""}catch{return""}}u(headerOf,"headerOf"),c(headerOf,"headerOf"),d(headerOf,"headerOf");const statusOf=d(e=>typeof e?.status=="number"?e.status:void 0,"statusOf");function failureKind(e,t){const r=e?.name,n=r==="TimeoutError";return{timedOut:n,aborted:!n&&(r==="AbortError"||t?.aborted===!0)}}u(failureKind,"failureKind"),c(failureKind,"failureKind"),d(failureKind,"failureKind");async function readStream(e,t,r){const n=(0,ai_providers_1.createStreamAccumulator)(t);let i,o=!1;const a=e.body;if(a){const f=a.getReader(),s=new TextDecoder;let m=0;try{for(;;){const{done:g,value:y}=await f.read();if(g)break;if(m+=y.byteLength,n.push(s.decode(y,{stream:!0})),i===void 0&&n.eventCount>0&&(i=Date.now()-r),m>MAX_STREAM_BYTES||Date.now()-r>MAX_STREAM_MS){o=!0,await f.cancel().catch(()=>{});break}}}catch{o=!0}}return{response:n.end(),sse:!0,cut:o,...i!==void 0?{firstEventMs:i}:{}}}u(readStream,"readStream"),c(readStream,"readStream"),d(readStream,"readStream");async function readBody(e){const t={completion:"",toolCalls:[],usage:{}};if(!e.res||!e.clone)return{response:t,sse:!1,cut:!1};try{if(headerOf(e.res,"content-type").includes("text/event-stream"))return await readStream(e.clone,e.target,e.startedAt);const r=Number(headerOf(e.res,"content-length"));if(Number.isFinite(r)&&r>MAX_RESPONSE_PARSE_BYTES)return{response:t,sse:!1,cut:!1};const n=await e.clone.text().catch(()=>{});if(n&&/^\s*(?:event|data):/.test(n)){const i=(0,ai_providers_1.createStreamAccumulator)(e.target);return i.push(n),{response:i.end(),sse:!0,cut:!1}}return{response:(0,ai_providers_1.normalizeResponse)(e.target,parseJson(n)),sse:!1,cut:!1}}catch{return{response:t,sse:!1,cut:!1}}}u(readBody,"readBody"),c(readBody,"readBody"),d(readBody,"readBody");async function capture(e){const t=readBody(e),r=e.request.text??await e.request.pending,n=e.request.bytes??(r?Buffer.byteLength(r):void 0),i=n!==void 0&&n>MAX_REQUEST_PARSE_BYTES,o=(0,ai_providers_1.normalizeRequest)(e.target,i?void 0:parseJson(r)),a=statusOf(e.res),f=await t;let s=f.response;const m=o.stream||f.sse,g=f.firstEventMs,y=f.cut,{aborted:v,timedOut:_}=e.failure!==void 0?failureKind(e.failure,e.signal):{aborted:!1,timedOut:!1};e.failure!==void 0&&(s={...s,error:String(e.failure?.message??e.failure)});const A=v||y,T=Date.now()-e.startedAt,l=s.model??o.model,w=sum(o.messages.map(S=>S.content.length))+(o.system?.length??0);let p,h=!1;if(e.mode==="content"&&e.target.api!=="embeddings"){const S={schemaVersion:1,id:(0,ai_store_1.newAiCallId)(),capturedAt:Date.now(),...e.ctx?.flowId?{flowId:e.ctx.flowId}:{},...e.ctx?.requestId?{requestId:e.ctx.requestId}:{},provider:e.target.provider,api:e.target.api,...l?{model:l}:{},host:e.host,endpoint:e.endpoint,stream:m,...a!==void 0?{status:a}:{},request:{...o.system?{system:o.system}:{},messages:o.messages,...o.tools.length?{tools:o.tools}:{},...Object.keys(o.params).length?{params:o.params}:{}},response:{completion:s.completion,...s.reasoning?{reasoning:s.reasoning}:{},...s.toolCalls.length?{toolCalls:s.toolCalls}:{},...s.finishReason?{finishReason:s.finishReason}:{},usage:s.usage,...s.error?{error:s.error}:{}}},M=(0,ai_store_1.writeAiContent)(S);M&&(p=M.id,h=M.truncated)}const b=a!==void 0&&a>=400||e.failure!==void 0&&!v,C=l??"?";(0,emit_1.lensEmit)("ai",e.failure!==void 0&&!v?"error":"info",a!==void 0?`ai ${e.target.provider}/${C} ${e.target.api} \u2192 ${a}`:`ai ${e.target.provider}/${C} ${e.target.api} ${v?"aborted":"failed"}`,{name:e.target.provider,kind:"ai-call",provider:e.target.provider,api:e.target.api,...l?{model:l}:{},...o.model&&l&&o.model!==l?{requestedModel:o.model}:{},host:e.host,endpoint:e.endpoint,method:e.method,...a!==void 0?{status:a}:{},stream:m,startedAt:e.startedAt,durationMs:T,...e.ttfbMs!==void 0?{ttfbMs:e.ttfbMs}:{},...g!==void 0?{firstEventMs:g}:{},...Object.keys(s.usage).length?{usage:s.usage}:{},...s.finishReason?{finishReason:s.finishReason}:{},toolCallCount:s.toolCalls.length,sizes:{messageCount:o.messages.length,toolCount:o.tools.length,promptChars:w,completionChars:s.completion.length,...n!==void 0?{requestBytes:n}:{}},...o.inputCount!==void 0?{inputCount:o.inputCount}:{},...s.vectorCount!==void 0?{vectorCount:s.vectorCount}:{},contentCaptured:p!==void 0,...p?{contentRef:p}:{},...h?{truncated:!0}:{},...A?{aborted:!0}:{},..._?{timedOut:!0}:{},...s.error?{error:(0,ai_store_1.redactAiText)(s.error).slice(0,300)}:{}},b?`ai:error:${e.target.provider}:${C}`:`ai:${e.target.provider}:${C}`,e.ctx,"ai")}u(capture,"capture"),c(capture,"capture"),d(capture,"capture");let savedFetch;const pending=new Set;async function flushAiTapForTests(){await Promise.allSettled([...pending])}u(flushAiTapForTests,"flushAiTapForTests"),c(flushAiTapForTests,"flushAiTapForTests"),d(flushAiTapForTests,"flushAiTapForTests");function resetAiTapForTests(){const e=globalThis;savedFetch&&(e.fetch=savedFetch),delete e.__lensmcpAiTap,savedFetch=void 0,pending.clear()}u(resetAiTapForTests,"resetAiTapForTests"),c(resetAiTapForTests,"resetAiTapForTests"),d(resetAiTapForTests,"resetAiTapForTests");function tapAi(){const e=aiCaptureMode();if(e==="off")return;const t=globalThis;if(typeof t.fetch!="function"||t.__lensmcpAiTap)return;t.__lensmcpAiTap=!0;const r=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS),n=t.fetch.bind(globalThis);savedFetch=t.fetch,t.fetch=(async(i,o)=>{const a=locate(i),f=methodOf(i,o),s=a&&f==="POST"?(0,ai_providers_1.matchTarget)(a.host,a.port,a.pathname,r):void 0;if(!a||!s)return n(i,o);const m=Date.now();(0,flow_context_1.startLiveFlow)();const g=(0,flow_context_1.flowContext)(),y=a.pathname.length>MAX_ENDPOINT_CHARS?`${a.pathname.slice(0,MAX_ENDPOINT_CHARS)}\u2026`:a.pathname,v=takeRequestBody(i,o),_=o?.signal??(typeof i=="object"&&i!==null&&!(i instanceof URL)?i.signal:void 0),A=d(h=>{const b=capture(h).catch(()=>{});pending.add(b),b.finally(()=>pending.delete(b))},"track"),T={mode:e,target:s,host:a.host,endpoint:y,method:f,startedAt:m,ctx:g,signal:_,request:v};let l;try{l=await n(i,o)}catch(h){throw A({...T,failure:h}),h}const w=Date.now()-m;let p;try{p=l.clone()}catch{p=void 0}return A({...T,ttfbMs:w,res:l,...p?{clone:p}:{}}),l})}u(tapAi,"tapAi"),c(tapAi,"tapAi"),d(tapAi,"tapAi");
1
+ "use strict";var R=Object.defineProperty;var c=(t,e)=>R(t,"name",{value:e,configurable:!0});var x=Object.defineProperty,d=c((t,e)=>x(t,"name",{value:e,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.aiCaptureMode=aiCaptureMode,exports.flushAiTapForTests=flushAiTapForTests,exports.resetAiTapForTests=resetAiTapForTests,exports.tapAi=tapAi;const emit_1=require("./emit"),flow_context_1=require("./flow-context"),ai_providers_1=require("./ai-providers"),ai_store_1=require("./ai-store");function aiCaptureMode(t=process.env){const e=(t.LENSMCP_AI_CAPTURE??"").trim().toLowerCase();return e==="content"?"content":e==="metadata"||e==="1"||e==="true"||e==="on"?"metadata":"off"}c(aiCaptureMode,"aiCaptureMode"),d(aiCaptureMode,"aiCaptureMode");const MAX_REQUEST_PARSE_BYTES=2*1024*1024,MAX_RESPONSE_PARSE_BYTES=8*1024*1024,MAX_STREAM_BYTES=8*1024*1024,MAX_STREAM_MS=300*1e3,MAX_ENDPOINT_CHARS=256;function locate(t){try{const e=new URL(typeof t=="string"?t:t instanceof URL?t.href:t.url);return{host:e.hostname,port:e.port,pathname:e.pathname}}catch{return}}c(locate,"locate"),d(locate,"locate");const methodOf=d((t,e)=>{const o=typeof t=="object"&&t!==null&&!(t instanceof URL)?t.method:void 0;return String(e?.method??o??"GET").toUpperCase()},"methodOf"),decode=d(t=>({bytes:t.byteLength,...t.byteLength<=MAX_REQUEST_PARSE_BYTES?{text:Buffer.from(t.buffer,t.byteOffset,t.byteLength).toString("utf8")}:{}}),"decode");function takeRequestBody(t,e){const o=e?.body;if(typeof o=="string")return{text:o,bytes:Buffer.byteLength(o)};if(o instanceof ArrayBuffer)return decode(new Uint8Array(o));if(ArrayBuffer.isView(o))return decode(new Uint8Array(o.buffer,o.byteOffset,o.byteLength));if(typeof Blob<"u"&&o instanceof Blob)return{bytes:o.size,...o.size<=MAX_REQUEST_PARSE_BYTES?{pending:o.text().catch(()=>{})}:{}};if(o==null&&typeof t=="object"&&t!==null&&!(t instanceof URL)){const s=t;if(!s.bodyUsed&&s.body)try{return{pending:s.clone().text().catch(()=>{})}}catch{return{}}}return{}}c(takeRequestBody,"takeRequestBody"),d(takeRequestBody,"takeRequestBody");const sum=d(t=>t.reduce((e,o)=>e+o,0),"sum");function parseJson(t){if(t)try{return JSON.parse(t)}catch{return}}c(parseJson,"parseJson"),d(parseJson,"parseJson");function headerOf(t,e){try{return t?.headers?.get?.(e)??""}catch{return""}}c(headerOf,"headerOf"),d(headerOf,"headerOf");const statusOf=d(t=>typeof t?.status=="number"?t.status:void 0,"statusOf");function failureKind(t,e){const o=t?.name,s=o==="TimeoutError";return{timedOut:s,aborted:!s&&(o==="AbortError"||e?.aborted===!0)}}c(failureKind,"failureKind"),d(failureKind,"failureKind");async function readStream(t,e,o){const s=(0,ai_providers_1.createStreamAccumulator)(e);let i,r=!1;const a=t.body;if(a){const l=a.getReader(),n=new TextDecoder;let p=0;try{for(;;){const{done:m,value:g}=await l.read();if(m)break;if(p+=g.byteLength,s.push(n.decode(g,{stream:!0})),i===void 0&&s.eventCount>0&&(i=Date.now()-o),p>MAX_STREAM_BYTES||Date.now()-o>MAX_STREAM_MS){r=!0,await l.cancel().catch(()=>{});break}}}catch{r=!0}}return{response:s.end(),sse:!0,cut:r,...i!==void 0?{firstEventMs:i}:{}}}c(readStream,"readStream"),d(readStream,"readStream");async function readBody(t){const e={completion:"",toolCalls:[],usage:{}};if(!t.res||!t.clone)return{response:e,sse:!1,cut:!1};try{if(headerOf(t.res,"content-type").includes("text/event-stream"))return await readStream(t.clone,t.target,t.startedAt);const o=Number(headerOf(t.res,"content-length"));if(Number.isFinite(o)&&o>MAX_RESPONSE_PARSE_BYTES)return{response:e,sse:!1,cut:!1};const s=await t.clone.text().catch(()=>{});if(s&&/^\s*(?:event|data):/.test(s)){const i=(0,ai_providers_1.createStreamAccumulator)(t.target);return i.push(s),{response:i.end(),sse:!0,cut:!1}}return{response:(0,ai_providers_1.normalizeResponse)(t.target,parseJson(s)),sse:!1,cut:!1}}catch{return{response:e,sse:!1,cut:!1}}}c(readBody,"readBody"),d(readBody,"readBody");async function capture(t){const e=readBody(t),o=t.request.text??await t.request.pending,s=t.request.bytes??(o?Buffer.byteLength(o):void 0),i=s!==void 0&&s>MAX_REQUEST_PARSE_BYTES,r=(0,ai_providers_1.normalizeRequest)(t.target,i?void 0:parseJson(o)),a=statusOf(t.res),l=await e;let n=l.response;const p=r.stream||l.sse,m=l.firstEventMs,g=l.cut,{aborted:y,timedOut:C}=t.failure!==void 0?failureKind(t.failure,t.signal):{aborted:!1,timedOut:!1};t.failure!==void 0&&(n={...n,error:String(t.failure?.message??t.failure)});const b=y||g,A=Date.now()-t.startedAt,u=n.model??r.model,_=sum(r.messages.map(w=>w.content.length))+(r.system?.length??0);let f,h=!1;if(t.mode==="content"&&t.target.api!=="embeddings"){const w={schemaVersion:1,id:(0,ai_store_1.newAiCallId)(),capturedAt:Date.now(),...t.ctx?.flowId?{flowId:t.ctx.flowId}:{},...t.ctx?.requestId?{requestId:t.ctx.requestId}:{},provider:t.target.provider,api:t.target.api,...u?{model:u}:{},host:t.host,endpoint:t.endpoint,stream:p,...a!==void 0?{status:a}:{},request:{...r.system?{system:r.system}:{},messages:r.messages,...r.tools.length?{tools:r.tools}:{},...Object.keys(r.params).length?{params:r.params}:{}},response:{completion:n.completion,...n.reasoning?{reasoning:n.reasoning}:{},...n.toolCalls.length?{toolCalls:n.toolCalls}:{},...n.finishReason?{finishReason:n.finishReason}:{},usage:n.usage,...n.error?{error:n.error}:{}}},S=(0,ai_store_1.writeAiContent)(w);S&&(f=S.id,h=S.truncated)}const v=a!==void 0&&a>=400||t.failure!==void 0&&!y,T=u??"?";(0,emit_1.lensEmit)("ai",t.failure!==void 0&&!y?"error":"info",a!==void 0?`ai ${t.target.provider}/${T} ${t.target.api} \u2192 ${a}`:`ai ${t.target.provider}/${T} ${t.target.api} ${y?"aborted":"failed"}`,{name:t.target.provider,kind:"ai-call",provider:t.target.provider,api:t.target.api,...u?{model:u}:{},...r.model&&u&&r.model!==u?{requestedModel:r.model}:{},host:t.host,endpoint:t.endpoint,method:t.method,...a!==void 0?{status:a}:{},stream:p,startedAt:t.startedAt,durationMs:A,...t.ttfbMs!==void 0?{ttfbMs:t.ttfbMs}:{},...m!==void 0?{firstEventMs:m}:{},...Object.keys(n.usage).length?{usage:n.usage}:{},...n.finishReason?{finishReason:n.finishReason}:{},toolCallCount:n.toolCalls.length,sizes:{messageCount:r.messages.length,toolCount:r.tools.length,promptChars:_,completionChars:n.completion.length,...s!==void 0?{requestBytes:s}:{}},...r.inputCount!==void 0?{inputCount:r.inputCount}:{},...n.vectorCount!==void 0?{vectorCount:n.vectorCount}:{},contentCaptured:f!==void 0,...f?{contentRef:f}:{},...h?{truncated:!0}:{},...b?{aborted:!0}:{},...C?{timedOut:!0}:{},...n.error?{error:(0,ai_store_1.redactAiText)(n.error).slice(0,300)}:{}},v?`ai:error:${t.target.provider}:${T}`:`ai:${t.target.provider}:${T}`,t.ctx,"ai")}c(capture,"capture"),d(capture,"capture");let savedFetch;const pending=new Set;async function flushAiTapForTests(){await Promise.allSettled([...pending])}c(flushAiTapForTests,"flushAiTapForTests"),d(flushAiTapForTests,"flushAiTapForTests");function resetAiTapForTests(){const t=globalThis;savedFetch&&(t.fetch=savedFetch),delete t.__lensmcpAiTap,savedFetch=void 0,pending.clear()}c(resetAiTapForTests,"resetAiTapForTests"),d(resetAiTapForTests,"resetAiTapForTests");function tapAi(){const t=aiCaptureMode();if(t==="off")return;const e=globalThis;if(typeof e.fetch!="function"||e.__lensmcpAiTap)return;e.__lensmcpAiTap=!0;const o=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS),s=e.fetch.bind(globalThis);savedFetch=e.fetch,e.fetch=(async(i,r)=>{const a=locate(i),l=methodOf(i,r),n=a&&l==="POST"?(0,ai_providers_1.matchTarget)(a.host,a.port,a.pathname,o):void 0;if(!a||!n)return s(i,r);const p=Date.now();(0,flow_context_1.startLiveFlow)();const m=(0,flow_context_1.flowContext)(),g=a.pathname.length>MAX_ENDPOINT_CHARS?`${a.pathname.slice(0,MAX_ENDPOINT_CHARS)}\u2026`:a.pathname,y=takeRequestBody(i,r),C=r?.signal??(typeof i=="object"&&i!==null&&!(i instanceof URL)?i.signal:void 0),b=d(h=>{const v=capture(h).catch(()=>{});pending.add(v),v.finally(()=>pending.delete(v))},"track"),A={mode:t,target:n,host:a.host,endpoint:g,method:l,startedAt:p,ctx:m,signal:C,request:y};let u;try{u=await s(i,r)}catch(h){throw b({...A,failure:h}),h}const _=Date.now()-p;let f;try{f=u.clone()}catch{f=void 0}return b({...A,ttfbMs:_,res:u,...f?{clone:f}:{}}),u})}c(tapAi,"tapAi"),d(tapAi,"tapAi");
package/lib/tap-bullmq.js CHANGED
@@ -1 +1 @@
1
- "use strict";var y=Object.defineProperty;var f=(t,e)=>y(t,"name",{value:e,configurable:!0});var b=Object.defineProperty,a=f((t,e)=>b(t,"name",{value:e,configurable:!0}),"a"),g=Object.defineProperty,i=a((t,e)=>g(t,"name",{value:e,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.bullmqTap=bullmqTap,exports.stopWorkIntake=stopWorkIntake,exports.workIntakeReport=workIntakeReport,exports.resetQueueStatePublishersForTests=resetQueueStatePublishersForTests,exports.resetWorkIntakeForTests=resetWorkIntakeForTests;const active_work_1=require("./active-work"),workerGeneration=new WeakMap,headless_flow_1=require("@lensmcp/core/headless-flow"),emit_1=require("./emit"),flow_context_1=require("./flow-context");function jobFlow(t){const e=t?.opts?.__lensmcpFlow;return e&&typeof e=="object"?e:void 0}f(jobFlow,"jobFlow"),a(jobFlow,"jobFlow"),i(jobFlow,"jobFlow");const jobLegId=i((t,e)=>`job:${t}#${e?.id??"?"}`,"jobLegId");function flowOfJob(t,e){const o=jobFlow(e)?.flowId;if(o)return{flowId:o,own:!1};if((0,headless_flow_1.headlessFlowsEnabled)())return{flowId:(0,headless_flow_1.headlessJobFlowId)(t,e?.id),own:!0}}f(flowOfJob,"flowOfJob"),a(flowOfJob,"flowOfJob"),i(flowOfJob,"flowOfJob");const publishers=new Map,sources=new Map,sourceFor=i(t=>{let e=sources.get(t);return e||sources.set(t,e={}),e},"sourceFor"),usable=i(t=>!!t&&t.closing===void 0,"usable"),currentQueue=i(t=>{const e=sources.get(t),o=e?.app?.deref();return usable(o)?o:e?.own},"currentQueue");function ownConnection(t){if(!t||typeof t!="object")return;const e=t;if(typeof e.duplicate=="function")try{return e.duplicate()}catch{return}return Object.fromEntries(Object.entries(e).filter(([,o])=>typeof o!="function"))}f(ownConnection,"ownConnection"),a(ownConnection,"ownConnection"),i(ownConnection,"ownConnection");function bullmqTap(t){const e=t;if(typeof e?.Queue!="function"||typeof e?.Worker!="function")return!1;tappedQueue=e.Queue;try{tapQueueAdd(e)}catch{}try{tapWorkerEmit(e)}catch{}try{tapWorkerProcess(e)}catch{}try{tapWorkerStamp(e)}catch{}try{tapWorkerIntake(e)}catch{}try{tapWorkerConstruct(e)}catch{}try{installWorkIntakeControl()}catch{}return!0}f(bullmqTap,"bullmqTap"),a(bullmqTap,"bullmqTap"),i(bullmqTap,"bullmqTap");function stampWorker(t){try{if(workerGeneration.has(t))return;workerGeneration.set(t,(0,active_work_1.activeWorkGeneration)()),knownWorkers.add(new WeakRef(t))}catch{}}f(stampWorker,"stampWorker"),a(stampWorker,"stampWorker"),i(stampWorker,"stampWorker");function tapWorkerConstruct(t){const e=t.Worker;if(typeof e!="function"||e.__lensmcpGen)return;const o=new Proxy(e,{construct(r,n,s){const p=Reflect.construct(r,n,s);return stampWorker(p),p}});Object.defineProperty(e,"__lensmcpGen",{value:!0,enumerable:!1}),t.Worker=o}f(tapWorkerConstruct,"tapWorkerConstruct"),a(tapWorkerConstruct,"tapWorkerConstruct"),i(tapWorkerConstruct,"tapWorkerConstruct");function tapWorkerStamp(t){const e=t.Worker?.prototype;if(e)for(const o of["createLockManager","run"]){const r=e[o];if(typeof r!="function"||r.__lensmcpStamp)continue;const n=i(function(...s){return stampWorker(this),r.apply(this,s)},"wrapped");n.__lensmcpStamp=!0,e[o]=n}}f(tapWorkerStamp,"tapWorkerStamp"),a(tapWorkerStamp,"tapWorkerStamp"),i(tapWorkerStamp,"tapWorkerStamp");const knownWorkers=new Set,stoppedWorkers=new WeakSet,intake=new Map,INTAKE_GENERATIONS_KEPT=64;function intakeOf(t){let e=intake.get(t);if(!e){intake.set(t,e={workers:0,running:0,runningAtStop:0,takenAfterStop:0,finishedAfterStop:0});for(const o of intake.keys()){if(intake.size<=INTAKE_GENERATIONS_KEPT)break;intake.delete(o)}}return e}f(intakeOf,"intakeOf"),a(intakeOf,"intakeOf"),i(intakeOf,"intakeOf");function beginIntake(t,e){if(e===void 0)return()=>{};const o=intakeOf(e);return o.running+=1,stoppedWorkers.has(t)&&(o.takenAfterStop+=1),()=>{o.running-=1,o.stoppedAt!==void 0&&(o.finishedAfterStop+=1)}}f(beginIntake,"beginIntake"),a(beginIntake,"beginIntake"),i(beginIntake,"beginIntake");function stopWorkIntake(t){const e={workers:0,running:0,runningAtStop:0,takenAfterStop:0,finishedAfterStop:0},o=Date.now();for(const r of knownWorkers){const n=r.deref();if(!n){knownWorkers.delete(r);continue}const s=workerGeneration.get(n);if(s===void 0||s>=t||stoppedWorkers.has(n))continue;const p=n.pause;if(typeof p!="function")continue;stoppedWorkers.add(n),knownWorkers.delete(r);try{Promise.resolve(p.call(n,!0)).catch(()=>{})}catch{}const u=intakeOf(s);u.stoppedAt===void 0&&(u.stoppedAt=o,u.runningAtStop=u.running,e.running+=u.running,e.runningAtStop+=u.running),u.workers+=1,e.workers+=1}return e}f(stopWorkIntake,"stopWorkIntake"),a(stopWorkIntake,"stopWorkIntake"),i(stopWorkIntake,"stopWorkIntake");function workIntakeReport(t){const e=intake.get(t);if(!(!e||e.stoppedAt===void 0))return{workers:e.workers,running:e.running,runningAtStop:e.runningAtStop,takenAfterStop:e.takenAfterStop,finishedAfterStop:e.finishedAfterStop}}f(workIntakeReport,"workIntakeReport"),a(workIntakeReport,"workIntakeReport"),i(workIntakeReport,"workIntakeReport");function tapWorkerIntake(t){const e=t.Worker?.prototype;if(!e)return;const o=e.moveToActive;if(typeof o=="function"&&!o.__lensmcpIntake){const n=i(function(...s){return stoppedWorkers.has(this)?Promise.resolve(void 0):o.apply(this,s)},"wrapped");n.__lensmcpIntake=!0,e.moveToActive=n}const r=e.resume;if(typeof r=="function"&&!r.__lensmcpIntake){const n=i(function(...s){if(!stoppedWorkers.has(this))return r.apply(this,s)},"wrapped");n.__lensmcpIntake=!0,e.resume=n}}f(tapWorkerIntake,"tapWorkerIntake"),a(tapWorkerIntake,"tapWorkerIntake"),i(tapWorkerIntake,"tapWorkerIntake");function installWorkIntakeControl(){const t=globalThis;t.__lensmcpStopWorkIntake=stopWorkIntake,t.__lensmcpWorkIntakeReport=workIntakeReport}f(installWorkIntakeControl,"installWorkIntakeControl"),a(installWorkIntakeControl,"installWorkIntakeControl"),i(installWorkIntakeControl,"installWorkIntakeControl");function tapWorkerProcess(t){const e=t.Worker?.prototype,o=e?.callProcessJob;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(async function(n,...s){const p=workerGeneration.get(this),u=(0,active_work_1.beginActiveWork)(p),l=beginIntake(this,p),c=i(()=>{u(),l()},"endWork"),d=String(this?.name??n?.queueName??"queue"),w=flowOfJob(d,n);if(!w)return o.call(this,n,...s).finally(c);const h=jobLegId(d,n),k=Date.now(),I={flowId:w.flowId,requestId:h};if(w.own){const m=`job:${d}/${n?.name??"job"}`;(0,emit_1.lensEmit)("queue","info",`job ${n?.name??""}#${n?.id??"?"} \xB7 ${d}`,{queue:d,kind:"flow-origin",job:n?.name,jobId:n?.id,originNodeId:m},`queue-origin:${d}`,{...I,originType:"job",originNodeId:m})}return(0,flow_context_1.runInFlowContext)(I,async()=>{try{const m=await o.call(this,n,...s);return(0,emit_1.lensEmit)("queue","info",`process ${n?.name}#${n?.id} (${Date.now()-k}ms)`,{queue:d,kind:"queue-process",job:n?.name,jobId:n?.id,startedAt:k,durationMs:Date.now()-k,status:"ok"},`queue:${d}`,I),m}catch(m){throw(0,emit_1.lensEmit)("queue","error",`process ${n?.name}#${n?.id} failed (${Date.now()-k}ms)`,{queue:d,kind:"queue-process",job:n?.name,jobId:n?.id,startedAt:k,durationMs:Date.now()-k,status:"error",error:String(m?.message??m)},`queue:${d}`,I),m}finally{c()}})},"wrapped");r.__lensmcp=!0,e.callProcessJob=r}f(tapWorkerProcess,"tapWorkerProcess"),a(tapWorkerProcess,"tapWorkerProcess"),i(tapWorkerProcess,"tapWorkerProcess");function tapQueueAdd(t){const e=t.Queue?.prototype,o=e?.add;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(async function(n,...s){const p=Date.now(),u=(0,flow_context_1.flowContext)();if(u?.flowId){const c=s[1]??{};s[1]={...c,__lensmcpFlow:{flowId:u.flowId,...u.requestId?{originRequestId:u.requestId}:{}}}}const l=await o.call(this,n,...s);try{const c=String(this?.name??"queue"),d=s[0];let w;try{const k=JSON.stringify(d);w=k&&k!=="undefined"?k.length>300?k.slice(0,299)+"\u2026":k:void 0}catch{}(0,emit_1.lensEmit)("queue","info",`enqueued ${n}#${l?.id} \u2192 ${c}`,{queue:c,kind:"queue-enqueued",job:n,jobId:l?.id,...w?{data:w}:{},startedAt:p,durationMs:Date.now()-p},`queue:${c}`,u);const h=sourceFor(c);h.app?.deref()!==this&&(h.app=new WeakRef(this)),ensureStatePublisher(c)}catch{}return l},"wrapped");r.__lensmcp=!0,e.add=r}f(tapQueueAdd,"tapQueueAdd"),a(tapQueueAdd,"tapQueueAdd"),i(tapQueueAdd,"tapQueueAdd");function tapWorkerEmit(t){const e=t.Worker?.prototype,o=e?.emit;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(function(n,...s){try{observeWorkerEvent(this,String(n),s)}catch{}return o.call(this,n,...s)},"wrapped");r.__lensmcp=!0,e.emit=r}f(tapWorkerEmit,"tapWorkerEmit"),a(tapWorkerEmit,"tapWorkerEmit"),i(tapWorkerEmit,"tapWorkerEmit");function observeWorkerEvent(t,e,o){if(e!=="active"&&e!=="completed"&&e!=="failed")return;const r=String(t.name??"queue"),n=o[0],s=flowOfJob(r,n),p=s?{flowId:s.flowId,requestId:jobLegId(r,n)}:void 0;if(e==="active")(0,emit_1.lensEmit)("queue","info",`processing ${n?.name}#${n?.id}`,{queue:r,kind:"queue-active",jobId:n?.id},`queue:${r}`,p);else if(e==="completed"){let u;try{const l=n?.returnvalue??o[1],c=JSON.stringify(l);u=c&&c!=="undefined"?c.length>160?c.slice(0,159)+"\u2026":c:void 0}catch{}(0,emit_1.lensEmit)("queue","info",`completed ${n?.name}#${n?.id}`,{queue:r,kind:"queue-completed",jobId:n?.id,...u?{returned:u}:{}},`queue:${r}`,p)}else{const u=o[1];(0,emit_1.lensEmit)("queue","error",`job ${n?.id} failed: ${u?.message}`,{queue:r,kind:"queue-failed",jobId:n?.id,error:String(u?.message??u)},`queue:${r}`,p)}if(!currentQueue(r))try{const u=t.opts,l=ownConnection(u?.connection);if(l){const c=snapshotQueueClass();c&&(sourceFor(r).own=new c(r,{connection:l}))}}catch{}ensureStatePublisher(r)}f(observeWorkerEvent,"observeWorkerEvent"),a(observeWorkerEvent,"observeWorkerEvent"),i(observeWorkerEvent,"observeWorkerEvent");let tappedQueue;function snapshotQueueClass(){if(tappedQueue)return tappedQueue;try{return require("bullmq").Queue}catch{return}}f(snapshotQueueClass,"snapshotQueueClass"),a(snapshotQueueClass,"snapshotQueueClass"),i(snapshotQueueClass,"snapshotQueueClass");function ensureStatePublisher(t){if(publishers.has(t))return;let e="";const o=setInterval(()=>{(async()=>{try{const r=currentQueue(t);if(!r)return;const n=await r.getJobCounts(),s=[];for(const l of["active","waiting","failed","completed","delayed"])for(const c of await r.getJobs([l],0,7)){const d=c?.data?.to;s.push({id:String(c.id),name:c.name,state:l,timestamp:c.timestamp??0,...typeof d=="string"?{to:d}:{}})}s.sort((l,c)=>Number(c.timestamp)-Number(l.timestamp));const p=s.slice(0,8),u=JSON.stringify([n,p.map(l=>`${l.id}${l.state}`)]);if(u===e)return;e=u,(0,emit_1.lensEmit)("queue","info",`queue state: ${n.active??0} active \xB7 ${n.waiting??0} waiting \xB7 ${n.failed??0} failed`,{queue:t,kind:"queue-state",counts:n,recent:p},`queue:${t}`)}catch{}})()},2e3);o.unref?.(),publishers.set(t,o)}f(ensureStatePublisher,"ensureStatePublisher"),a(ensureStatePublisher,"ensureStatePublisher"),i(ensureStatePublisher,"ensureStatePublisher");function resetQueueStatePublishersForTests(){for(const t of publishers.values())clearInterval(t);publishers.clear(),sources.clear()}f(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests"),a(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests"),i(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests");function resetWorkIntakeForTests(){knownWorkers.clear(),intake.clear()}f(resetWorkIntakeForTests,"resetWorkIntakeForTests"),a(resetWorkIntakeForTests,"resetWorkIntakeForTests"),i(resetWorkIntakeForTests,"resetWorkIntakeForTests");
1
+ "use strict";var b=Object.defineProperty;var a=(t,e)=>b(t,"name",{value:e,configurable:!0});var g=Object.defineProperty,i=a((t,e)=>g(t,"name",{value:e,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.bullmqTap=bullmqTap,exports.stopWorkIntake=stopWorkIntake,exports.workIntakeReport=workIntakeReport,exports.resetQueueStatePublishersForTests=resetQueueStatePublishersForTests,exports.resetWorkIntakeForTests=resetWorkIntakeForTests;const active_work_1=require("./active-work"),workerGeneration=new WeakMap,headless_flow_1=require("@lensmcp/core/headless-flow"),emit_1=require("./emit"),flow_context_1=require("./flow-context");function jobFlow(t){const e=t?.opts?.__lensmcpFlow;return e&&typeof e=="object"?e:void 0}a(jobFlow,"jobFlow"),i(jobFlow,"jobFlow");const jobLegId=i((t,e)=>`job:${t}#${e?.id??"?"}`,"jobLegId");function flowOfJob(t,e){const o=jobFlow(e)?.flowId;if(o)return{flowId:o,own:!1};if((0,headless_flow_1.headlessFlowsEnabled)())return{flowId:(0,headless_flow_1.headlessJobFlowId)(t,e?.id),own:!0}}a(flowOfJob,"flowOfJob"),i(flowOfJob,"flowOfJob");const publishers=new Map,sources=new Map,sourceFor=i(t=>{let e=sources.get(t);return e||sources.set(t,e={}),e},"sourceFor"),usable=i(t=>!!t&&t.closing===void 0,"usable"),currentQueue=i(t=>{const e=sources.get(t),o=e?.app?.deref();return usable(o)?o:e?.own},"currentQueue");function ownConnection(t){if(!t||typeof t!="object")return;const e=t;if(typeof e.duplicate=="function")try{return e.duplicate()}catch{return}return Object.fromEntries(Object.entries(e).filter(([,o])=>typeof o!="function"))}a(ownConnection,"ownConnection"),i(ownConnection,"ownConnection");function bullmqTap(t){const e=t;if(typeof e?.Queue!="function"||typeof e?.Worker!="function")return!1;tappedQueue=e.Queue;try{tapQueueAdd(e)}catch{}try{tapWorkerEmit(e)}catch{}try{tapWorkerProcess(e)}catch{}try{tapWorkerStamp(e)}catch{}try{tapWorkerIntake(e)}catch{}try{tapWorkerConstruct(e)}catch{}try{installWorkIntakeControl()}catch{}return!0}a(bullmqTap,"bullmqTap"),i(bullmqTap,"bullmqTap");function stampWorker(t){try{if(workerGeneration.has(t))return;workerGeneration.set(t,(0,active_work_1.activeWorkGeneration)()),knownWorkers.add(new WeakRef(t))}catch{}}a(stampWorker,"stampWorker"),i(stampWorker,"stampWorker");function tapWorkerConstruct(t){const e=t.Worker;if(typeof e!="function"||e.__lensmcpGen)return;const o=new Proxy(e,{construct(r,n,s){const f=Reflect.construct(r,n,s);return stampWorker(f),f}});Object.defineProperty(e,"__lensmcpGen",{value:!0,enumerable:!1}),t.Worker=o}a(tapWorkerConstruct,"tapWorkerConstruct"),i(tapWorkerConstruct,"tapWorkerConstruct");function tapWorkerStamp(t){const e=t.Worker?.prototype;if(e)for(const o of["createLockManager","run"]){const r=e[o];if(typeof r!="function"||r.__lensmcpStamp)continue;const n=i(function(...s){return stampWorker(this),r.apply(this,s)},"wrapped");n.__lensmcpStamp=!0,e[o]=n}}a(tapWorkerStamp,"tapWorkerStamp"),i(tapWorkerStamp,"tapWorkerStamp");const knownWorkers=new Set,stoppedWorkers=new WeakSet,intake=new Map,INTAKE_GENERATIONS_KEPT=64;function intakeOf(t){let e=intake.get(t);if(!e){intake.set(t,e={workers:0,running:0,runningAtStop:0,takenAfterStop:0,finishedAfterStop:0});for(const o of intake.keys()){if(intake.size<=INTAKE_GENERATIONS_KEPT)break;intake.delete(o)}}return e}a(intakeOf,"intakeOf"),i(intakeOf,"intakeOf");function beginIntake(t,e){if(e===void 0)return()=>{};const o=intakeOf(e);return o.running+=1,stoppedWorkers.has(t)&&(o.takenAfterStop+=1),()=>{o.running-=1,o.stoppedAt!==void 0&&(o.finishedAfterStop+=1)}}a(beginIntake,"beginIntake"),i(beginIntake,"beginIntake");function stopWorkIntake(t){const e={workers:0,running:0,runningAtStop:0,takenAfterStop:0,finishedAfterStop:0},o=Date.now();for(const r of knownWorkers){const n=r.deref();if(!n){knownWorkers.delete(r);continue}const s=workerGeneration.get(n);if(s===void 0||s>=t||stoppedWorkers.has(n))continue;const f=n.pause;if(typeof f!="function")continue;stoppedWorkers.add(n),knownWorkers.delete(r);try{Promise.resolve(f.call(n,!0)).catch(()=>{})}catch{}const u=intakeOf(s);u.stoppedAt===void 0&&(u.stoppedAt=o,u.runningAtStop=u.running,e.running+=u.running,e.runningAtStop+=u.running),u.workers+=1,e.workers+=1}return e}a(stopWorkIntake,"stopWorkIntake"),i(stopWorkIntake,"stopWorkIntake");function workIntakeReport(t){const e=intake.get(t);if(!(!e||e.stoppedAt===void 0))return{workers:e.workers,running:e.running,runningAtStop:e.runningAtStop,takenAfterStop:e.takenAfterStop,finishedAfterStop:e.finishedAfterStop}}a(workIntakeReport,"workIntakeReport"),i(workIntakeReport,"workIntakeReport");function tapWorkerIntake(t){const e=t.Worker?.prototype;if(!e)return;const o=e.moveToActive;if(typeof o=="function"&&!o.__lensmcpIntake){const n=i(function(...s){return stoppedWorkers.has(this)?Promise.resolve(void 0):o.apply(this,s)},"wrapped");n.__lensmcpIntake=!0,e.moveToActive=n}const r=e.resume;if(typeof r=="function"&&!r.__lensmcpIntake){const n=i(function(...s){if(!stoppedWorkers.has(this))return r.apply(this,s)},"wrapped");n.__lensmcpIntake=!0,e.resume=n}}a(tapWorkerIntake,"tapWorkerIntake"),i(tapWorkerIntake,"tapWorkerIntake");function installWorkIntakeControl(){const t=globalThis;t.__lensmcpStopWorkIntake=stopWorkIntake,t.__lensmcpWorkIntakeReport=workIntakeReport}a(installWorkIntakeControl,"installWorkIntakeControl"),i(installWorkIntakeControl,"installWorkIntakeControl");function tapWorkerProcess(t){const e=t.Worker?.prototype,o=e?.callProcessJob;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(async function(n,...s){const f=workerGeneration.get(this),u=(0,active_work_1.beginActiveWork)(f),p=beginIntake(this,f),c=i(()=>{u(),p()},"endWork"),l=String(this?.name??n?.queueName??"queue"),m=flowOfJob(l,n);if(!m)return o.call(this,n,...s).finally(c);const w=jobLegId(l,n),d=Date.now(),h={flowId:m.flowId,requestId:w};if(m.own){const k=`job:${l}/${n?.name??"job"}`;(0,emit_1.lensEmit)("queue","info",`job ${n?.name??""}#${n?.id??"?"} \xB7 ${l}`,{queue:l,kind:"flow-origin",job:n?.name,jobId:n?.id,originNodeId:k},`queue-origin:${l}`,{...h,originType:"job",originNodeId:k})}return(0,flow_context_1.runInFlowContext)(h,async()=>{try{const k=await o.call(this,n,...s);return(0,emit_1.lensEmit)("queue","info",`process ${n?.name}#${n?.id} (${Date.now()-d}ms)`,{queue:l,kind:"queue-process",job:n?.name,jobId:n?.id,startedAt:d,durationMs:Date.now()-d,status:"ok"},`queue:${l}`,h),k}catch(k){throw(0,emit_1.lensEmit)("queue","error",`process ${n?.name}#${n?.id} failed (${Date.now()-d}ms)`,{queue:l,kind:"queue-process",job:n?.name,jobId:n?.id,startedAt:d,durationMs:Date.now()-d,status:"error",error:String(k?.message??k)},`queue:${l}`,h),k}finally{c()}})},"wrapped");r.__lensmcp=!0,e.callProcessJob=r}a(tapWorkerProcess,"tapWorkerProcess"),i(tapWorkerProcess,"tapWorkerProcess");function tapQueueAdd(t){const e=t.Queue?.prototype,o=e?.add;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(async function(n,...s){const f=Date.now(),u=(0,flow_context_1.flowContext)();if(u?.flowId){const c=s[1]??{};s[1]={...c,__lensmcpFlow:{flowId:u.flowId,...u.requestId?{originRequestId:u.requestId}:{}}}}const p=await o.call(this,n,...s);try{const c=String(this?.name??"queue"),l=s[0];let m;try{const d=JSON.stringify(l);m=d&&d!=="undefined"?d.length>300?d.slice(0,299)+"\u2026":d:void 0}catch{}(0,emit_1.lensEmit)("queue","info",`enqueued ${n}#${p?.id} \u2192 ${c}`,{queue:c,kind:"queue-enqueued",job:n,jobId:p?.id,...m?{data:m}:{},startedAt:f,durationMs:Date.now()-f},`queue:${c}`,u);const w=sourceFor(c);w.app?.deref()!==this&&(w.app=new WeakRef(this)),ensureStatePublisher(c)}catch{}return p},"wrapped");r.__lensmcp=!0,e.add=r}a(tapQueueAdd,"tapQueueAdd"),i(tapQueueAdd,"tapQueueAdd");function tapWorkerEmit(t){const e=t.Worker?.prototype,o=e?.emit;if(!e||typeof o!="function"||o.__lensmcp)return;const r=i(function(n,...s){try{observeWorkerEvent(this,String(n),s)}catch{}return o.call(this,n,...s)},"wrapped");r.__lensmcp=!0,e.emit=r}a(tapWorkerEmit,"tapWorkerEmit"),i(tapWorkerEmit,"tapWorkerEmit");function observeWorkerEvent(t,e,o){if(e!=="active"&&e!=="completed"&&e!=="failed")return;const r=String(t.name??"queue"),n=o[0],s=flowOfJob(r,n),f=s?{flowId:s.flowId,requestId:jobLegId(r,n)}:void 0;if(e==="active")(0,emit_1.lensEmit)("queue","info",`processing ${n?.name}#${n?.id}`,{queue:r,kind:"queue-active",jobId:n?.id},`queue:${r}`,f);else if(e==="completed"){let u;try{const p=n?.returnvalue??o[1],c=JSON.stringify(p);u=c&&c!=="undefined"?c.length>160?c.slice(0,159)+"\u2026":c:void 0}catch{}(0,emit_1.lensEmit)("queue","info",`completed ${n?.name}#${n?.id}`,{queue:r,kind:"queue-completed",jobId:n?.id,...u?{returned:u}:{}},`queue:${r}`,f)}else{const u=o[1];(0,emit_1.lensEmit)("queue","error",`job ${n?.id} failed: ${u?.message}`,{queue:r,kind:"queue-failed",jobId:n?.id,error:String(u?.message??u)},`queue:${r}`,f)}if(!currentQueue(r))try{const u=t.opts,p=ownConnection(u?.connection);if(p){const c=snapshotQueueClass();c&&(sourceFor(r).own=new c(r,{connection:p}))}}catch{}ensureStatePublisher(r)}a(observeWorkerEvent,"observeWorkerEvent"),i(observeWorkerEvent,"observeWorkerEvent");let tappedQueue;function snapshotQueueClass(){if(tappedQueue)return tappedQueue;try{return require("bullmq").Queue}catch{return}}a(snapshotQueueClass,"snapshotQueueClass"),i(snapshotQueueClass,"snapshotQueueClass");function ensureStatePublisher(t){if(publishers.has(t))return;let e="";const o=setInterval(()=>{(async()=>{try{const r=currentQueue(t);if(!r)return;const n=await r.getJobCounts(),s=[];for(const p of["active","waiting","failed","completed","delayed"])for(const c of await r.getJobs([p],0,7)){const l=c?.data?.to;s.push({id:String(c.id),name:c.name,state:p,timestamp:c.timestamp??0,...typeof l=="string"?{to:l}:{}})}s.sort((p,c)=>Number(c.timestamp)-Number(p.timestamp));const f=s.slice(0,8),u=JSON.stringify([n,f.map(p=>`${p.id}${p.state}`)]);if(u===e)return;e=u,(0,emit_1.lensEmit)("queue","info",`queue state: ${n.active??0} active \xB7 ${n.waiting??0} waiting \xB7 ${n.failed??0} failed`,{queue:t,kind:"queue-state",counts:n,recent:f},`queue:${t}`)}catch{}})()},2e3);o.unref?.(),publishers.set(t,o)}a(ensureStatePublisher,"ensureStatePublisher"),i(ensureStatePublisher,"ensureStatePublisher");function resetQueueStatePublishersForTests(){for(const t of publishers.values())clearInterval(t);publishers.clear(),sources.clear()}a(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests"),i(resetQueueStatePublishersForTests,"resetQueueStatePublishersForTests");function resetWorkIntakeForTests(){knownWorkers.clear(),intake.clear()}a(resetWorkIntakeForTests,"resetWorkIntakeForTests"),i(resetWorkIntakeForTests,"resetWorkIntakeForTests");
package/lib/tap-egress.js CHANGED
@@ -1 +1 @@
1
- "use strict";var L=Object.defineProperty;var E=(e,t)=>L(e,"name",{value:t,configurable:!0});var O=Object.defineProperty,g=E((e,t)=>O(e,"name",{value:t,configurable:!0}),"g"),D=Object.defineProperty,c=g((e,t)=>D(e,"name",{value:t,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.flushEgressCaptureForTests=flushEgressCaptureForTests,exports.tapEgress=tapEgress,exports.resetEgressTapForTests=resetEgressTapForTests;const redact_1=require("@lensmcp/core/redact"),http_exchange_1=require("@lensmcp/core/http-exchange"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),ai_providers_1=require("./ai-providers"),http_capture_1=require("./http-capture"),http_store_1=require("./http-store"),capture_file_1=require("./capture-file"),tap_ai_1=require("./tap-ai"),INTERNAL=[/\.local$/i,/\.internal$/i,/^localhost$/i,/^127\./,/^\[?::1\]?$/,/^0\.0\.0\.0$/,/^10\./,/^192\.168\./,/^172\.(1[6-9]|2\d|3[01])\./,/^169\.254\./,/^\[?[fF][cCdD][0-9a-fA-F]{2}:/,/^\[?[fF][eE]80:/],isInternal=c(e=>e===""||INTERNAL.some(t=>t.test(e)),"isInternal"),CAPTURE_QUERY=process.env.LENSMCP_EGRESS_QUERY==="1",MAX_PATH_CHARS=256,clipPath=c(e=>e.length>MAX_PATH_CHARS?`${e.slice(0,MAX_PATH_CHARS)}\u2026`:e,"clipPath");function capturePath(e,t){const s=e||"/";return!CAPTURE_QUERY||t.length<=1?clipPath(s):(0,redact_1.redactUrl)(`${s}${t}`)}E(capturePath,"capturePath"),g(capturePath,"capturePath"),c(capturePath,"capturePath");const fingerprintFor=c((e,t)=>t?`external:error:${e}`:`external:${e}`,"fingerprintFor"),PARENT_HEADER="x-lensmcp-parent-request-id",FLOW_HEADER="x-lensmcp-flow-id",ORIGIN_HEADER="x-lensmcp-origin-node-id";let hopsOutside=0;function hopHeaders(e,t){if(!e?.requestId&&!e?.flowId||t(http_exchange_1.LENS_REQUEST_ID_HEADER)||t(PARENT_HEADER)||t(FLOW_HEADER))return;const s={};if(e.requestId){const i=(0,flow_context_1.liveFlowContext)(),r=i?i.hopCount=(i.hopCount??0)+1:++hopsOutside;s[http_exchange_1.LENS_REQUEST_ID_HEADER]=`${e.requestId}.${r}`,s[PARENT_HEADER]=e.requestId}return e.flowId&&(s[FLOW_HEADER]=e.flowId),e.originNodeId&&(s[ORIGIN_HEADER]=e.originNodeId),s}E(hopHeaders,"hopHeaders"),g(hopHeaders,"hopHeaders"),c(hopHeaders,"hopHeaders");function isAiCall(e,t,s){return!!e&&t==="POST"&&!!(0,ai_providers_1.matchTarget)(e.hostname,e.port,e.pathname,s)}E(isAiCall,"isAiCall"),g(isAiCall,"isAiCall"),c(isAiCall,"isAiCall");function stampFetch(e,t,s){try{const i=t?.headers??(typeof e=="object"&&e!==null&&!(e instanceof URL)?e.headers:void 0),r=new Headers(i),p=hopHeaders(s,n=>r.has(n));if(!p)return{init:t};for(const[n,f]of Object.entries(p))r.set(n,f);const o=p[http_exchange_1.LENS_REQUEST_ID_HEADER];return{init:{...t,headers:r},...o?{calleeRequestId:o}:{}}}catch{return{init:t}}}E(stampFetch,"stampFetch"),g(stampFetch,"stampFetch"),c(stampFetch,"stampFetch");function stampRequest(e,t){try{if(e.headersSent||typeof e.setHeader!="function"||typeof e.getHeader!="function")return;const s=hopHeaders(t,i=>e.getHeader(i)!==void 0);if(!s)return;for(const[i,r]of Object.entries(s))e.setHeader(i,r);return s[http_exchange_1.LENS_REQUEST_ID_HEADER]}catch{return}}E(stampRequest,"stampRequest"),g(stampRequest,"stampRequest"),c(stampRequest,"stampRequest");const pendingExchanges=new Set;async function flushEgressCaptureForTests(){await Promise.allSettled([...pendingExchanges])}E(flushEgressCaptureForTests,"flushEgressCaptureForTests"),g(flushEgressCaptureForTests,"flushEgressCaptureForTests"),c(flushEgressCaptureForTests,"flushEgressCaptureForTests");async function finishExchange(e){const t=[],s=[],i=await(0,http_capture_1.requestPart)(e.request,e.url.search,e.mode,!!e.aiOpaque,s,t,!!e.ai&&!e.aiOpaque),r=e.reading?await e.reading.catch(()=>{}):void 0,{headers:p,redacted:o}=(0,http_store_1.redactHeaders)(e.responseHeaders??[]);t.push(...o);const n=typeof e.status=="number"?e.status:void 0,f={schemaVersion:1,id:e.id,capturedAt:Date.now(),side:"egress",service:emit_1.PROJECT,...e.ctx?.flowId?{flowId:e.ctx.flowId}:{},...e.ctx?.requestId?{requestId:e.ctx.requestId}:{},method:e.method,url:`${e.url.protocol}//${e.url.host}${e.path}`,host:e.url.hostname,path:e.path,...n!==void 0?{status:n}:{},...e.statusText?{statusText:e.statusText}:{},...e.error?{error:e.error}:{},startedAt:e.startedAt,...e.ttfbMs!==void 0?{ttfbMs:e.ttfbMs}:{},durationMs:(r?.endedAt??Date.now())-e.startedAt,capture:e.mode==="bodies"?"bodies":"headers",request:i,response:{headers:p,...r?.body?{body:r.body}:{},...r?.stream?{stream:r.stream}:{}},redacted:{headers:[...new Set(t)],bodyFields:[...s.map(u=>`request.${u}`),...e.responseFields.map(u=>`response.${u}`)]},...e.ai?{ai:{provider:e.ai}}:{}};(0,http_store_1.writeHttpExchange)(f)}E(finishExchange,"finishExchange"),g(finishExchange,"finishExchange"),c(finishExchange,"finishExchange");function trackExchange(e){const t=(typeof e=="function"?new Promise(s=>setImmediate(s)).then(()=>finishExchange(e())):finishExchange(e)).catch(()=>{});pendingExchanges.add(t),t.finally(()=>pendingExchanges.delete(t))}E(trackExchange,"trackExchange"),g(trackExchange,"trackExchange"),c(trackExchange,"trackExchange");function tapEgress(){tapFetch(),tapHttpModule("http"),tapHttpModule("https")}E(tapEgress,"tapEgress"),g(tapEgress,"tapEgress"),c(tapEgress,"tapEgress");let savedFetch;const httpOriginals=new Map;function resetEgressTapForTests(){const e=globalThis;savedFetch&&(e.fetch=savedFetch),delete e.__lensmcpFetchTap,restoreHttp("http"),restoreHttp("https"),savedFetch=void 0}E(resetEgressTapForTests,"resetEgressTapForTests"),g(resetEgressTapForTests,"resetEgressTapForTests"),c(resetEgressTapForTests,"resetEgressTapForTests");function restoreHttp(e){const t=httpOriginals.get(e);if(!t)return;const s=require(`node:${e}`);s.request=t.request,s.get=t.get,httpOriginals.delete(e)}E(restoreHttp,"restoreHttp"),g(restoreHttp,"restoreHttp"),c(restoreHttp,"restoreHttp");function tapFetch(){const e=globalThis;if(typeof e.fetch!="function"||e.__lensmcpFetchTap)return;e.__lensmcpFetchTap=!0;const t=e.fetch.bind(globalThis);savedFetch=e.fetch;const s=(0,http_store_1.httpCaptureMode)(),i=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS);e.fetch=(async(r,p)=>{let o="",n="/",f=!1,u;try{const h=new URL(typeof r=="string"?r:r instanceof URL?r.href:r.url);u=h,o=h.hostname,f=h.search.length>1,n=capturePath(h.pathname,h.search)}catch{}if(isInternal(o))return t(r,p);const m=Date.now(),d=typeof r=="object"&&r!==null&&!(r instanceof URL)?r.method:void 0,a=String(p?.method??d??"GET").toUpperCase();isAiCall(u,a,i)&&(0,flow_context_1.startLiveFlow)();const _=(0,flow_context_1.flowContext)(),y=(0,http_exchange_1.isServiceHopHost)(o)?stampFetch(r,p,_):{init:p},R=y.init,q=y.calleeRequestId,w=(0,flow_context_1.liveFlowContext)();w&&(w.externalCallCount=(w.externalCallCount??0)+1);const T=s!=="off"&&u?(0,http_store_1.newExchangeId)():void 0,b=T&&u&&a==="POST"?(0,ai_providers_1.matchTarget)(o,u.port,u.pathname,i)?.provider:void 0,$=!!b&&(0,tap_ai_1.aiCaptureMode)()!=="content"&&!(0,capture_file_1.aiBodiesAsked)(),I=!!b&&!$,H=I&&!!u&&!/\/embeddings\/?$/.test(u.pathname),M=T?(0,http_capture_1.takeRequest)(r,R,s==="bodies",I):void 0,C=c(h=>({id:T,mode:s,method:a,url:u,path:u.pathname.length>256?`${u.pathname.slice(0,256)}\u2026`:u.pathname,startedAt:m,ctx:_,request:M,...b?{ai:b}:{},...$?{aiOpaque:$}:{},responseFields:[],...h}),"job");try{const h=await t(r,R),l=Date.now()-m,x=h.status>=500,v=[];let A;if(T&&s==="bodies")try{A=(0,http_capture_1.readResponse)(h,h.clone(),m,{ai:$,large:H,paths:v})}catch{A=void 0}const F=(0,emit_1.lensEmit)("external","info",`egress ${a} ${o} \u2192 ${h.status}`,{name:o,kind:"egress",method:a,host:o,path:n,status:h.status,...f?{hasQuery:!0}:{},startedAt:m,durationMs:l,...T?{exchangeId:T}:{},...q?{calleeRequestId:q}:{}},fingerprintFor(o,x),_);if(T&&F){const S={status:h.status,...h.statusText?{statusText:h.statusText}:{},responseHeaders:(0,http_capture_1.headerPairs)(h.headers)};trackExchange(C({...S,ttfbMs:l,responseFields:v,...A?{reading:A}:{}}))}return h}catch(h){const l=String(h?.message??h),x=(0,emit_1.lensEmit)("external","error",`egress ${a} ${o} failed`,{name:o,kind:"egress",method:a,host:o,path:n,...f?{hasQuery:!0}:{},error:l,startedAt:m,durationMs:Date.now()-m,...T?{exchangeId:T}:{},...q?{calleeRequestId:q}:{}},fingerprintFor(o,!0),_);throw T&&x&&trackExchange(C({error:l})),h}})}E(tapFetch,"tapFetch"),g(tapFetch,"tapFetch"),c(tapFetch,"tapFetch");function tapHttpModule(e){const t=require(`node:${e}`),s=t.request;if(typeof s!="function"||s.__lensmcp)return;httpOriginals.set(e,{request:s,get:t.get});const i=(0,http_store_1.httpCaptureMode)(),r=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS),p=c(function(...o){const n=s.apply(this,o);try{observe(e,o,n,i,r)}catch{}return n},"wrapped");p.__lensmcp=!0,t.request=p,typeof t.get=="function"&&(t.get=function(...o){const n=p.apply(this,o);return n.end(),n})}E(tapHttpModule,"tapHttpModule"),g(tapHttpModule,"tapHttpModule"),c(tapHttpModule,"tapHttpModule");const headerOf=c((e,t)=>{const s=e?.[t];return Array.isArray(s)?s.join(", "):s??""},"headerOf");function teeRequest(e,t,s,i=!1){const r=t?new http_capture_1.WrittenBody(!s,i):void 0,p=c(()=>{try{return e.getHeaders?.()}catch{return}},"sentHeaders");let o,n=!1;const f=e.write;r&&typeof f=="function"&&(e.write=function(m,...d){try{n||r.take(m,d[0])}catch{}return f.call(this,m,...d)});const u=e.end;return e.end=function(m,...d){try{n||(n=!0,r?.take(m,d[0]),o=p())}catch{}return u.call(this,m,...d)},()=>(0,http_capture_1.writtenRequest)(o??p(),r)}E(teeRequest,"teeRequest"),g(teeRequest,"teeRequest"),c(teeRequest,"teeRequest");function teeResponse(e,t,s){let i=!1;const r=c(n=>{if(i)return;i=!0,clearTimeout(p);const f=Date.now();s(()=>t.size?t.finish(n,f):{endedAt:f})},"finish"),p=setTimeout(()=>r(!0),http_capture_1.MAX_STREAM_MS);p.unref?.();const o=e.emit;e.emit=function(n,...f){try{return o.call(this,n,...f)}finally{try{if(n==="data"){const u=i?void 0:(0,http_capture_1.chunkBytes)(f[0],e.readableEncoding);u&&!t.push(u)&&r(!1)}else n==="end"?r(!1):(n==="aborted"||n==="error"||n==="close")&&r(!0)}catch{}}}}E(teeResponse,"teeResponse"),g(teeResponse,"teeResponse"),c(teeResponse,"teeResponse");function observe(e,t,s,i,r){const p=parseTarget(t,e),{host:o,method:n,path:f,hasQuery:u}=p;if(isInternal(o))return;const m=Date.now();isAiCall(targetUrl(p),n,r)&&(0,flow_context_1.startLiveFlow)();const d=(0,flow_context_1.flowContext)(),a=(0,http_exchange_1.isServiceHopHost)(o)?stampRequest(s,d):void 0,_=(0,flow_context_1.liveFlowContext)();_&&(_.externalCallCount=(_.externalCallCount??0)+1);const y=i!=="off"?targetUrl(p):void 0,R=y?(0,http_store_1.newExchangeId)():void 0,q=R&&y&&n==="POST"?(0,ai_providers_1.matchTarget)(o,y.port,y.pathname,r)?.provider:void 0,w=!!q&&(0,tap_ai_1.aiCaptureMode)()!=="content"&&!(0,capture_file_1.aiBodiesAsked)(),T=!!q&&!w,b=T&&!!y&&!/\/embeddings\/?$/.test(y.pathname),$=R?teeRequest(s,i==="bodies",w,T):void 0,I=c(l=>({id:R,mode:i,method:n,url:y,path:clipPath(y.pathname),startedAt:m,ctx:d,request:$(),...q?{ai:q}:{},...w?{aiOpaque:w}:{},responseFields:[],...l}),"job");let H=!1;const M=c(l=>{if(H)return;H=!0;const x=l?.statusCode,v=Date.now()-m,A=(0,emit_1.lensEmit)("external","info",`egress ${n} ${o} \u2192 ${x??"?"}`,{name:o,kind:"egress",method:n,host:o,path:f,...x!=null?{status:x}:{},...u?{hasQuery:!0}:{},startedAt:m,durationMs:v,...R?{exchangeId:R}:{},...a?{calleeRequestId:a}:{}},fingerprintFor(o,x!=null&&x>=500),d);if(!R||!A||!l||typeof l.emit!="function")return;const F={...x!=null?{status:x}:{},...l.statusMessage?{statusText:l.statusMessage}:{},responseHeaders:(0,http_capture_1.headerPairs)(l.headers),ttfbMs:v};if(i!=="bodies"){trackExchange(()=>I(F));return}const S=[],P=new http_capture_1.ResponseSink(headerOf(l.headers,"content-type"),m,{ai:w,large:b,paths:S,encoding:headerOf(l.headers,"content-encoding")});teeResponse(l,P,U=>trackExchange(()=>I({...F,responseFields:S,reading:Promise.resolve(U())})))},"onResponse"),C=c(l=>{if(H)return;H=!0;const x=String(l?.message??l),v=(0,emit_1.lensEmit)("external","error",`egress ${n} ${o} failed`,{name:o,kind:"egress",method:n,host:o,path:f,...u?{hasQuery:!0}:{},error:x,startedAt:m,durationMs:Date.now()-m,...R?{exchangeId:R}:{},...a?{calleeRequestId:a}:{}},fingerprintFor(o,!0),d);R&&v&&trackExchange(()=>I({error:x}))},"onError"),h=s.emit;s.emit=function(l,...x){try{l==="response"?M(x[0]):l==="error"&&C(x[0])}catch{}return h.call(this,l,...x)}}E(observe,"observe"),g(observe,"observe"),c(observe,"observe");function targetUrl(e){try{const t=e.host.includes(":")&&!e.host.startsWith("[")?`[${e.host}]`:e.host,s=e.pathname.startsWith("/")?e.pathname:`/${e.pathname}`;return new URL(`${e.protocol}//${t}${e.port?`:${e.port}`:""}${s}${e.search}`)}catch{return}}E(targetUrl,"targetUrl"),g(targetUrl,"targetUrl"),c(targetUrl,"targetUrl");function parseTarget(e,t="http"){let s="",i="GET",r="/",p=!1,o=`${t}:`,n="",f="/",u="";const m=c((d,a)=>{p=a.length>1,r=capturePath(d,a),f=d||"/",u=a},"take");for(const d of e)if(typeof d=="string")try{const a=new URL(d);s=a.hostname,o=a.protocol,n=a.port,m(a.pathname,a.search)}catch{}else if(d instanceof URL)s=d.hostname,o=d.protocol,n=d.port,m(d.pathname,d.search);else if(d&&typeof d=="object"){const a=d;if(typeof a.method=="string"&&(i=a.method.toUpperCase()),typeof a.socketPath=="string")return{host:"",method:i,path:r,hasQuery:p,protocol:o,port:n,pathname:f,search:u};if(typeof a.path=="string"){const _=a.path,y=_.indexOf("?");m(y===-1?_:_.slice(0,y),y===-1?"":_.slice(y))}if(typeof a.protocol=="string"&&a.protocol&&(o=a.protocol),(typeof a.port=="number"||typeof a.port=="string"&&a.port)&&(n=String(a.port)),typeof a.hostname=="string"&&a.hostname)s=a.hostname;else if(typeof a.host=="string"&&a.host){const[_,y]=a.host.split(":");s=_??"",y&&!(typeof a.port=="number"||typeof a.port=="string")&&(n=y)}}return{host:s,method:i,path:r,hasQuery:p,protocol:o,port:n,pathname:f,search:u}}E(parseTarget,"parseTarget"),g(parseTarget,"parseTarget"),c(parseTarget,"parseTarget");
1
+ "use strict";var O=Object.defineProperty;var g=(t,e)=>O(t,"name",{value:e,configurable:!0});var D=Object.defineProperty,c=g((t,e)=>D(t,"name",{value:e,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.flushEgressCaptureForTests=flushEgressCaptureForTests,exports.tapEgress=tapEgress,exports.resetEgressTapForTests=resetEgressTapForTests;const redact_1=require("@lensmcp/core/redact"),http_exchange_1=require("@lensmcp/core/http-exchange"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),ai_providers_1=require("./ai-providers"),http_capture_1=require("./http-capture"),http_store_1=require("./http-store"),capture_file_1=require("./capture-file"),tap_ai_1=require("./tap-ai"),INTERNAL=[/\.local$/i,/\.internal$/i,/^localhost$/i,/^127\./,/^\[?::1\]?$/,/^0\.0\.0\.0$/,/^10\./,/^192\.168\./,/^172\.(1[6-9]|2\d|3[01])\./,/^169\.254\./,/^\[?[fF][cCdD][0-9a-fA-F]{2}:/,/^\[?[fF][eE]80:/],isInternal=c(t=>t===""||INTERNAL.some(e=>e.test(t)),"isInternal"),CAPTURE_QUERY=process.env.LENSMCP_EGRESS_QUERY==="1",MAX_PATH_CHARS=256,clipPath=c(t=>t.length>MAX_PATH_CHARS?`${t.slice(0,MAX_PATH_CHARS)}\u2026`:t,"clipPath");function capturePath(t,e){const s=t||"/";return!CAPTURE_QUERY||e.length<=1?clipPath(s):(0,redact_1.redactUrl)(`${s}${e}`)}g(capturePath,"capturePath"),c(capturePath,"capturePath");const fingerprintFor=c((t,e)=>e?`external:error:${t}`:`external:${t}`,"fingerprintFor"),PARENT_HEADER="x-lensmcp-parent-request-id",FLOW_HEADER="x-lensmcp-flow-id",ORIGIN_HEADER="x-lensmcp-origin-node-id";let hopsOutside=0;function hopHeaders(t,e){if(!t?.requestId&&!t?.flowId||e(http_exchange_1.LENS_REQUEST_ID_HEADER)||e(PARENT_HEADER)||e(FLOW_HEADER))return;const s={};if(t.requestId){const i=(0,flow_context_1.liveFlowContext)(),r=i?i.hopCount=(i.hopCount??0)+1:++hopsOutside;s[http_exchange_1.LENS_REQUEST_ID_HEADER]=`${t.requestId}.${r}`,s[PARENT_HEADER]=t.requestId}return t.flowId&&(s[FLOW_HEADER]=t.flowId),t.originNodeId&&(s[ORIGIN_HEADER]=t.originNodeId),s}g(hopHeaders,"hopHeaders"),c(hopHeaders,"hopHeaders");function isAiCall(t,e,s){return!!t&&e==="POST"&&!!(0,ai_providers_1.matchTarget)(t.hostname,t.port,t.pathname,s)}g(isAiCall,"isAiCall"),c(isAiCall,"isAiCall");function stampFetch(t,e,s){try{const i=e?.headers??(typeof t=="object"&&t!==null&&!(t instanceof URL)?t.headers:void 0),r=new Headers(i),d=hopHeaders(s,n=>r.has(n));if(!d)return{init:e};for(const[n,f]of Object.entries(d))r.set(n,f);const o=d[http_exchange_1.LENS_REQUEST_ID_HEADER];return{init:{...e,headers:r},...o?{calleeRequestId:o}:{}}}catch{return{init:e}}}g(stampFetch,"stampFetch"),c(stampFetch,"stampFetch");function stampRequest(t,e){try{if(t.headersSent||typeof t.setHeader!="function"||typeof t.getHeader!="function")return;const s=hopHeaders(e,i=>t.getHeader(i)!==void 0);if(!s)return;for(const[i,r]of Object.entries(s))t.setHeader(i,r);return s[http_exchange_1.LENS_REQUEST_ID_HEADER]}catch{return}}g(stampRequest,"stampRequest"),c(stampRequest,"stampRequest");const pendingExchanges=new Set;async function flushEgressCaptureForTests(){await Promise.allSettled([...pendingExchanges])}g(flushEgressCaptureForTests,"flushEgressCaptureForTests"),c(flushEgressCaptureForTests,"flushEgressCaptureForTests");async function finishExchange(t){const e=[],s=[],i=await(0,http_capture_1.requestPart)(t.request,t.url.search,t.mode,!!t.aiOpaque,s,e,!!t.ai&&!t.aiOpaque),r=t.reading?await t.reading.catch(()=>{}):void 0,{headers:d,redacted:o}=(0,http_store_1.redactHeaders)(t.responseHeaders??[]);e.push(...o);const n=typeof t.status=="number"?t.status:void 0,f={schemaVersion:1,id:t.id,capturedAt:Date.now(),side:"egress",service:emit_1.PROJECT,...t.ctx?.flowId?{flowId:t.ctx.flowId}:{},...t.ctx?.requestId?{requestId:t.ctx.requestId}:{},method:t.method,url:`${t.url.protocol}//${t.url.host}${t.path}`,host:t.url.hostname,path:t.path,...n!==void 0?{status:n}:{},...t.statusText?{statusText:t.statusText}:{},...t.error?{error:t.error}:{},startedAt:t.startedAt,...t.ttfbMs!==void 0?{ttfbMs:t.ttfbMs}:{},durationMs:(r?.endedAt??Date.now())-t.startedAt,capture:t.mode==="bodies"?"bodies":"headers",request:i,response:{headers:d,...r?.body?{body:r.body}:{},...r?.stream?{stream:r.stream}:{}},redacted:{headers:[...new Set(e)],bodyFields:[...s.map(u=>`request.${u}`),...t.responseFields.map(u=>`response.${u}`)]},...t.ai?{ai:{provider:t.ai}}:{}};(0,http_store_1.writeHttpExchange)(f)}g(finishExchange,"finishExchange"),c(finishExchange,"finishExchange");function trackExchange(t){const e=(typeof t=="function"?new Promise(s=>setImmediate(s)).then(()=>finishExchange(t())):finishExchange(t)).catch(()=>{});pendingExchanges.add(e),e.finally(()=>pendingExchanges.delete(e))}g(trackExchange,"trackExchange"),c(trackExchange,"trackExchange");function tapEgress(){tapFetch(),tapHttpModule("http"),tapHttpModule("https")}g(tapEgress,"tapEgress"),c(tapEgress,"tapEgress");let savedFetch;const httpOriginals=new Map;function resetEgressTapForTests(){const t=globalThis;savedFetch&&(t.fetch=savedFetch),delete t.__lensmcpFetchTap,restoreHttp("http"),restoreHttp("https"),savedFetch=void 0}g(resetEgressTapForTests,"resetEgressTapForTests"),c(resetEgressTapForTests,"resetEgressTapForTests");function restoreHttp(t){const e=httpOriginals.get(t);if(!e)return;const s=require(`node:${t}`);s.request=e.request,s.get=e.get,httpOriginals.delete(t)}g(restoreHttp,"restoreHttp"),c(restoreHttp,"restoreHttp");function tapFetch(){const t=globalThis;if(typeof t.fetch!="function"||t.__lensmcpFetchTap)return;t.__lensmcpFetchTap=!0;const e=t.fetch.bind(globalThis);savedFetch=t.fetch;const s=(0,http_store_1.httpCaptureMode)(),i=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS);t.fetch=(async(r,d)=>{let o="",n="/",f=!1,u;try{const p=new URL(typeof r=="string"?r:r instanceof URL?r.href:r.url);u=p,o=p.hostname,f=p.search.length>1,n=capturePath(p.pathname,p.search)}catch{}if(isInternal(o))return e(r,d);const m=Date.now(),h=typeof r=="object"&&r!==null&&!(r instanceof URL)?r.method:void 0,a=String(d?.method??h??"GET").toUpperCase();isAiCall(u,a,i)&&(0,flow_context_1.startLiveFlow)();const x=(0,flow_context_1.flowContext)(),E=(0,http_exchange_1.isServiceHopHost)(o)?stampFetch(r,d,x):{init:d},w=E.init,T=E.calleeRequestId,q=(0,flow_context_1.liveFlowContext)();q&&(q.externalCallCount=(q.externalCallCount??0)+1);const _=s!=="off"&&u?(0,http_store_1.newExchangeId)():void 0,v=_&&u&&a==="POST"?(0,ai_providers_1.matchTarget)(o,u.port,u.pathname,i)?.provider:void 0,$=!!v&&(0,tap_ai_1.aiCaptureMode)()!=="content"&&!(0,capture_file_1.aiBodiesAsked)(),I=!!v&&!$,b=I&&!!u&&!/\/embeddings\/?$/.test(u.pathname),F=_?(0,http_capture_1.takeRequest)(r,w,s==="bodies",I):void 0,H=c(p=>({id:_,mode:s,method:a,url:u,path:u.pathname.length>256?`${u.pathname.slice(0,256)}\u2026`:u.pathname,startedAt:m,ctx:x,request:F,...v?{ai:v}:{},...$?{aiOpaque:$}:{},responseFields:[],...p}),"job");try{const p=await e(r,w),l=Date.now()-m,y=p.status>=500,R=[];let A;if(_&&s==="bodies")try{A=(0,http_capture_1.readResponse)(p,p.clone(),m,{ai:$,large:b,paths:R})}catch{A=void 0}const C=(0,emit_1.lensEmit)("external","info",`egress ${a} ${o} \u2192 ${p.status}`,{name:o,kind:"egress",method:a,host:o,path:n,status:p.status,...f?{hasQuery:!0}:{},startedAt:m,durationMs:l,..._?{exchangeId:_}:{},...T?{calleeRequestId:T}:{}},fingerprintFor(o,y),x);if(_&&C){const S={status:p.status,...p.statusText?{statusText:p.statusText}:{},responseHeaders:(0,http_capture_1.headerPairs)(p.headers)};trackExchange(H({...S,ttfbMs:l,responseFields:R,...A?{reading:A}:{}}))}return p}catch(p){const l=String(p?.message??p),y=(0,emit_1.lensEmit)("external","error",`egress ${a} ${o} failed`,{name:o,kind:"egress",method:a,host:o,path:n,...f?{hasQuery:!0}:{},error:l,startedAt:m,durationMs:Date.now()-m,..._?{exchangeId:_}:{},...T?{calleeRequestId:T}:{}},fingerprintFor(o,!0),x);throw _&&y&&trackExchange(H({error:l})),p}})}g(tapFetch,"tapFetch"),c(tapFetch,"tapFetch");function tapHttpModule(t){const e=require(`node:${t}`),s=e.request;if(typeof s!="function"||s.__lensmcp)return;httpOriginals.set(t,{request:s,get:e.get});const i=(0,http_store_1.httpCaptureMode)(),r=(0,ai_providers_1.parseExtraHosts)(process.env.LENSMCP_AI_HOSTS),d=c(function(...o){const n=s.apply(this,o);try{observe(t,o,n,i,r)}catch{}return n},"wrapped");d.__lensmcp=!0,e.request=d,typeof e.get=="function"&&(e.get=function(...o){const n=d.apply(this,o);return n.end(),n})}g(tapHttpModule,"tapHttpModule"),c(tapHttpModule,"tapHttpModule");const headerOf=c((t,e)=>{const s=t?.[e];return Array.isArray(s)?s.join(", "):s??""},"headerOf");function teeRequest(t,e,s,i=!1){const r=e?new http_capture_1.WrittenBody(!s,i):void 0,d=c(()=>{try{return t.getHeaders?.()}catch{return}},"sentHeaders");let o,n=!1;const f=t.write;r&&typeof f=="function"&&(t.write=function(m,...h){try{n||r.take(m,h[0])}catch{}return f.call(this,m,...h)});const u=t.end;return t.end=function(m,...h){try{n||(n=!0,r?.take(m,h[0]),o=d())}catch{}return u.call(this,m,...h)},()=>(0,http_capture_1.writtenRequest)(o??d(),r)}g(teeRequest,"teeRequest"),c(teeRequest,"teeRequest");function teeResponse(t,e,s){let i=!1;const r=c(n=>{if(i)return;i=!0,clearTimeout(d);const f=Date.now();s(()=>e.size?e.finish(n,f):{endedAt:f})},"finish"),d=setTimeout(()=>r(!0),http_capture_1.MAX_STREAM_MS);d.unref?.();const o=t.emit;t.emit=function(n,...f){try{return o.call(this,n,...f)}finally{try{if(n==="data"){const u=i?void 0:(0,http_capture_1.chunkBytes)(f[0],t.readableEncoding);u&&!e.push(u)&&r(!1)}else n==="end"?r(!1):(n==="aborted"||n==="error"||n==="close")&&r(!0)}catch{}}}}g(teeResponse,"teeResponse"),c(teeResponse,"teeResponse");function observe(t,e,s,i,r){const d=parseTarget(e,t),{host:o,method:n,path:f,hasQuery:u}=d;if(isInternal(o))return;const m=Date.now();isAiCall(targetUrl(d),n,r)&&(0,flow_context_1.startLiveFlow)();const h=(0,flow_context_1.flowContext)(),a=(0,http_exchange_1.isServiceHopHost)(o)?stampRequest(s,h):void 0,x=(0,flow_context_1.liveFlowContext)();x&&(x.externalCallCount=(x.externalCallCount??0)+1);const E=i!=="off"?targetUrl(d):void 0,w=E?(0,http_store_1.newExchangeId)():void 0,T=w&&E&&n==="POST"?(0,ai_providers_1.matchTarget)(o,E.port,E.pathname,r)?.provider:void 0,q=!!T&&(0,tap_ai_1.aiCaptureMode)()!=="content"&&!(0,capture_file_1.aiBodiesAsked)(),_=!!T&&!q,v=_&&!!E&&!/\/embeddings\/?$/.test(E.pathname),$=w?teeRequest(s,i==="bodies",q,_):void 0,I=c(l=>({id:w,mode:i,method:n,url:E,path:clipPath(E.pathname),startedAt:m,ctx:h,request:$(),...T?{ai:T}:{},...q?{aiOpaque:q}:{},responseFields:[],...l}),"job");let b=!1;const F=c(l=>{if(b)return;b=!0;const y=l?.statusCode,R=Date.now()-m,A=(0,emit_1.lensEmit)("external","info",`egress ${n} ${o} \u2192 ${y??"?"}`,{name:o,kind:"egress",method:n,host:o,path:f,...y!=null?{status:y}:{},...u?{hasQuery:!0}:{},startedAt:m,durationMs:R,...w?{exchangeId:w}:{},...a?{calleeRequestId:a}:{}},fingerprintFor(o,y!=null&&y>=500),h);if(!w||!A||!l||typeof l.emit!="function")return;const C={...y!=null?{status:y}:{},...l.statusMessage?{statusText:l.statusMessage}:{},responseHeaders:(0,http_capture_1.headerPairs)(l.headers),ttfbMs:R};if(i!=="bodies"){trackExchange(()=>I(C));return}const S=[],M=new http_capture_1.ResponseSink(headerOf(l.headers,"content-type"),m,{ai:q,large:v,paths:S,encoding:headerOf(l.headers,"content-encoding")});teeResponse(l,M,P=>trackExchange(()=>I({...C,responseFields:S,reading:Promise.resolve(P())})))},"onResponse"),H=c(l=>{if(b)return;b=!0;const y=String(l?.message??l),R=(0,emit_1.lensEmit)("external","error",`egress ${n} ${o} failed`,{name:o,kind:"egress",method:n,host:o,path:f,...u?{hasQuery:!0}:{},error:y,startedAt:m,durationMs:Date.now()-m,...w?{exchangeId:w}:{},...a?{calleeRequestId:a}:{}},fingerprintFor(o,!0),h);w&&R&&trackExchange(()=>I({error:y}))},"onError"),p=s.emit;s.emit=function(l,...y){try{l==="response"?F(y[0]):l==="error"&&H(y[0])}catch{}return p.call(this,l,...y)}}g(observe,"observe"),c(observe,"observe");function targetUrl(t){try{const e=t.host.includes(":")&&!t.host.startsWith("[")?`[${t.host}]`:t.host,s=t.pathname.startsWith("/")?t.pathname:`/${t.pathname}`;return new URL(`${t.protocol}//${e}${t.port?`:${t.port}`:""}${s}${t.search}`)}catch{return}}g(targetUrl,"targetUrl"),c(targetUrl,"targetUrl");function parseTarget(t,e="http"){let s="",i="GET",r="/",d=!1,o=`${e}:`,n="",f="/",u="";const m=c((h,a)=>{d=a.length>1,r=capturePath(h,a),f=h||"/",u=a},"take");for(const h of t)if(typeof h=="string")try{const a=new URL(h);s=a.hostname,o=a.protocol,n=a.port,m(a.pathname,a.search)}catch{}else if(h instanceof URL)s=h.hostname,o=h.protocol,n=h.port,m(h.pathname,h.search);else if(h&&typeof h=="object"){const a=h;if(typeof a.method=="string"&&(i=a.method.toUpperCase()),typeof a.socketPath=="string")return{host:"",method:i,path:r,hasQuery:d,protocol:o,port:n,pathname:f,search:u};if(typeof a.path=="string"){const x=a.path,E=x.indexOf("?");m(E===-1?x:x.slice(0,E),E===-1?"":x.slice(E))}if(typeof a.protocol=="string"&&a.protocol&&(o=a.protocol),(typeof a.port=="number"||typeof a.port=="string"&&a.port)&&(n=String(a.port)),typeof a.hostname=="string"&&a.hostname)s=a.hostname;else if(typeof a.host=="string"&&a.host){const[x,E]=a.host.split(":");s=x??"",E&&!(typeof a.port=="number"||typeof a.port=="string")&&(n=E)}}return{host:s,method:i,path:r,hasQuery:d,protocol:o,port:n,pathname:f,search:u}}g(parseTarget,"parseTarget"),c(parseTarget,"parseTarget");
@@ -1 +1 @@
1
- "use strict";var w=Object.defineProperty;var c=(e,o)=>w(e,"name",{value:o,configurable:!0});var x=Object.defineProperty,l=c((e,o)=>x(e,"name",{value:o,configurable:!0}),"l"),P=Object.defineProperty,n=l((e,o)=>P(e,"name",{value:o,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapEventLoop=tapEventLoop,exports.stopEventLoopTapForTests=stopEventLoopTapForTests;const node_perf_hooks_1=require("node:perf_hooks"),emit_1=require("./emit"),loop_identity_1=require("./loop-identity"),tap_loop_callbacks_1=require("./tap-loop-callbacks"),loop_watchdog_1=require("./loop-watchdog"),SAMPLE_MS=(()=>{const e=Number(process.env.LENSMCP_EVENT_LOOP_SAMPLE_MS);return Number.isFinite(e)&&e>=1e3?e:3e4})(),REPORT_ABOVE_MS=(()=>{const e=Number(process.env.LENSMCP_EVENT_LOOP_MIN_MS);return Number.isFinite(e)&&e>=0?e:50})(),STEP_MS=(()=>{const e=Number(process.env.LENSMCP_EVENT_LOOP_STEP_MS);return Math.min(Number.isFinite(e)&&e>=1e3?e:5e3,SAMPLE_MS)})(),MAX_CARRIED=Math.ceil(Math.max(12e4,2*SAMPLE_MS)/STEP_MS),RESOLUTION_MS=20,round=n((e,o)=>Number(e.toFixed(o)),"round");let timer,published=!1,stopMonitoring;function tapEventLoop(){if(process.env.LENSMCP_EVENT_LOOP==="0"||timer)return;const e=(0,node_perf_hooks_1.monitorEventLoopDelay)({resolution:RESOLUTION_MS});e.enable();let o=node_perf_hooks_1.performance.eventLoopUtilization(),d=0;const E=process.env.LENSMCP_EVENT_LOOP_CALLBACKS!=="0";let m=!1;const _=n(()=>`${E?"Callback wall time and loop delay":"Loop delay only; callback measurement disabled"}; ${m?"independent watchdog":"watchdog unavailable or disabled"}`,"coverage"),L=(0,loop_watchdog_1.startLoopWatchdog)(()=>{m=!1,(0,emit_1.lensEmit)("perf","warning","Event loop watchdog unavailable",{kind:"event-loop-status",loop:loop_identity_1.NODE_LOOP,coverage:_()},"perf:event-loop-status",void 0,"performance")});m=!!L,(0,emit_1.lensEmit)("perf","info","Event loop monitoring started",{kind:"event-loop-status",loop:loop_identity_1.NODE_LOOP,coverage:_()},"perf:event-loop-status",void 0,"performance");let t=[],u=[],M=Date.now(),f=o;timer=setInterval(()=>{const v=RESOLUTION_MS,O=e.mean/1e6;if(!Number.isFinite(O))return;const a=Date.now(),i=node_perf_hooks_1.performance.eventLoopUtilization(),b=[a,round(Math.max(0,O-v),2),round(Math.max(0,e.percentile(99)/1e6-v),2),round(Math.max(0,e.max/1e6-v),2),round(node_perf_hooks_1.performance.eventLoopUtilization(i,f).utilization,4)];if(f=i,e.reset(),t.push(b),t.length>MAX_CARRIED&&t.splice(0,t.length-MAX_CARRIED),u.push(b),a-M<SAMPLE_MS-STEP_MS/2)return;M=a;const p=u;u=[];const h=p.reduce((r,T)=>r+T[1],0)/p.length,g=Math.max(...p.map(r=>r[2])),s=Math.max(...p.map(r=>r[3])),S=node_perf_hooks_1.performance.eventLoopUtilization(i,o).utilization;o=i,!(published&&s<REPORT_ABOVE_MS&&a-d<6e4)&&(published=!0,d=a,(0,emit_1.lensEmit)("perf",s>=1e3?"error":"info",`event loop lag ${h.toFixed(1)}ms mean / ${s.toFixed(1)}ms max`,{kind:"event-loop-lag",lagMs:round(h,2),maxMs:round(s,2),p99Ms:round(g,2),windowMs:SAMPLE_MS,loop:loop_identity_1.NODE_LOOP,utilization:round(S,4),stepMs:STEP_MS,samples:t},"perf:event-loop-lag",void 0,"performance")&&(t=[]))},STEP_MS),timer.unref?.();const N=E?(0,tap_loop_callbacks_1.tapLoopCallbacks)(Math.max(50,REPORT_ABOVE_MS)):void 0;stopMonitoring=n(()=>{N?.(),L?.(),e.disable()},"stopMonitoring")}c(tapEventLoop,"tapEventLoop"),l(tapEventLoop,"tapEventLoop"),n(tapEventLoop,"tapEventLoop");function stopEventLoopTapForTests(){timer&&clearInterval(timer),timer=void 0,stopMonitoring?.(),stopMonitoring=void 0,published=!1}c(stopEventLoopTapForTests,"stopEventLoopTapForTests"),l(stopEventLoopTapForTests,"stopEventLoopTapForTests"),n(stopEventLoopTapForTests,"stopEventLoopTapForTests");
1
+ "use strict";var x=Object.defineProperty;var l=(e,o)=>x(e,"name",{value:o,configurable:!0});var P=Object.defineProperty,n=l((e,o)=>P(e,"name",{value:o,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapEventLoop=tapEventLoop,exports.stopEventLoopTapForTests=stopEventLoopTapForTests;const node_perf_hooks_1=require("node:perf_hooks"),emit_1=require("./emit"),loop_identity_1=require("./loop-identity"),tap_loop_callbacks_1=require("./tap-loop-callbacks"),loop_watchdog_1=require("./loop-watchdog"),SAMPLE_MS=(()=>{const e=Number(process.env.LENSMCP_EVENT_LOOP_SAMPLE_MS);return Number.isFinite(e)&&e>=1e3?e:3e4})(),REPORT_ABOVE_MS=(()=>{const e=Number(process.env.LENSMCP_EVENT_LOOP_MIN_MS);return Number.isFinite(e)&&e>=0?e:50})(),STEP_MS=(()=>{const e=Number(process.env.LENSMCP_EVENT_LOOP_STEP_MS);return Math.min(Number.isFinite(e)&&e>=1e3?e:5e3,SAMPLE_MS)})(),MAX_CARRIED=Math.ceil(Math.max(12e4,2*SAMPLE_MS)/STEP_MS),RESOLUTION_MS=20,round=n((e,o)=>Number(e.toFixed(o)),"round");let timer,published=!1,stopMonitoring;function tapEventLoop(){if(process.env.LENSMCP_EVENT_LOOP==="0"||timer)return;const e=(0,node_perf_hooks_1.monitorEventLoopDelay)({resolution:RESOLUTION_MS});e.enable();let o=node_perf_hooks_1.performance.eventLoopUtilization(),v=0;const d=process.env.LENSMCP_EVENT_LOOP_CALLBACKS!=="0";let c=!1;const _=n(()=>`${d?"Callback wall time and loop delay":"Loop delay only; callback measurement disabled"}; ${c?"independent watchdog":"watchdog unavailable or disabled"}`,"coverage"),E=(0,loop_watchdog_1.startLoopWatchdog)(()=>{c=!1,(0,emit_1.lensEmit)("perf","warning","Event loop watchdog unavailable",{kind:"event-loop-status",loop:loop_identity_1.NODE_LOOP,coverage:_()},"perf:event-loop-status",void 0,"performance")});c=!!E,(0,emit_1.lensEmit)("perf","info","Event loop monitoring started",{kind:"event-loop-status",loop:loop_identity_1.NODE_LOOP,coverage:_()},"perf:event-loop-status",void 0,"performance");let t=[],m=[],M=Date.now(),L=o;timer=setInterval(()=>{const u=RESOLUTION_MS,f=e.mean/1e6;if(!Number.isFinite(f))return;const a=Date.now(),i=node_perf_hooks_1.performance.eventLoopUtilization(),O=[a,round(Math.max(0,f-u),2),round(Math.max(0,e.percentile(99)/1e6-u),2),round(Math.max(0,e.max/1e6-u),2),round(node_perf_hooks_1.performance.eventLoopUtilization(i,L).utilization,4)];if(L=i,e.reset(),t.push(O),t.length>MAX_CARRIED&&t.splice(0,t.length-MAX_CARRIED),m.push(O),a-M<SAMPLE_MS-STEP_MS/2)return;M=a;const p=m;m=[];const b=p.reduce((r,S)=>r+S[1],0)/p.length,N=Math.max(...p.map(r=>r[2])),s=Math.max(...p.map(r=>r[3])),g=node_perf_hooks_1.performance.eventLoopUtilization(i,o).utilization;o=i,!(published&&s<REPORT_ABOVE_MS&&a-v<6e4)&&(published=!0,v=a,(0,emit_1.lensEmit)("perf",s>=1e3?"error":"info",`event loop lag ${b.toFixed(1)}ms mean / ${s.toFixed(1)}ms max`,{kind:"event-loop-lag",lagMs:round(b,2),maxMs:round(s,2),p99Ms:round(N,2),windowMs:SAMPLE_MS,loop:loop_identity_1.NODE_LOOP,utilization:round(g,4),stepMs:STEP_MS,samples:t},"perf:event-loop-lag",void 0,"performance")&&(t=[]))},STEP_MS),timer.unref?.();const h=d?(0,tap_loop_callbacks_1.tapLoopCallbacks)(Math.max(50,REPORT_ABOVE_MS)):void 0;stopMonitoring=n(()=>{h?.(),E?.(),e.disable()},"stopMonitoring")}l(tapEventLoop,"tapEventLoop"),n(tapEventLoop,"tapEventLoop");function stopEventLoopTapForTests(){timer&&clearInterval(timer),timer=void 0,stopMonitoring?.(),stopMonitoring=void 0,published=!1}l(stopEventLoopTapForTests,"stopEventLoopTapForTests"),n(stopEventLoopTapForTests,"stopEventLoopTapForTests");
package/lib/tap-exec.js CHANGED
@@ -1 +1 @@
1
- "use strict";var y=Object.defineProperty;var g=(r,e)=>y(r,"name",{value:e,configurable:!0});var m=Object.defineProperty,p=g((r,e)=>m(r,"name",{value:e,configurable:!0}),"p"),f=Object.defineProperty,d=p((r,e)=>f(r,"name",{value:e,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapExec=tapExec;const redact_1=require("@lensmcp/core/redact"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),shown=d(r=>{const e=(0,redact_1.redactSecretText)(r.slice(0,4096));return e.length>200?`${e.slice(0,199)}\u2026`:e},"shown"),fmtCmd=d((r,e)=>{const t=Array.isArray(e)?e.map(String).slice(0,8).join(" "):"";return shown(`${String(r)}${t?" "+t:""}`)},"fmtCmd");function wrap(r,e,t){const n=r[e];if(typeof n!="function"||n.__lensmcp)return;const o=t(n);o.__lensmcp=!0,r[e]=o}g(wrap,"wrap"),p(wrap,"wrap"),d(wrap,"wrap");function observeChild(r,e,t,n){if(!t||typeof t.once!="function")return;const o=t;if(o.__lensmcpObserved)return;o.__lensmcpObserved=!0;const a=Date.now();t.once("exit",(...c)=>{const s=c[0],x=c[1];(0,emit_1.lensEmit)("exec",s===0?"info":x?"error":"warning",`exec ${e.split(" ")[0]} \u2192 ${s??x}`,{name:"exec",kind:"exec",cmd:e,via:r,...s!=null?{code:s}:{},...x?{signal:x}:{},durationMs:Date.now()-a,...t.pid?{pid:t.pid}:{}},void 0,n)}),t.once("error",(...c)=>{const s=c[0];(0,emit_1.lensEmit)("exec","error",`exec ${e.split(" ")[0]} failed to start`,{name:"exec",kind:"exec",cmd:e,via:r,error:(0,redact_1.clip)((0,redact_1.redactSecretText)(String(s?.message??s)),500),durationMs:Date.now()-a},void 0,n)})}g(observeChild,"observeChild"),p(observeChild,"observeChild"),d(observeChild,"observeChild");function tapExec(r=require("node:child_process")){for(const e of["spawn","fork"])wrap(r,e,t=>function(n,...o){const a=Array.isArray(o[0])?o[0]:[],c=(0,flow_context_1.flowContext)(),s=t.call(this,n,...o);try{observeChild(e,fmtCmd(n,a),s,c)}catch{}return s});wrap(r,"exec",e=>function(t,...n){const o=(0,flow_context_1.flowContext)(),a=e.call(this,t,...n);try{observeChild("exec",shown(String(t)),a,o)}catch{}return a}),wrap(r,"execFile",e=>function(t,...n){const o=Array.isArray(n[0])?n[0]:[],a=(0,flow_context_1.flowContext)(),c=e.call(this,t,...n);try{observeChild("execFile",fmtCmd(t,o),c,a)}catch{}return c});for(const e of["execSync","execFileSync","spawnSync"])wrap(r,e,t=>function(n,...o){const a=Array.isArray(o[0])?o[0]:[],c=e==="execSync"?shown(String(n)):fmtCmd(n,a),s=(0,flow_context_1.flowContext)(),x=Date.now();try{const l=t.call(this,n,...o),i=l&&typeof l=="object"?l:{},u=i.status??0;return i.error||i.signal?((0,emit_1.lensEmit)("exec","error",i.error?`exec ${c.split(" ")[0]} failed to start`:`exec ${c.split(" ")[0]} \u2192 ${i.signal}`,{name:"exec",kind:"exec",cmd:c,via:e,...i.error?{error:(0,redact_1.clip)((0,redact_1.redactSecretText)(String(i.error?.message??i.error)),500)}:{},...i.signal?{signal:i.signal}:{},durationMs:Date.now()-x,sync:!0},void 0,s),l):((0,emit_1.lensEmit)("exec",u===0?"info":"warning",`exec ${c.split(" ")[0]} \u2192 ${u}`,{name:"exec",kind:"exec",cmd:c,via:e,code:u,durationMs:Date.now()-x,sync:!0},void 0,s),l)}catch(l){const i=l,u=typeof i?.status=="number"&&!i.signal;throw(0,emit_1.lensEmit)("exec",u?"warning":"error",u?`exec ${c.split(" ")[0]} \u2192 ${i.status}`:`exec ${c.split(" ")[0]} failed`,{name:"exec",kind:"exec",cmd:c,via:e,...u?{code:i.status}:{error:(0,redact_1.clip)((0,redact_1.redactSecretText)(String(i?.message??l)),500)},...typeof i?.signal=="string"?{signal:i.signal}:{},durationMs:Date.now()-x,sync:!0},void 0,s),l}})}g(tapExec,"tapExec"),p(tapExec,"tapExec"),d(tapExec,"tapExec");
1
+ "use strict";var m=Object.defineProperty;var p=(n,e)=>m(n,"name",{value:e,configurable:!0});var f=Object.defineProperty,d=p((n,e)=>f(n,"name",{value:e,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapExec=tapExec;const redact_1=require("@lensmcp/core/redact"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),shown=d(n=>{const e=(0,redact_1.redactSecretText)(n.slice(0,4096));return e.length>200?`${e.slice(0,199)}\u2026`:e},"shown"),fmtCmd=d((n,e)=>{const r=Array.isArray(e)?e.map(String).slice(0,8).join(" "):"";return shown(`${String(n)}${r?" "+r:""}`)},"fmtCmd");function wrap(n,e,r){const t=n[e];if(typeof t!="function"||t.__lensmcp)return;const o=r(t);o.__lensmcp=!0,n[e]=o}p(wrap,"wrap"),d(wrap,"wrap");function observeChild(n,e,r,t){if(!r||typeof r.once!="function")return;const o=r;if(o.__lensmcpObserved)return;o.__lensmcpObserved=!0;const a=Date.now();r.once("exit",(...c)=>{const s=c[0],x=c[1];(0,emit_1.lensEmit)("exec",s===0?"info":x?"error":"warning",`exec ${e.split(" ")[0]} \u2192 ${s??x}`,{name:"exec",kind:"exec",cmd:e,via:n,...s!=null?{code:s}:{},...x?{signal:x}:{},durationMs:Date.now()-a,...r.pid?{pid:r.pid}:{}},void 0,t)}),r.once("error",(...c)=>{const s=c[0];(0,emit_1.lensEmit)("exec","error",`exec ${e.split(" ")[0]} failed to start`,{name:"exec",kind:"exec",cmd:e,via:n,error:(0,redact_1.clip)((0,redact_1.redactSecretText)(String(s?.message??s)),500),durationMs:Date.now()-a},void 0,t)})}p(observeChild,"observeChild"),d(observeChild,"observeChild");function tapExec(n=require("node:child_process")){for(const e of["spawn","fork"])wrap(n,e,r=>function(t,...o){const a=Array.isArray(o[0])?o[0]:[],c=(0,flow_context_1.flowContext)(),s=r.call(this,t,...o);try{observeChild(e,fmtCmd(t,a),s,c)}catch{}return s});wrap(n,"exec",e=>function(r,...t){const o=(0,flow_context_1.flowContext)(),a=e.call(this,r,...t);try{observeChild("exec",shown(String(r)),a,o)}catch{}return a}),wrap(n,"execFile",e=>function(r,...t){const o=Array.isArray(t[0])?t[0]:[],a=(0,flow_context_1.flowContext)(),c=e.call(this,r,...t);try{observeChild("execFile",fmtCmd(r,o),c,a)}catch{}return c});for(const e of["execSync","execFileSync","spawnSync"])wrap(n,e,r=>function(t,...o){const a=Array.isArray(o[0])?o[0]:[],c=e==="execSync"?shown(String(t)):fmtCmd(t,a),s=(0,flow_context_1.flowContext)(),x=Date.now();try{const l=r.call(this,t,...o),i=l&&typeof l=="object"?l:{},u=i.status??0;return i.error||i.signal?((0,emit_1.lensEmit)("exec","error",i.error?`exec ${c.split(" ")[0]} failed to start`:`exec ${c.split(" ")[0]} \u2192 ${i.signal}`,{name:"exec",kind:"exec",cmd:c,via:e,...i.error?{error:(0,redact_1.clip)((0,redact_1.redactSecretText)(String(i.error?.message??i.error)),500)}:{},...i.signal?{signal:i.signal}:{},durationMs:Date.now()-x,sync:!0},void 0,s),l):((0,emit_1.lensEmit)("exec",u===0?"info":"warning",`exec ${c.split(" ")[0]} \u2192 ${u}`,{name:"exec",kind:"exec",cmd:c,via:e,code:u,durationMs:Date.now()-x,sync:!0},void 0,s),l)}catch(l){const i=l,u=typeof i?.status=="number"&&!i.signal;throw(0,emit_1.lensEmit)("exec",u?"warning":"error",u?`exec ${c.split(" ")[0]} \u2192 ${i.status}`:`exec ${c.split(" ")[0]} failed`,{name:"exec",kind:"exec",cmd:c,via:e,...u?{code:i.status}:{error:(0,redact_1.clip)((0,redact_1.redactSecretText)(String(i?.message??l)),500)},...typeof i?.signal=="string"?{signal:i.signal}:{},durationMs:Date.now()-x,sync:!0},void 0,s),l}})}p(tapExec,"tapExec"),d(tapExec,"tapExec");
package/lib/tap-fs.js CHANGED
@@ -1 +1 @@
1
- "use strict";var y=Object.defineProperty;var u=(r,n)=>y(r,"name",{value:n,configurable:!0});var h=Object.defineProperty,c=u((r,n)=>h(r,"name",{value:n,configurable:!0}),"c"),d=Object.defineProperty,f=c((r,n)=>d(r,"name",{value:n,configurable:!0}),"f");Object.defineProperty(exports,"__esModule",{value:!0}),exports.FsWindow=exports.OWN_EVENTS=void 0,exports.flushFsWindowForTests=flushFsWindowForTests,exports.tapFs=tapFs;const tslib_1=require("tslib"),os=tslib_1.__importStar(require("node:os")),emit_1=require("./emit"),flow_context_1=require("./flow-context"),PATHS_KEPT=50,PATHS_SENT=20;exports.OWN_EVENTS=4;const SLICES_KEPT=64;class FsSlice{static{u(this,"FsSlice")}static{c(this,"FsSlice")}static{f(this,"FsSlice")}constructor(n,s){this.flowId=n,this.requestId=s,this.reads=0,this.writes=0,this.bytesRead=0,this.bytesWritten=0,this.first=1/0,this.last=0,this.counts=new Map,this.ops=new Map}absorb(n){this.reads+=n.reads,this.writes+=n.writes,this.bytesRead+=n.bytesRead,this.bytesWritten+=n.bytesWritten;for(const[s,e]of n.counts)this.counts.set(s,(this.counts.get(s)??0)+e);for(const[s,e]of n.ops)this.ops.set(s,e)}payload(n={}){const s=[...this.counts.entries()].sort((t,i)=>i[1]-t[1]).slice(0,3).map(([t])=>t),e=[...this.ops.values()].sort((t,i)=>i.at-t.at).slice(0,PATHS_SENT);return{reads:this.reads,writes:this.writes,bytesRead:this.bytesRead,bytesWritten:this.bytesWritten,top:s,paths:e,...n}}}class FsWindow{static{u(this,"FsWindow")}static{c(this,"FsWindow")}static{f(this,"FsWindow")}constructor(){this.slices=new Map,this.kept=0}record(n,s,e,t,i,o=!1){let l=i?.flowId?`${i.flowId}\0${i.requestId??""}`:"";l&&!this.slices.has(l)&&this.slices.size>=SLICES_KEPT&&(l="");let a=this.slices.get(l);a||(a=l?new FsSlice(i?.flowId,i?.requestId):new FsSlice,this.slices.set(l,a)),n==="read"?(a.reads+=1,a.bytesRead+=e):(a.writes+=1,a.bytesWritten+=e),a.first=Math.min(a.first,t),a.last=Math.max(a.last,t),(a.counts.size<PATHS_KEPT||a.counts.has(s))&&a.counts.set(s,(a.counts.get(s)??0)+1);const p=`${n}\0${s}\0${i?.flowId??""}`,w=a.ops.get(p);w?(w.n+=1,w.bytes+=e,w.at=t,i?.requestId&&(w.requestId=i.requestId)):this.kept<PATHS_KEPT&&(this.kept+=1,a.ops.set(p,{path:s,op:n,n:1,bytes:e,...o?{stream:!0}:{},at:t,...i?.flowId?{flowId:i.flowId}:{},...i?.requestId?{requestId:i.requestId}:{}}))}drain(){if(!this.slices.size)return[];const n=[...this.slices.entries()].filter(([o])=>o!=="").sort(([o,l],[a,p])=>p.reads+p.writes-(l.reads+l.writes)||p.last-l.last||(o<a?-1:1)),s=n.slice(0,exports.OWN_EVENTS),e=n.slice(exports.OWN_EVENTS),t=this.slices.get("")??new FsSlice;for(const[,o]of e)t.absorb(o);const i=s.map(([,o])=>({ctx:{flowId:o.flowId,...o.requestId?{requestId:o.requestId}:{}},payload:o.payload({startedAt:o.first})}));return t.reads+t.writes>0&&i.push({payload:t.payload(e.length?{merged:e.length}:{})}),this.slices.clear(),this.kept=0,i}}exports.FsWindow=FsWindow;const current=new FsWindow;let timer=null;const TMP=os.tmpdir(),CWD=process.cwd(),SKIP=["node_modules","/.nx/","/dist/","/.git/",".lensmcp"],CODE=/\.(?:[cm]?[jt]sx?|map|node)$/;let appending=0;function trackedPath(r){if((0,emit_1.isLensWriting)())return null;const n=typeof r=="string"?r:Buffer.isBuffer(r)?r.toString():r instanceof URL?r.pathname:null;return!n||n===emit_1.EVENT_FILE||n.startsWith(TMP)||SKIP.some(s=>n.includes(s))?null:n}u(trackedPath,"trackedPath"),c(trackedPath,"trackedPath"),f(trackedPath,"trackedPath");function record(r,n,s=0,e,t=!1){const i=trackedPath(n);if(!i||r==="read"&&CODE.test(i))return;const o=i.startsWith(CWD)?i.slice(CWD.length+1):i;current.record(r,o,s,Date.now(),e??(0,flow_context_1.flowContext)(),t),timer||(timer=setTimeout(flush,1e3),timer.unref?.())}u(record,"record"),c(record,"record"),f(record,"record");function flush(){timer=null;for(const{ctx:r,payload:n}of current.drain()){const s=n.paths.find(t=>t.op!=="read")??n.paths[0],e=r&&s?`fs ${s.op} ${s.path}${n.paths.length>1?` +${n.paths.length-1}`:""}`:`fs ${n.reads} reads \xB7 ${n.writes} writes`;(0,emit_1.lensEmit)("fs","info",e,{name:"fs",kind:"fs-ops",...n},`fs:${emit_1.PROJECT}`,r)}}u(flush,"flush"),c(flush,"flush"),f(flush,"flush");const byteLen=f(r=>typeof r=="string"?Buffer.byteLength(r):Buffer.isBuffer(r)?r.length:0,"byteLen");function wrap(r,n,s){const e=r?.[n];if(!r||typeof e!="function"||e.__lensmcp)return;const t=s(e);t.__lensmcp=!0;try{r[n]=t}catch{}}u(wrap,"wrap"),c(wrap,"wrap"),f(wrap,"wrap");function flushFsWindowForTests(){timer&&clearTimeout(timer),flush()}u(flushFsWindowForTests,"flushFsWindowForTests"),c(flushFsWindowForTests,"flushFsWindowForTests"),f(flushFsWindowForTests,"flushFsWindowForTests");function tapFs(r=require("node:fs")){wrap(r,"readFileSync",s=>function(e,...t){const i=s.call(this,e,...t);return record("read",e,byteLen(i)),i}),wrap(r,"writeFileSync",s=>function(e,t,...i){const o=appending>0,l=s.call(this,e,t,...i);return o||record("write",e,byteLen(t)),l}),wrap(r,"appendFileSync",s=>function(e,t,...i){appending++;let o;try{o=s.call(this,e,t,...i)}finally{appending--}return record("append",e,byteLen(t)),o}),wrap(r,"readFile",s=>function(e,...t){const i=t[t.length-1];if(typeof i=="function"){const o=(0,flow_context_1.flowContext)();t[t.length-1]=(l,a)=>{l||record("read",e,byteLen(a),o),i(l,a)}}return s.call(this,e,...t)});for(const s of["writeFile","appendFile"])wrap(r,s,e=>function(t,i,...o){const l=o[o.length-1],a=appending>0;if(typeof l=="function"){const p=(0,flow_context_1.flowContext)();o[o.length-1]=w=>{!w&&!a&&record(s==="appendFile"?"append":"write",t,byteLen(i),p),l(w)}}if(s!=="appendFile")return e.call(this,t,i,...o);appending++;try{return e.call(this,t,i,...o)}finally{appending--}});const n=r.promises;wrap(n,"readFile",s=>async function(e,...t){const i=(0,flow_context_1.flowContext)(),o=await s.call(this,e,...t);return record("read",e,byteLen(o),i),o});for(const s of["writeFile","appendFile"])wrap(n,s,e=>async function(t,i,...o){const l=(0,flow_context_1.flowContext)(),a=await e.call(this,t,i,...o);return record(s==="appendFile"?"append":"write",t,byteLen(i),l),a});wrap(r,"createReadStream",s=>function(e,...t){return record("read",e,0,(0,flow_context_1.flowContext)(),!0),s.call(this,e,...t)}),wrap(r,"createWriteStream",s=>function(e,...t){return record("write",e,0,(0,flow_context_1.flowContext)(),!0),s.call(this,e,...t)})}u(tapFs,"tapFs"),c(tapFs,"tapFs"),f(tapFs,"tapFs");
1
+ "use strict";var h=Object.defineProperty;var c=(r,n)=>h(r,"name",{value:n,configurable:!0});var d=Object.defineProperty,f=c((r,n)=>d(r,"name",{value:n,configurable:!0}),"f");Object.defineProperty(exports,"__esModule",{value:!0}),exports.FsWindow=exports.OWN_EVENTS=void 0,exports.flushFsWindowForTests=flushFsWindowForTests,exports.tapFs=tapFs;const tslib_1=require("tslib"),os=tslib_1.__importStar(require("node:os")),emit_1=require("./emit"),flow_context_1=require("./flow-context"),PATHS_KEPT=50,PATHS_SENT=20;exports.OWN_EVENTS=4;const SLICES_KEPT=64;class FsSlice{static{c(this,"FsSlice")}static{f(this,"FsSlice")}constructor(n,s){this.flowId=n,this.requestId=s,this.reads=0,this.writes=0,this.bytesRead=0,this.bytesWritten=0,this.first=1/0,this.last=0,this.counts=new Map,this.ops=new Map}absorb(n){this.reads+=n.reads,this.writes+=n.writes,this.bytesRead+=n.bytesRead,this.bytesWritten+=n.bytesWritten;for(const[s,e]of n.counts)this.counts.set(s,(this.counts.get(s)??0)+e);for(const[s,e]of n.ops)this.ops.set(s,e)}payload(n={}){const s=[...this.counts.entries()].sort((t,i)=>i[1]-t[1]).slice(0,3).map(([t])=>t),e=[...this.ops.values()].sort((t,i)=>i.at-t.at).slice(0,PATHS_SENT);return{reads:this.reads,writes:this.writes,bytesRead:this.bytesRead,bytesWritten:this.bytesWritten,top:s,paths:e,...n}}}class FsWindow{static{c(this,"FsWindow")}static{f(this,"FsWindow")}constructor(){this.slices=new Map,this.kept=0}record(n,s,e,t,i,o=!1){let l=i?.flowId?`${i.flowId}\0${i.requestId??""}`:"";l&&!this.slices.has(l)&&this.slices.size>=SLICES_KEPT&&(l="");let a=this.slices.get(l);a||(a=l?new FsSlice(i?.flowId,i?.requestId):new FsSlice,this.slices.set(l,a)),n==="read"?(a.reads+=1,a.bytesRead+=e):(a.writes+=1,a.bytesWritten+=e),a.first=Math.min(a.first,t),a.last=Math.max(a.last,t),(a.counts.size<PATHS_KEPT||a.counts.has(s))&&a.counts.set(s,(a.counts.get(s)??0)+1);const u=`${n}\0${s}\0${i?.flowId??""}`,p=a.ops.get(u);p?(p.n+=1,p.bytes+=e,p.at=t,i?.requestId&&(p.requestId=i.requestId)):this.kept<PATHS_KEPT&&(this.kept+=1,a.ops.set(u,{path:s,op:n,n:1,bytes:e,...o?{stream:!0}:{},at:t,...i?.flowId?{flowId:i.flowId}:{},...i?.requestId?{requestId:i.requestId}:{}}))}drain(){if(!this.slices.size)return[];const n=[...this.slices.entries()].filter(([o])=>o!=="").sort(([o,l],[a,u])=>u.reads+u.writes-(l.reads+l.writes)||u.last-l.last||(o<a?-1:1)),s=n.slice(0,exports.OWN_EVENTS),e=n.slice(exports.OWN_EVENTS),t=this.slices.get("")??new FsSlice;for(const[,o]of e)t.absorb(o);const i=s.map(([,o])=>({ctx:{flowId:o.flowId,...o.requestId?{requestId:o.requestId}:{}},payload:o.payload({startedAt:o.first})}));return t.reads+t.writes>0&&i.push({payload:t.payload(e.length?{merged:e.length}:{})}),this.slices.clear(),this.kept=0,i}}exports.FsWindow=FsWindow;const current=new FsWindow;let timer=null;const TMP=os.tmpdir(),CWD=process.cwd(),SKIP=["node_modules","/.nx/","/dist/","/.git/",".lensmcp"],CODE=/\.(?:[cm]?[jt]sx?|map|node)$/;let appending=0;function trackedPath(r){if((0,emit_1.isLensWriting)())return null;const n=typeof r=="string"?r:Buffer.isBuffer(r)?r.toString():r instanceof URL?r.pathname:null;return!n||n===emit_1.EVENT_FILE||n.startsWith(TMP)||SKIP.some(s=>n.includes(s))?null:n}c(trackedPath,"trackedPath"),f(trackedPath,"trackedPath");function record(r,n,s=0,e,t=!1){const i=trackedPath(n);if(!i||r==="read"&&CODE.test(i))return;const o=i.startsWith(CWD)?i.slice(CWD.length+1):i;current.record(r,o,s,Date.now(),e??(0,flow_context_1.flowContext)(),t),timer||(timer=setTimeout(flush,1e3),timer.unref?.())}c(record,"record"),f(record,"record");function flush(){timer=null;for(const{ctx:r,payload:n}of current.drain()){const s=n.paths.find(t=>t.op!=="read")??n.paths[0],e=r&&s?`fs ${s.op} ${s.path}${n.paths.length>1?` +${n.paths.length-1}`:""}`:`fs ${n.reads} reads \xB7 ${n.writes} writes`;(0,emit_1.lensEmit)("fs","info",e,{name:"fs",kind:"fs-ops",...n},`fs:${emit_1.PROJECT}`,r)}}c(flush,"flush"),f(flush,"flush");const byteLen=f(r=>typeof r=="string"?Buffer.byteLength(r):Buffer.isBuffer(r)?r.length:0,"byteLen");function wrap(r,n,s){const e=r?.[n];if(!r||typeof e!="function"||e.__lensmcp)return;const t=s(e);t.__lensmcp=!0;try{r[n]=t}catch{}}c(wrap,"wrap"),f(wrap,"wrap");function flushFsWindowForTests(){timer&&clearTimeout(timer),flush()}c(flushFsWindowForTests,"flushFsWindowForTests"),f(flushFsWindowForTests,"flushFsWindowForTests");function tapFs(r=require("node:fs")){wrap(r,"readFileSync",s=>function(e,...t){const i=s.call(this,e,...t);return record("read",e,byteLen(i)),i}),wrap(r,"writeFileSync",s=>function(e,t,...i){const o=appending>0,l=s.call(this,e,t,...i);return o||record("write",e,byteLen(t)),l}),wrap(r,"appendFileSync",s=>function(e,t,...i){appending++;let o;try{o=s.call(this,e,t,...i)}finally{appending--}return record("append",e,byteLen(t)),o}),wrap(r,"readFile",s=>function(e,...t){const i=t[t.length-1];if(typeof i=="function"){const o=(0,flow_context_1.flowContext)();t[t.length-1]=(l,a)=>{l||record("read",e,byteLen(a),o),i(l,a)}}return s.call(this,e,...t)});for(const s of["writeFile","appendFile"])wrap(r,s,e=>function(t,i,...o){const l=o[o.length-1],a=appending>0;if(typeof l=="function"){const u=(0,flow_context_1.flowContext)();o[o.length-1]=p=>{!p&&!a&&record(s==="appendFile"?"append":"write",t,byteLen(i),u),l(p)}}if(s!=="appendFile")return e.call(this,t,i,...o);appending++;try{return e.call(this,t,i,...o)}finally{appending--}});const n=r.promises;wrap(n,"readFile",s=>async function(e,...t){const i=(0,flow_context_1.flowContext)(),o=await s.call(this,e,...t);return record("read",e,byteLen(o),i),o});for(const s of["writeFile","appendFile"])wrap(n,s,e=>async function(t,i,...o){const l=(0,flow_context_1.flowContext)(),a=await e.call(this,t,i,...o);return record(s==="appendFile"?"append":"write",t,byteLen(i),l),a});wrap(r,"createReadStream",s=>function(e,...t){return record("read",e,0,(0,flow_context_1.flowContext)(),!0),s.call(this,e,...t)}),wrap(r,"createWriteStream",s=>function(e,...t){return record("write",e,0,(0,flow_context_1.flowContext)(),!0),s.call(this,e,...t)})}c(tapFs,"tapFs"),f(tapFs,"tapFs");
@@ -1 +1 @@
1
- "use strict";var T=Object.defineProperty;var d=(s,e)=>T(s,"name",{value:e,configurable:!0});var A=Object.defineProperty,c=d((s,e)=>A(s,"name",{value:e,configurable:!0}),"c"),x=Object.defineProperty,a=c((s,e)=>x(s,"name",{value:e,configurable:!0}),"a");Object.defineProperty(exports,"__esModule",{value:!0}),exports.EXCHANGE_ID=void 0,exports.tapIngress=tapIngress,exports.resetIngressTapForTests=resetIngressTapForTests;const tslib_1=require("tslib"),http=tslib_1.__importStar(require("node:http")),zlib=tslib_1.__importStar(require("node:zlib")),headless_flow_1=require("@lensmcp/core/headless-flow"),http_exchange_1=require("@lensmcp/core/http-exchange"),emit_1=require("./emit"),http_store_1=require("./http-store");exports.EXCHANGE_ID=Symbol.for("lensmcp.exchangeId");const MAX_READ=2*1024*1024,MAX_PATH_CHARS=256;let originalEmit;function tapIngress(){if(originalEmit)return;const s=(0,http_store_1.httpCaptureMode)();if(s==="off")return;const e=http.Server.prototype,r=e.emit;originalEmit=r,e.emit=function(t,...i){if(t==="request")try{watch(i[0],i[1],s)}catch{}return r.call(this,t,...i)}}d(tapIngress,"tapIngress"),c(tapIngress,"tapIngress"),a(tapIngress,"tapIngress");function resetIngressTapForTests(){originalEmit&&(http.Server.prototype.emit=originalEmit),originalEmit=void 0}d(resetIngressTapForTests,"resetIngressTapForTests"),c(resetIngressTapForTests,"resetIngressTapForTests"),a(resetIngressTapForTests,"resetIngressTapForTests");const one=a(s=>s===void 0?void 0:Array.isArray(s)?s.join(", "):String(s),"one"),pairs=a(s=>Object.entries(s).flatMap(([e,r])=>r===void 0?[]:[[e,one(r)]]),"pairs");class Tee{static{d(this,"Tee")}static{c(this,"Tee")}static{a(this,"Tee")}constructor(){this.chunks=[],this.read=0,this.size=0}take(e,r){if(e==null||typeof e=="function")return;const t=Buffer.isBuffer(e)?e:e instanceof Uint8Array?Buffer.from(e):typeof e=="string"?Buffer.from(e,typeof r=="string"?r:"utf8"):void 0;t&&(this.size+=t.length,this.read<MAX_READ&&(this.chunks.push(t),this.read+=t.length))}bytes(){return Buffer.concat(this.chunks)}}function watch(s,e,r){if(!s||!e||s[exports.EXCHANGE_ID])return;const t=s.url??"/",i=t.indexOf("?"),l=i<0?t:t.slice(0,i);if((0,headless_flow_1.isProbePath)(l))return;const p=(0,http_store_1.newExchangeId)();s[exports.EXCHANGE_ID]=p;const m=Date.now(),g=r==="bodies",y=new Tee,u=new Tee;if(g){const b=s.emit;s.emit=function(o,...n){return o==="data"&&y.take(n[0]),b.call(this,o,...n)};const w=e.write,_=e.end;e.write=function(o,...n){return u.take(o,n[0]),w.call(this,o,...n)},e.end=function(o,...n){return u.take(o,n[0]),_.call(this,o,...n)}}let h=!1;const f=a(()=>{if(!h){h=!0;try{(0,http_store_1.writeHttpExchange)(exchangeOf(p,s,e,{url:t,q:i,path:l,startedAt:m,bodies:g,sent:y,answered:u}))}catch{}}},"finish");e.once("finish",f),e.once("close",f)}d(watch,"watch"),c(watch,"watch"),a(watch,"watch");function unpacked(s,e){try{if(s==="gzip"||s==="x-gzip")return zlib.gunzipSync(e,{maxOutputLength:MAX_READ});if(s==="br")return zlib.brotliDecompressSync(e,{maxOutputLength:MAX_READ});if(s==="deflate")return zlib.inflateSync(e,{maxOutputLength:MAX_READ})}catch{return}}d(unpacked,"unpacked"),c(unpacked,"unpacked"),a(unpacked,"unpacked");function exchangeOf(s,e,r,t){const i=[],l=[],p=[],m=(0,http_store_1.redactHeaders)(pairs(e.headers));i.push(...m.redacted);const g=(0,http_store_1.redactHeaders)(pairs(r.getHeaders()));i.push(...g.redacted);const y=t.bodies&&t.q>=0?(0,http_store_1.redactQuery)(t.url.slice(t.q)):[];let u;t.bodies&&t.sent.size&&(u=(0,http_store_1.keepBody)(one(e.headers["content-type"])??"",t.sent.bytes(),t.sent.size,l));let h;if(t.bodies&&t.answered.size){const n=one(r.getHeader("content-type"))??"",E=(one(r.getHeader("content-encoding"))??"").trim().toLowerCase();if(!E||E==="identity")h=(0,http_store_1.keepBody)(n,t.answered.bytes(),t.answered.size,p);else{const I=t.answered.size<=MAX_READ?unpacked(E,t.answered.bytes()):void 0;h=I?(0,http_store_1.keepBody)(n,I,I.length,p):{contentType:n.split(";")[0].trim().toLowerCase(),size:t.answered.size,kept:0,truncated:!1,omitted:"encoded"}}}const f=one(e.headers.host)??"localhost",b=t.path.length>MAX_PATH_CHARS?`${t.path.slice(0,MAX_PATH_CHARS)}\u2026`:t.path,w=one(e.headers["x-lensmcp-flow-id"]),_=one(e.headers[http_exchange_1.LENS_REQUEST_ID_HEADER])||one(e.headers["x-request-id"]),o=!r.writableFinished;return{schemaVersion:1,id:s,capturedAt:Date.now(),side:"ingress",service:emit_1.PROJECT,...w?{flowId:w}:{},..._?{requestId:_}:{},method:(e.method??"GET").toUpperCase(),url:`http://${f}${b}`,host:f.split(":")[0]??f,path:b,status:r.statusCode,...r.statusMessage?{statusText:r.statusMessage}:{},...o?{error:"the client went away before the answer ended"}:{},startedAt:t.startedAt,durationMs:Date.now()-t.startedAt,capture:t.bodies?"bodies":"headers",request:{headers:m.headers,...y.length?{query:y}:{},...u?{body:u}:{}},response:{headers:g.headers,...h?{body:h}:{}},redacted:{headers:[...new Set(i)],bodyFields:[...l.map(n=>`request.${n}`),...p.map(n=>`response.${n}`)]}}}d(exchangeOf,"exchangeOf"),c(exchangeOf,"exchangeOf"),a(exchangeOf,"exchangeOf");
1
+ "use strict";var A=Object.defineProperty;var c=(r,e)=>A(r,"name",{value:e,configurable:!0});var x=Object.defineProperty,a=c((r,e)=>x(r,"name",{value:e,configurable:!0}),"a");Object.defineProperty(exports,"__esModule",{value:!0}),exports.EXCHANGE_ID=void 0,exports.tapIngress=tapIngress,exports.resetIngressTapForTests=resetIngressTapForTests;const tslib_1=require("tslib"),http=tslib_1.__importStar(require("node:http")),zlib=tslib_1.__importStar(require("node:zlib")),headless_flow_1=require("@lensmcp/core/headless-flow"),http_exchange_1=require("@lensmcp/core/http-exchange"),emit_1=require("./emit"),http_store_1=require("./http-store");exports.EXCHANGE_ID=Symbol.for("lensmcp.exchangeId");const MAX_READ=2*1024*1024,MAX_PATH_CHARS=256;let originalEmit;function tapIngress(){if(originalEmit)return;const r=(0,http_store_1.httpCaptureMode)();if(r==="off")return;const e=http.Server.prototype,s=e.emit;originalEmit=s,e.emit=function(t,...i){if(t==="request")try{watch(i[0],i[1],r)}catch{}return s.call(this,t,...i)}}c(tapIngress,"tapIngress"),a(tapIngress,"tapIngress");function resetIngressTapForTests(){originalEmit&&(http.Server.prototype.emit=originalEmit),originalEmit=void 0}c(resetIngressTapForTests,"resetIngressTapForTests"),a(resetIngressTapForTests,"resetIngressTapForTests");const one=a(r=>r===void 0?void 0:Array.isArray(r)?r.join(", "):String(r),"one"),pairs=a(r=>Object.entries(r).flatMap(([e,s])=>s===void 0?[]:[[e,one(s)]]),"pairs");class Tee{static{c(this,"Tee")}static{a(this,"Tee")}constructor(){this.chunks=[],this.read=0,this.size=0}take(e,s){if(e==null||typeof e=="function")return;const t=Buffer.isBuffer(e)?e:e instanceof Uint8Array?Buffer.from(e):typeof e=="string"?Buffer.from(e,typeof s=="string"?s:"utf8"):void 0;t&&(this.size+=t.length,this.read<MAX_READ&&(this.chunks.push(t),this.read+=t.length))}bytes(){return Buffer.concat(this.chunks)}}function watch(r,e,s){if(!r||!e||r[exports.EXCHANGE_ID])return;const t=r.url??"/",i=t.indexOf("?"),l=i<0?t:t.slice(0,i);if((0,headless_flow_1.isProbePath)(l))return;const h=(0,http_store_1.newExchangeId)();r[exports.EXCHANGE_ID]=h;const y=Date.now(),f=s==="bodies",g=new Tee,d=new Tee;if(f){const m=r.emit;r.emit=function(o,...n){return o==="data"&&g.take(n[0]),m.call(this,o,...n)};const w=e.write,b=e.end;e.write=function(o,...n){return d.take(o,n[0]),w.call(this,o,...n)},e.end=function(o,...n){return d.take(o,n[0]),b.call(this,o,...n)}}let u=!1;const p=a(()=>{if(!u){u=!0;try{(0,http_store_1.writeHttpExchange)(exchangeOf(h,r,e,{url:t,q:i,path:l,startedAt:y,bodies:f,sent:g,answered:d}))}catch{}}},"finish");e.once("finish",p),e.once("close",p)}c(watch,"watch"),a(watch,"watch");function unpacked(r,e){try{if(r==="gzip"||r==="x-gzip")return zlib.gunzipSync(e,{maxOutputLength:MAX_READ});if(r==="br")return zlib.brotliDecompressSync(e,{maxOutputLength:MAX_READ});if(r==="deflate")return zlib.inflateSync(e,{maxOutputLength:MAX_READ})}catch{return}}c(unpacked,"unpacked"),a(unpacked,"unpacked");function exchangeOf(r,e,s,t){const i=[],l=[],h=[],y=(0,http_store_1.redactHeaders)(pairs(e.headers));i.push(...y.redacted);const f=(0,http_store_1.redactHeaders)(pairs(s.getHeaders()));i.push(...f.redacted);const g=t.bodies&&t.q>=0?(0,http_store_1.redactQuery)(t.url.slice(t.q)):[];let d;t.bodies&&t.sent.size&&(d=(0,http_store_1.keepBody)(one(e.headers["content-type"])??"",t.sent.bytes(),t.sent.size,l));let u;if(t.bodies&&t.answered.size){const n=one(s.getHeader("content-type"))??"",_=(one(s.getHeader("content-encoding"))??"").trim().toLowerCase();if(!_||_==="identity")u=(0,http_store_1.keepBody)(n,t.answered.bytes(),t.answered.size,h);else{const E=t.answered.size<=MAX_READ?unpacked(_,t.answered.bytes()):void 0;u=E?(0,http_store_1.keepBody)(n,E,E.length,h):{contentType:n.split(";")[0].trim().toLowerCase(),size:t.answered.size,kept:0,truncated:!1,omitted:"encoded"}}}const p=one(e.headers.host)??"localhost",m=t.path.length>MAX_PATH_CHARS?`${t.path.slice(0,MAX_PATH_CHARS)}\u2026`:t.path,w=one(e.headers["x-lensmcp-flow-id"]),b=one(e.headers[http_exchange_1.LENS_REQUEST_ID_HEADER])||one(e.headers["x-request-id"]),o=!s.writableFinished;return{schemaVersion:1,id:r,capturedAt:Date.now(),side:"ingress",service:emit_1.PROJECT,...w?{flowId:w}:{},...b?{requestId:b}:{},method:(e.method??"GET").toUpperCase(),url:`http://${p}${m}`,host:p.split(":")[0]??p,path:m,status:s.statusCode,...s.statusMessage?{statusText:s.statusMessage}:{},...o?{error:"the client went away before the answer ended"}:{},startedAt:t.startedAt,durationMs:Date.now()-t.startedAt,capture:t.bodies?"bodies":"headers",request:{headers:y.headers,...g.length?{query:g}:{},...d?{body:d}:{}},response:{headers:f.headers,...u?{body:u}:{}},redacted:{headers:[...new Set(i)],bodyFields:[...l.map(n=>`request.${n}`),...h.map(n=>`response.${n}`)]}}}c(exchangeOf,"exchangeOf"),a(exchangeOf,"exchangeOf");
@@ -1 +1 @@
1
- "use strict";var m=Object.defineProperty;var p=(a,e)=>m(a,"name",{value:e,configurable:!0});var y=Object.defineProperty,d=p((a,e)=>y(a,"name",{value:e,configurable:!0}),"d"),_=Object.defineProperty,f=d((a,e)=>_(a,"name",{value:e,configurable:!0}),"f");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapLoopCallbacks=tapLoopCallbacks;const node_async_hooks_1=require("node:async_hooks"),node_perf_hooks_1=require("node:perf_hooks"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),loop_identity_1=require("./loop-identity");function tapLoopCallbacks(a=50){const e=new Map,r=new Map;let n=!1,u=!1,s=!1,i=0;const c=[],k=(0,node_async_hooks_1.createHook)({init(t,l){n||(e.set(t,l),e.size>2e4&&e.delete(e.keys().next().value))},before(t){if(!(n||!e.has(t)))try{r.set(t,{start:node_perf_hooks_1.performance.now(),at:Date.now(),type:e.get(t)??"unknown"})}catch{}},after(t){const l=r.get(t);if(r.delete(t),!l||n)return;const b=node_perf_hooks_1.performance.now()-l.start;if(!(b<a)){if(c.length>=50){i++;return}c.push({...l,duration:b,id:t,context:(0,flow_context_1.flowContext)()}),!s&&(s=!0,n=!0,setImmediate(()=>{if(s=!1,!u){n=!0;try{for(const o of c.splice(0))(0,emit_1.lensEmit)("perf",o.duration>=1e3?"error":"warning",`Event loop callback blocked for ${o.duration.toFixed(1)}ms (${o.type})`,{kind:"event-loop-stall",incidentId:`${loop_identity_1.NODE_LOOP.id}:callback:${o.id}:${o.start}`,loop:loop_identity_1.NODE_LOOP,startedAt:o.at,durationMs:Math.round(o.duration*100)/100,state:"recovered",mechanism:"callback",callbackType:o.type,...i?{droppedIncidents:i}:{}},"perf:event-loop-stall",o.context,"performance");i=0}finally{n=!1}}}),n=!1)}},destroy(t){e.delete(t),r.delete(t)}});return k.enable(),()=>{u=!0,k.disable(),e.clear(),r.clear(),c.length=0}}p(tapLoopCallbacks,"tapLoopCallbacks"),d(tapLoopCallbacks,"tapLoopCallbacks"),f(tapLoopCallbacks,"tapLoopCallbacks");
1
+ "use strict";var y=Object.defineProperty;var d=(r,e)=>y(r,"name",{value:e,configurable:!0});var _=Object.defineProperty,f=d((r,e)=>_(r,"name",{value:e,configurable:!0}),"f");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapLoopCallbacks=tapLoopCallbacks;const node_async_hooks_1=require("node:async_hooks"),node_perf_hooks_1=require("node:perf_hooks"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),loop_identity_1=require("./loop-identity");function tapLoopCallbacks(r=50){const e=new Map,a=new Map;let n=!1,p=!1,c=!1,i=0;const s=[],u=(0,node_async_hooks_1.createHook)({init(t,l){n||(e.set(t,l),e.size>2e4&&e.delete(e.keys().next().value))},before(t){if(!(n||!e.has(t)))try{a.set(t,{start:node_perf_hooks_1.performance.now(),at:Date.now(),type:e.get(t)??"unknown"})}catch{}},after(t){const l=a.get(t);if(a.delete(t),!l||n)return;const k=node_perf_hooks_1.performance.now()-l.start;if(!(k<r)){if(s.length>=50){i++;return}s.push({...l,duration:k,id:t,context:(0,flow_context_1.flowContext)()}),!c&&(c=!0,n=!0,setImmediate(()=>{if(c=!1,!p){n=!0;try{for(const o of s.splice(0))(0,emit_1.lensEmit)("perf",o.duration>=1e3?"error":"warning",`Event loop callback blocked for ${o.duration.toFixed(1)}ms (${o.type})`,{kind:"event-loop-stall",incidentId:`${loop_identity_1.NODE_LOOP.id}:callback:${o.id}:${o.start}`,loop:loop_identity_1.NODE_LOOP,startedAt:o.at,durationMs:Math.round(o.duration*100)/100,state:"recovered",mechanism:"callback",callbackType:o.type,...i?{droppedIncidents:i}:{}},"perf:event-loop-stall",o.context,"performance");i=0}finally{n=!1}}}),n=!1)}},destroy(t){e.delete(t),a.delete(t)}});return u.enable(),()=>{p=!0,u.disable(),e.clear(),a.clear(),s.length=0}}d(tapLoopCallbacks,"tapLoopCallbacks"),f(tapLoopCallbacks,"tapLoopCallbacks");
@@ -1,6 +1,6 @@
1
- "use strict";var x=Object.defineProperty;var c=(e,t)=>x(e,"name",{value:t,configurable:!0});var T=Object.defineProperty,s=c((e,t)=>T(e,"name",{value:t,configurable:!0}),"s"),S=Object.defineProperty,o=s((e,t)=>S(e,"name",{value:t,configurable:!0}),"o");Object.defineProperty(exports,"__esModule",{value:!0}),exports.isLoggerEcho=isLoggerEcho,exports.resetNestLoggerTapForTests=resetNestLoggerTapForTests,exports.nestLoggerTap=nestLoggerTap;const redact_1=require("@lensmcp/core/redact"),flood_guard_1=require("./flood-guard"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),LEVELS=["verbose","debug","log","warn","error","fatal"],SEVERITY={verbose:"debug",debug:"debug",log:"info",warn:"warning",error:"error",fatal:"fatal"},MAX_TEXT_CHARS=4e3,TITLE_CHARS=240,shapeGuard=(0,flood_guard_1.createEventFloodGuard)({burst:30,perSec:5}),podGuard=(0,flood_guard_1.createEventFloodGuard)({burst:400,perSec:100});let depth=0;const recent=[],ECHO_WINDOW_MS=2e3,ECHO_NEEDLE_CHARS=96,ECHO_MIN_CHARS=12,MAX_RECENT=64;function isLoggerEcho(e,t=Date.now()){for(let r=recent.length-1;r>=0;r--){const n=recent[r];if(t-n.at>ECHO_WINDOW_MS)return recent.splice(0,r+1),!1;if(e.includes(n.needle)||n.escaped!==void 0&&e.includes(n.escaped))return recent.splice(r,1),!0}return!1}c(isLoggerEcho,"isLoggerEcho"),s(isLoggerEcho,"isLoggerEcho"),o(isLoggerEcho,"isLoggerEcho");function expectEcho(e,t){const r=e.split(`
2
- `,1)[0]??"";if(r.length<ECHO_MIN_CHARS)return;const n=r.slice(0,ECHO_NEEDLE_CHARS),i=JSON.stringify(n).slice(1,-1);recent.push({needle:n,at:t,...i!==n?{escaped:i}:{}}),recent.length>MAX_RECENT&&recent.splice(0,recent.length-MAX_RECENT)}c(expectEcho,"expectEcho"),s(expectEcho,"expectEcho"),o(expectEcho,"expectEcho");function resetNestLoggerTapForTests(){recent.length=0,depth=0}c(resetNestLoggerTapForTests,"resetNestLoggerTapForTests"),s(resetNestLoggerTapForTests,"resetNestLoggerTapForTests"),o(resetNestLoggerTapForTests,"resetNestLoggerTapForTests");function textOf(e){if(typeof e=="string")return e;if(e instanceof Error)return e.stack??`${e.name}: ${e.message}`;if(e===null||typeof e!="object")return String(e);try{return JSON.stringify(e)??String(e)}catch{return Object.prototype.toString.call(e)}}c(textOf,"textOf"),s(textOf,"textOf"),o(textOf,"textOf");function openingOf(e){return typeof e=="string"?e.split(`
1
+ "use strict";var T=Object.defineProperty;var s=(e,t)=>T(e,"name",{value:t,configurable:!0});var S=Object.defineProperty,o=s((e,t)=>S(e,"name",{value:t,configurable:!0}),"o");Object.defineProperty(exports,"__esModule",{value:!0}),exports.isLoggerEcho=isLoggerEcho,exports.resetNestLoggerTapForTests=resetNestLoggerTapForTests,exports.nestLoggerTap=nestLoggerTap;const redact_1=require("@lensmcp/core/redact"),flood_guard_1=require("./flood-guard"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),LEVELS=["verbose","debug","log","warn","error","fatal"],SEVERITY={verbose:"debug",debug:"debug",log:"info",warn:"warning",error:"error",fatal:"fatal"},MAX_TEXT_CHARS=4e3,TITLE_CHARS=240,shapeGuard=(0,flood_guard_1.createEventFloodGuard)({burst:30,perSec:5}),podGuard=(0,flood_guard_1.createEventFloodGuard)({burst:400,perSec:100});let depth=0;const recent=[],ECHO_WINDOW_MS=2e3,ECHO_NEEDLE_CHARS=96,ECHO_MIN_CHARS=12,MAX_RECENT=64;function isLoggerEcho(e,t=Date.now()){for(let r=recent.length-1;r>=0;r--){const n=recent[r];if(t-n.at>ECHO_WINDOW_MS)return recent.splice(0,r+1),!1;if(e.includes(n.needle)||n.escaped!==void 0&&e.includes(n.escaped))return recent.splice(r,1),!0}return!1}s(isLoggerEcho,"isLoggerEcho"),o(isLoggerEcho,"isLoggerEcho");function expectEcho(e,t){const r=e.split(`
2
+ `,1)[0]??"";if(r.length<ECHO_MIN_CHARS)return;const n=r.slice(0,ECHO_NEEDLE_CHARS),c=JSON.stringify(n).slice(1,-1);recent.push({needle:n,at:t,...c!==n?{escaped:c}:{}}),recent.length>MAX_RECENT&&recent.splice(0,recent.length-MAX_RECENT)}s(expectEcho,"expectEcho"),o(expectEcho,"expectEcho");function resetNestLoggerTapForTests(){recent.length=0,depth=0}s(resetNestLoggerTapForTests,"resetNestLoggerTapForTests"),o(resetNestLoggerTapForTests,"resetNestLoggerTapForTests");function textOf(e){if(typeof e=="string")return e;if(e instanceof Error)return e.stack??`${e.name}: ${e.message}`;if(e===null||typeof e!="object")return String(e);try{return JSON.stringify(e)??String(e)}catch{return Object.prototype.toString.call(e)}}s(textOf,"textOf"),o(textOf,"textOf");function openingOf(e){return typeof e=="string"?e.split(`
3
3
  `,1)[0]??"":e instanceof Error?`${e.name}: ${e.message}`.split(`
4
- `,1)[0]??"":e===null||typeof e!="object"?String(e):"{object}"}c(openingOf,"openingOf"),s(openingOf,"openingOf"),o(openingOf,"openingOf");const looksLikeStack=o(e=>typeof e=="string"&&/\n\s+at\s/.test(e),"looksLikeStack");function shapeOf(e){return e.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,"#").replace(/\b[0-9a-f]{12,}\b/gi,"#").replace(/\d+/g,"#").slice(0,80)}c(shapeOf,"shapeOf"),s(shapeOf,"shapeOf"),o(shapeOf,"shapeOf");function capture(e,t,r,n){const i=(0,flow_context_1.flowContext)();if(!i?.flowId&&!i?.requestId)return;const f=t?.context,a=n.slice();let g=typeof f=="string"&&f?f:void 0;!g&&a.length>0&&typeof a[a.length-1]=="string"&&!looksLikeStack(a[a.length-1])&&(g=a.pop());const E=openingOf(r),L=`${g??""}:${shapeOf((0,redact_1.redactText)(E.slice(0,MAX_TEXT_CHARS*2)))}`,_=Date.now(),d=shapeGuard.admit(L),y=d.ok?podGuard.admit("pod"):d;if(!d.ok||!y.ok){expectEcho(E,_);return}const b=[r,...a].filter(p=>p!==void 0).map(textOf);let h="";for(const p of b)h+=h===""?p:(looksLikeStack(p)?`
5
- `:" ")+p;const l=(0,redact_1.redactText)(h.slice(0,MAX_TEXT_CHARS*2)).slice(0,MAX_TEXT_CHARS);if(!l)return;const u=l.split(`
6
- `,1)[0]??"",O=looksLikeStack(l);(0,emit_1.lensLog)(SEVERITY[e],u.length>TITLE_CHARS?`${u.slice(0,TITLE_CHARS)}\u2026`:u,{...O?{stack:l}:l!==u||u.length>TITLE_CHARS?{text:l}:{},stream:"logger",level:e,...g?{logger:g}:{},bucket:L,suppressed:d.suppressed+y.suppressed});for(const p of b)expectEcho(p,_)}c(capture,"capture"),s(capture,"capture"),o(capture,"capture");function wrap(e,t){const r=e[t];if(typeof r!="function"||r.__lensmcpLog)return;const n=o(function(i,...f){if(depth===0)try{capture(t,this,i,f)}catch{}depth+=1;try{return r.call(this,i,...f)}finally{depth-=1}},"wrapped");n.__lensmcpLog=!0,e[t]=n}c(wrap,"wrap"),s(wrap,"wrap"),o(wrap,"wrap");function nestLoggerTap(e){if(process.env.LENSMCP_LOGS==="0")return!0;const t=e?.Logger;if(typeof t!="function"||!t.prototype)return!1;for(const r of LEVELS)wrap(t.prototype,r),wrap(t,r);return!0}c(nestLoggerTap,"nestLoggerTap"),s(nestLoggerTap,"nestLoggerTap"),o(nestLoggerTap,"nestLoggerTap");
4
+ `,1)[0]??"":e===null||typeof e!="object"?String(e):"{object}"}s(openingOf,"openingOf"),o(openingOf,"openingOf");const looksLikeStack=o(e=>typeof e=="string"&&/\n\s+at\s/.test(e),"looksLikeStack");function shapeOf(e){return e.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,"#").replace(/\b[0-9a-f]{12,}\b/gi,"#").replace(/\d+/g,"#").slice(0,80)}s(shapeOf,"shapeOf"),o(shapeOf,"shapeOf");function capture(e,t,r,n){const c=(0,flow_context_1.flowContext)();if(!c?.flowId&&!c?.requestId)return;const l=t?.context,i=n.slice();let f=typeof l=="string"&&l?l:void 0;!f&&i.length>0&&typeof i[i.length-1]=="string"&&!looksLikeStack(i[i.length-1])&&(f=i.pop());const h=openingOf(r),E=`${f??""}:${shapeOf((0,redact_1.redactText)(h.slice(0,MAX_TEXT_CHARS*2)))}`,_=Date.now(),u=shapeGuard.admit(E),L=u.ok?podGuard.admit("pod"):u;if(!u.ok||!L.ok){expectEcho(h,_);return}const y=[r,...i].filter(a=>a!==void 0).map(textOf);let d="";for(const a of y)d+=d===""?a:(looksLikeStack(a)?`
5
+ `:" ")+a;const p=(0,redact_1.redactText)(d.slice(0,MAX_TEXT_CHARS*2)).slice(0,MAX_TEXT_CHARS);if(!p)return;const g=p.split(`
6
+ `,1)[0]??"",b=looksLikeStack(p);(0,emit_1.lensLog)(SEVERITY[e],g.length>TITLE_CHARS?`${g.slice(0,TITLE_CHARS)}\u2026`:g,{...b?{stack:p}:p!==g||g.length>TITLE_CHARS?{text:p}:{},stream:"logger",level:e,...f?{logger:f}:{},bucket:E,suppressed:u.suppressed+L.suppressed});for(const a of y)expectEcho(a,_)}s(capture,"capture"),o(capture,"capture");function wrap(e,t){const r=e[t];if(typeof r!="function"||r.__lensmcpLog)return;const n=o(function(c,...l){if(depth===0)try{capture(t,this,c,l)}catch{}depth+=1;try{return r.call(this,c,...l)}finally{depth-=1}},"wrapped");n.__lensmcpLog=!0,e[t]=n}s(wrap,"wrap"),o(wrap,"wrap");function nestLoggerTap(e){if(process.env.LENSMCP_LOGS==="0")return!0;const t=e?.Logger;if(typeof t!="function"||!t.prototype)return!1;for(const r of LEVELS)wrap(t.prototype,r),wrap(t,r);return!0}s(nestLoggerTap,"nestLoggerTap"),o(nestLoggerTap,"nestLoggerTap");
package/lib/tap-nest.js CHANGED
@@ -1 +1 @@
1
- "use strict";var y=Object.defineProperty;var p=(e,t)=>y(e,"name",{value:t,configurable:!0});var d=Object.defineProperty,c=p((e,t)=>d(e,"name",{value:t,configurable:!0}),"c"),f=Object.defineProperty,s=c((e,t)=>f(e,"name",{value:t,configurable:!0}),"s");Object.defineProperty(exports,"__esModule",{value:!0}),exports.installChildAppBridge=installChildAppBridge,exports.nestTap=nestTap;const emit_1=require("./emit"),WRAPPED=Symbol.for("lensmcp.wrappedRoot"),captures=[],waiters=[];function pushCapture(e){const t=waiters.shift();t?(clearTimeout(t.timer),t.resolve(e)):captures.push(e)}p(pushCapture,"pushCapture"),c(pushCapture,"pushCapture"),s(pushCapture,"pushCapture");function nextCapture(e=6e4){const t=captures.shift();return t?Promise.resolve(t):new Promise((n,o)=>{const i={resolve:n,reject:o,timer:setTimeout(()=>{const r=waiters.indexOf(i);r>=0&&waiters.splice(r,1),o(new Error("[lensmcp] no NestJS app captured within 60s \u2014 does main.ts call app.listen()? (zero-touch pods boot by running your main and intercepting listen)"))},e)};i.timer.unref?.(),waiters.push(i)})}p(nextCapture,"nextCapture"),c(nextCapture,"nextCapture"),s(nextCapture,"nextCapture");function installChildAppBridge(){if(process.env.APP_RUNNER!=="1")return;const e=global,t=s(()=>nextCapture(),"factory");e.createChildApp=t,e.__lensmcpCreateChildApp=t}p(installChildAppBridge,"installChildAppBridge"),c(installChildAppBridge,"installChildAppBridge"),s(installChildAppBridge,"installChildAppBridge");function nestTap(e){const t=e,n=t?.NestFactory,o=n?.create;if(!n||typeof o!="function")return!1;if(o.__lensmcp)return!0;const i=s(async function(r,...l){let a=r;const u=r,m=!!(u?.[WRAPPED]||u?.module?.[WRAPPED]);if(process.env.LENSMCP_NEST!=="0"&&!m)try{a=await buildLensmcpRoot(r)}catch{a=r}return o.call(this??n,a,...l)},"wrapped");if(i.__lensmcp=!0,n.create=i,process.env.APP_RUNNER==="1"){const r=t?.NestApplication?.prototype,l=r?.listen;if(r&&typeof l=="function"&&!l.__lensmcp){const a=s(async function(u,...m){return captureApp(this,u).catch(h=>(console.error("[lensmcp] pod capture failed, falling back to TCP listen:",h),l.call(this,u,...m)))},"listenWrapped");a.__lensmcp=!0,r.listen=a}}return!0}p(nestTap,"nestTap"),c(nestTap,"nestTap"),s(nestTap,"nestTap");async function buildLensmcpRoot(e){const t=await import("@lensmcp/nest-instrumentation"),n=require("@nestjs/common"),o=t.LensmcpModule.forRoot({projectName:emit_1.PROJECT,trace:{autoInstrumentMethods:!0},memory:{mode:"light",scope:"all"}});class i{static{p(this,"i")}static{c(this,"n")}static{s(this,"LensmcpZeroTouchRoot")}}return i[WRAPPED]=!0,n.Module({imports:[o,e]})(i),i}p(buildLensmcpRoot,"buildLensmcpRoot"),c(buildLensmcpRoot,"buildLensmcpRoot"),s(buildLensmcpRoot,"buildLensmcpRoot");async function captureApp(e,t){await e.init();let n=e.getHttpAdapter?.()?.getInstance?.();if(typeof n!="function"){const o=n;o?.ready&&await o.ready(),typeof o?.routing=="function"&&(n=s((i,r)=>o.routing(i,r),"handler"))}if(typeof n!="function")throw new Error("[lensmcp] cannot derive a request handler from the HTTP adapter");return pushCapture({handler:n,serviceConfig:{port:t??process.env.PORT??0},close:s(()=>Promise.resolve(e.close()).then(()=>{}),"close"),app:e}),e.getHttpServer?.()}p(captureApp,"captureApp"),c(captureApp,"captureApp"),s(captureApp,"captureApp");
1
+ "use strict";var d=Object.defineProperty;var c=(e,t)=>d(e,"name",{value:t,configurable:!0});var f=Object.defineProperty,s=c((e,t)=>f(e,"name",{value:t,configurable:!0}),"s");Object.defineProperty(exports,"__esModule",{value:!0}),exports.installChildAppBridge=installChildAppBridge,exports.nestTap=nestTap;const emit_1=require("./emit"),WRAPPED=Symbol.for("lensmcp.wrappedRoot"),captures=[],waiters=[];function pushCapture(e){const t=waiters.shift();t?(clearTimeout(t.timer),t.resolve(e)):captures.push(e)}c(pushCapture,"pushCapture"),s(pushCapture,"pushCapture");function nextCapture(e=6e4){const t=captures.shift();return t?Promise.resolve(t):new Promise((n,r)=>{const i={resolve:n,reject:r,timer:setTimeout(()=>{const o=waiters.indexOf(i);o>=0&&waiters.splice(o,1),r(new Error("[lensmcp] no NestJS app captured within 60s \u2014 does main.ts call app.listen()? (zero-touch pods boot by running your main and intercepting listen)"))},e)};i.timer.unref?.(),waiters.push(i)})}c(nextCapture,"nextCapture"),s(nextCapture,"nextCapture");function installChildAppBridge(){if(process.env.APP_RUNNER!=="1")return;const e=global,t=s(()=>nextCapture(),"factory");e.createChildApp=t,e.__lensmcpCreateChildApp=t}c(installChildAppBridge,"installChildAppBridge"),s(installChildAppBridge,"installChildAppBridge");function nestTap(e){const t=e,n=t?.NestFactory,r=n?.create;if(!n||typeof r!="function")return!1;if(r.__lensmcp)return!0;const i=s(async function(o,...a){let p=o;const l=o,u=!!(l?.[WRAPPED]||l?.module?.[WRAPPED]);if(process.env.LENSMCP_NEST!=="0"&&!u)try{p=await buildLensmcpRoot(o)}catch{p=o}return r.call(this??n,p,...a)},"wrapped");if(i.__lensmcp=!0,n.create=i,process.env.APP_RUNNER==="1"){const o=t?.NestApplication?.prototype,a=o?.listen;if(o&&typeof a=="function"&&!a.__lensmcp){const p=s(async function(l,...u){return captureApp(this,l).catch(m=>(console.error("[lensmcp] pod capture failed, falling back to TCP listen:",m),a.call(this,l,...u)))},"listenWrapped");p.__lensmcp=!0,o.listen=p}}return!0}c(nestTap,"nestTap"),s(nestTap,"nestTap");async function buildLensmcpRoot(e){const t=await import("@lensmcp/nest-instrumentation"),n=require("@nestjs/common"),r=t.LensmcpModule.forRoot({projectName:emit_1.PROJECT,trace:{autoInstrumentMethods:!0},memory:{mode:"light",scope:"all"}});class i{static{c(this,"n")}static{s(this,"LensmcpZeroTouchRoot")}}return i[WRAPPED]=!0,n.Module({imports:[r,e]})(i),i}c(buildLensmcpRoot,"buildLensmcpRoot"),s(buildLensmcpRoot,"buildLensmcpRoot");async function captureApp(e,t){await e.init();let n=e.getHttpAdapter?.()?.getInstance?.();if(typeof n!="function"){const r=n;r?.ready&&await r.ready(),typeof r?.routing=="function"&&(n=s((i,o)=>r.routing(i,o),"handler"))}if(typeof n!="function")throw new Error("[lensmcp] cannot derive a request handler from the HTTP adapter");return pushCapture({handler:n,serviceConfig:{port:t??process.env.PORT??0},close:s(()=>Promise.resolve(e.close()).then(()=>{}),"close"),app:e}),e.getHttpServer?.()}c(captureApp,"captureApp"),s(captureApp,"captureApp");
@@ -1,2 +1,2 @@
1
- "use strict";var _=Object.defineProperty;var f=(e,o)=>_(e,"name",{value:o,configurable:!0});var k=Object.defineProperty,h=f((e,o)=>k(e,"name",{value:o,configurable:!0}),"h"),$=Object.defineProperty,p=h((e,o)=>$(e,"name",{value:o,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.checkoutSite=void 0,exports.pgPoolTap=pgPoolTap,exports.samplePgPoolsForTests=samplePgPoolsForTests,exports.resetPgPoolTapForTests=resetPgPoolTapForTests;const node_async_hooks_1=require("node:async_hooks"),pg_errors_1=require("@lensmcp/core/pg-errors"),active_work_1=require("./active-work"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),envMs=p((e,o,s)=>{const r=Number(process.env[e]);return Number.isFinite(r)&&r>=s?r:o},"envMs"),SAMPLE_MS=envMs("LENSMCP_PG_POOL_SAMPLE_MS",1e4,1e3),HOLD_WARN_MS=envMs("LENSMCP_PG_HOLD_WARN_MS",3e4,1e3),SLOW_WAIT_MS=250,BLOCKED_MIN_MS=1e3,WAITS_KEPT=256,SITE_FRAMES=8,stats=new WeakMap,live=[];let nextId=1,timer;const counters=p(e=>({total:e.totalCount??0,idle:e.idleCount??0,waiting:e.waitingCount??0,max:e.options?.max??10}),"counters");function whereOf(e){const o=e.options??{};let s=typeof o.host=="string"?o.host:void 0,r=typeof o.port=="number"||typeof o.port=="string"?String(o.port):void 0,t=typeof o.database=="string"?o.database:void 0;if(typeof o.connectionString=="string")try{const n=new URL(o.connectionString);s??=n.hostname||void 0,r??=n.port||void 0,t??=decodeURIComponent(n.pathname.replace(/^\//,""))||void 0}catch{}return{...t?{database:t}:{},...s?{server:`${s}:${r??5432}`}:{}}}f(whereOf,"whereOf"),h(whereOf,"whereOf"),p(whereOf,"whereOf");function statsOf(e){let o=stats.get(e);return o||(o={id:nextId++,gen:(0,active_work_1.activeWorkGeneration)(),ref:new WeakRef(e),createdAt:Date.now(),where:whereOf(e),out:new Map,acquires:0,waits:[],waitMax:0,peakWaiting:0,peakTotal:0,failures:0,holdMax:0},stats.set(e,o),live.push(o),startSampling()),o}f(statsOf,"statsOf"),h(statsOf,"statsOf"),p(statsOf,"statsOf");function siteOf(e){const o=(e.stack??"").split(`
2
- `).slice(1).map(r=>r.trim()).filter(r=>r.startsWith("at ")&&!/tap-pg-pool\.[cm]?[jt]s:/.test(r)),s=o.filter(r=>!r.includes("node_modules")&&!r.includes("node:"));return(s.length?s:o).slice(0,SITE_FRAMES)}f(siteOf,"siteOf"),h(siteOf,"siteOf"),p(siteOf,"siteOf");const secs=p(e=>e>=1e4?`${Math.round(e/1e3)} s`:e>=1e3?`${(e/1e3).toFixed(1)} s`:`${Math.round(e)} ms`,"secs");function failed(e,o,s,r,t,n){o.failures+=1;const i=(0,pg_errors_1.pgConnectReason)(s),u=counters(e),d=n?n.total>=n.max&&n.idle===0:u.total>=u.max&&u.idle===0,l=e.options?.connectionTimeoutMillis??0,g=i==="pool-wait-timeout"||i==="connect-timeout",c=g&&l>0?Math.max(0,r-l):0,a=c>=Math.max(BLOCKED_MIN_MS,l*.2),w=`${u.total}/${u.max} open, ${u.idle} idle, ${u.waiting} waiting`,m=n?`when it asked ${n.total}/${n.max} open, ${n.idle} idle, ${n.waiting} waiting; now ${w}`:w,x=i==="pool-wait-timeout"?a?`no connection in time \u2014 waited ${secs(r)} on a ${secs(l)} limit: the process was blocked ${secs(c)} (${m})`:d?`pool full \u2014 every connection in use, none free within ${secs(l)} (${m})`:`no connection in time \u2014 the pool had room when it asked, yet the ${secs(l)} wait ran out: the process was busy or the pool's queue stalled (${m})`:i==="connect-timeout"?`opening a connection took over ${secs(l)}${a?` \u2014 the process was blocked ${secs(c)}`:""} (${w})`:i?`could not get a connection: ${pg_errors_1.PG_CONNECT_MEANING[i]}`:`could not get a connection (${secs(r)})`,M=s;(0,emit_1.lensEmitOutcome)("db","error",x,{name:"postgres",kind:"db-pool-error",...i?{reason:i}:{},waitedMs:r,...l?{timeoutMs:l}:{},...g?{lateMs:c}:{},...a?{blockedMs:c}:{},...u,...n?{asked:n}:{},fullWhenAsked:d,pool:o.id,generation:o.gen,serving:(0,active_work_1.activeWorkGeneration)(),pools:live.length,...o.where,error:String(M?.message??s),...typeof M?.code=="string"?{code:M.code}:{}},`db:pool-error:${i??"other"}`,t)}f(failed,"failed"),h(failed,"failed"),p(failed,"failed");function checkedOut(e,o,s,r,t,n){if(e.waits.push(n),e.waits.length>WAITS_KEPT&&e.waits.splice(0,e.waits.length-WAITS_KEPT),n>e.waitMax&&(e.waitMax=n),!o||typeof o!="object")return s;const i=o;e.out.set(i,{at:Date.now(),site:r,ctx:t});const u=p(c=>{if(!c)return;e.out.delete(i);const a=Date.now()-c.at;a>e.holdMax&&(e.holdMax=a)},"back"),d=o.release,l=p(c=>typeof c=="function"?function(...a){return u(e.out.get(i)),c.apply(this??o,a)}:c,"wrap"),g=l(d);return g&&(o.release=g),s===d?g:l(s)}f(checkedOut,"checkedOut"),h(checkedOut,"checkedOut"),p(checkedOut,"checkedOut");function percentile(e,o){if(!e.length)return 0;const s=e.slice().sort((r,t)=>r-t);return s[Math.min(s.length-1,Math.floor(s.length*o))]}f(percentile,"percentile"),h(percentile,"percentile"),p(percentile,"percentile");function sample(e=Date.now()){for(let t=live.length-1;t>=0;t--){const n=live[t],i=n.ref.deref();(!i||i.ended&&n.out.size===0)&&live.splice(t,1)}const o=(0,active_work_1.activeWorkGeneration)(),s=live.reduce((t,n)=>Math.max(t,n.gen),0),r=live.map(t=>{const n=t.ref.deref(),i=counters(n);return{pool:t.id,generation:t.gen,total:i.total,idle:i.idle,waiting:i.waiting,max:i.max,...n.ending?{ending:!0}:{}}});for(const t of live){const n=t.ref.deref();if(!n)continue;const i=[];let u=0;for(const c of t.out.values()){const a=e-c.at;if(a>u&&(u=a),a<HOLD_WARN_MS||c.warned)continue;c.warned=!0;const w=siteOf(c.site);i.push({heldMs:a,site:w}),(0,emit_1.lensEmitOutcome)("db","info",`a connection held ${secs(a)} and not given back${w[0]?` \u2014 taken ${w[0].replace(/^at /,"at ")}`:""}`,{name:"postgres",kind:"db-pool-hold",heldMs:a,site:w,pool:t.id,generation:t.gen,...counters(n),...t.where},"db:pool-hold",c.ctx)}const d=counters(n),l=t.gen<s&&d.total>0,g=t.peakWaiting>0||t.waitMax>=SLOW_WAIT_MS||t.failures>0||i.length>0;(g||l)&&(0,emit_1.lensEmit)("db","info",l&&!g?`pool of generation ${t.gen} still holds ${d.total} connection(s) \u2014 the app serving now is generation ${o}`:`pool ${d.total}/${d.max} open \xB7 ${t.acquires} checkouts \xB7 wait p95 ${secs(percentile(t.waits,.95))} max ${secs(t.waitMax)}${t.peakWaiting?` \xB7 up to ${t.peakWaiting} waiting`:""}${t.failures?` \xB7 ${t.failures} failed`:""}`,{name:"postgres",kind:"db-pool",pool:t.id,generation:t.gen,serving:o,...d,acquires:t.acquires,waitP95Ms:percentile(t.waits,.95),waitMaxMs:t.waitMax,peakWaiting:t.peakWaiting,peakTotal:t.peakTotal,failures:t.failures,holdMaxMs:t.holdMax,out:t.out.size,longestHeldMs:u,...l?{leftover:!0}:{},windowMs:SAMPLE_MS,pools:r,...t.where},"db:pool",void 0),t.acquires=0,t.waits=[],t.waitMax=0,t.failures=0,t.holdMax=0,t.peakWaiting=d.waiting,t.peakTotal=d.total}}f(sample,"sample"),h(sample,"sample"),p(sample,"sample");function startSampling(){timer||(timer=setInterval(()=>{try{sample()}catch{}},SAMPLE_MS),timer.unref?.())}f(startSampling,"startSampling"),h(startSampling,"startSampling"),p(startSampling,"startSampling");const checkoutSites=new node_async_hooks_1.AsyncLocalStorage,checkoutSite=p(()=>checkoutSites.getStore(),"checkoutSite");exports.checkoutSite=checkoutSite;function pgPoolTap(e){let o=e?.Pool?.prototype??null;for(;o&&!Object.prototype.hasOwnProperty.call(o,"connect");)o=Object.getPrototypeOf(o);const s=o?.connect;if(!o||typeof s!="function")return!1;if(s.__lensmcp)return!0;const r=p(function(t){let n;try{n=statsOf(this)}catch{return s.call(this,t)}const i=Date.now(),u=(0,flow_context_1.flowContext)();let d;try{d=counters(this)}catch{}const l=new Error("pg checkout");n.acquires+=1;const g=p(()=>{try{const a=counters(this);a.waiting>n.peakWaiting&&(n.peakWaiting=a.waiting),a.total>n.peakTotal&&(n.peakTotal=a.total)}catch{}},"note");if(typeof t=="function"){const a=s.call(this,(w,m,x)=>{let M=x;try{w?failed(this,n,w,Date.now()-i,u,d):M=checkedOut(n,m,x,l,u,Date.now()-i)}catch{}checkoutSites.run(l,()=>t(w,m,M))});return g(),a}const c=s.call(this);return g(),!c||typeof c.then!="function"?c:c.then(a=>{try{checkedOut(n,a,a?.release,l,u,Date.now()-i)}catch{}return a},a=>{try{failed(this,n,a,Date.now()-i,u,d)}catch{}throw a})},"wrapped");return r.__lensmcp=!0,o.connect=r,!0}f(pgPoolTap,"pgPoolTap"),h(pgPoolTap,"pgPoolTap"),p(pgPoolTap,"pgPoolTap");function samplePgPoolsForTests(e){sample(e)}f(samplePgPoolsForTests,"samplePgPoolsForTests"),h(samplePgPoolsForTests,"samplePgPoolsForTests"),p(samplePgPoolsForTests,"samplePgPoolsForTests");function resetPgPoolTapForTests(){timer&&clearInterval(timer),timer=void 0,live.splice(0,live.length),nextId=1}f(resetPgPoolTapForTests,"resetPgPoolTapForTests"),h(resetPgPoolTapForTests,"resetPgPoolTapForTests"),p(resetPgPoolTapForTests,"resetPgPoolTapForTests");
1
+ "use strict";var k=Object.defineProperty;var h=(e,o)=>k(e,"name",{value:o,configurable:!0});var $=Object.defineProperty,p=h((e,o)=>$(e,"name",{value:o,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.checkoutSite=void 0,exports.pgPoolTap=pgPoolTap,exports.samplePgPoolsForTests=samplePgPoolsForTests,exports.resetPgPoolTapForTests=resetPgPoolTapForTests;const node_async_hooks_1=require("node:async_hooks"),pg_errors_1=require("@lensmcp/core/pg-errors"),active_work_1=require("./active-work"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),envMs=p((e,o,s)=>{const r=Number(process.env[e]);return Number.isFinite(r)&&r>=s?r:o},"envMs"),SAMPLE_MS=envMs("LENSMCP_PG_POOL_SAMPLE_MS",1e4,1e3),HOLD_WARN_MS=envMs("LENSMCP_PG_HOLD_WARN_MS",3e4,1e3),SLOW_WAIT_MS=250,BLOCKED_MIN_MS=1e3,WAITS_KEPT=256,SITE_FRAMES=8,stats=new WeakMap,live=[];let nextId=1,timer;const counters=p(e=>({total:e.totalCount??0,idle:e.idleCount??0,waiting:e.waitingCount??0,max:e.options?.max??10}),"counters");function whereOf(e){const o=e.options??{};let s=typeof o.host=="string"?o.host:void 0,r=typeof o.port=="number"||typeof o.port=="string"?String(o.port):void 0,t=typeof o.database=="string"?o.database:void 0;if(typeof o.connectionString=="string")try{const n=new URL(o.connectionString);s??=n.hostname||void 0,r??=n.port||void 0,t??=decodeURIComponent(n.pathname.replace(/^\//,""))||void 0}catch{}return{...t?{database:t}:{},...s?{server:`${s}:${r??5432}`}:{}}}h(whereOf,"whereOf"),p(whereOf,"whereOf");function statsOf(e){let o=stats.get(e);return o||(o={id:nextId++,gen:(0,active_work_1.activeWorkGeneration)(),ref:new WeakRef(e),createdAt:Date.now(),where:whereOf(e),out:new Map,acquires:0,waits:[],waitMax:0,peakWaiting:0,peakTotal:0,failures:0,holdMax:0},stats.set(e,o),live.push(o),startSampling()),o}h(statsOf,"statsOf"),p(statsOf,"statsOf");function siteOf(e){const o=(e.stack??"").split(`
2
+ `).slice(1).map(r=>r.trim()).filter(r=>r.startsWith("at ")&&!/tap-pg-pool\.[cm]?[jt]s:/.test(r)),s=o.filter(r=>!r.includes("node_modules")&&!r.includes("node:"));return(s.length?s:o).slice(0,SITE_FRAMES)}h(siteOf,"siteOf"),p(siteOf,"siteOf");const secs=p(e=>e>=1e4?`${Math.round(e/1e3)} s`:e>=1e3?`${(e/1e3).toFixed(1)} s`:`${Math.round(e)} ms`,"secs");function failed(e,o,s,r,t,n){o.failures+=1;const i=(0,pg_errors_1.pgConnectReason)(s),u=counters(e),d=n?n.total>=n.max&&n.idle===0:u.total>=u.max&&u.idle===0,l=e.options?.connectionTimeoutMillis??0,f=i==="pool-wait-timeout"||i==="connect-timeout",c=f&&l>0?Math.max(0,r-l):0,a=c>=Math.max(BLOCKED_MIN_MS,l*.2),g=`${u.total}/${u.max} open, ${u.idle} idle, ${u.waiting} waiting`,w=n?`when it asked ${n.total}/${n.max} open, ${n.idle} idle, ${n.waiting} waiting; now ${g}`:g,M=i==="pool-wait-timeout"?a?`no connection in time \u2014 waited ${secs(r)} on a ${secs(l)} limit: the process was blocked ${secs(c)} (${w})`:d?`pool full \u2014 every connection in use, none free within ${secs(l)} (${w})`:`no connection in time \u2014 the pool had room when it asked, yet the ${secs(l)} wait ran out: the process was busy or the pool's queue stalled (${w})`:i==="connect-timeout"?`opening a connection took over ${secs(l)}${a?` \u2014 the process was blocked ${secs(c)}`:""} (${g})`:i?`could not get a connection: ${pg_errors_1.PG_CONNECT_MEANING[i]}`:`could not get a connection (${secs(r)})`,m=s;(0,emit_1.lensEmitOutcome)("db","error",M,{name:"postgres",kind:"db-pool-error",...i?{reason:i}:{},waitedMs:r,...l?{timeoutMs:l}:{},...f?{lateMs:c}:{},...a?{blockedMs:c}:{},...u,...n?{asked:n}:{},fullWhenAsked:d,pool:o.id,generation:o.gen,serving:(0,active_work_1.activeWorkGeneration)(),pools:live.length,...o.where,error:String(m?.message??s),...typeof m?.code=="string"?{code:m.code}:{}},`db:pool-error:${i??"other"}`,t)}h(failed,"failed"),p(failed,"failed");function checkedOut(e,o,s,r,t,n){if(e.waits.push(n),e.waits.length>WAITS_KEPT&&e.waits.splice(0,e.waits.length-WAITS_KEPT),n>e.waitMax&&(e.waitMax=n),!o||typeof o!="object")return s;const i=o;e.out.set(i,{at:Date.now(),site:r,ctx:t});const u=p(c=>{if(!c)return;e.out.delete(i);const a=Date.now()-c.at;a>e.holdMax&&(e.holdMax=a)},"back"),d=o.release,l=p(c=>typeof c=="function"?function(...a){return u(e.out.get(i)),c.apply(this??o,a)}:c,"wrap"),f=l(d);return f&&(o.release=f),s===d?f:l(s)}h(checkedOut,"checkedOut"),p(checkedOut,"checkedOut");function percentile(e,o){if(!e.length)return 0;const s=e.slice().sort((r,t)=>r-t);return s[Math.min(s.length-1,Math.floor(s.length*o))]}h(percentile,"percentile"),p(percentile,"percentile");function sample(e=Date.now()){for(let t=live.length-1;t>=0;t--){const n=live[t],i=n.ref.deref();(!i||i.ended&&n.out.size===0)&&live.splice(t,1)}const o=(0,active_work_1.activeWorkGeneration)(),s=live.reduce((t,n)=>Math.max(t,n.gen),0),r=live.map(t=>{const n=t.ref.deref(),i=counters(n);return{pool:t.id,generation:t.gen,total:i.total,idle:i.idle,waiting:i.waiting,max:i.max,...n.ending?{ending:!0}:{}}});for(const t of live){const n=t.ref.deref();if(!n)continue;const i=[];let u=0;for(const c of t.out.values()){const a=e-c.at;if(a>u&&(u=a),a<HOLD_WARN_MS||c.warned)continue;c.warned=!0;const g=siteOf(c.site);i.push({heldMs:a,site:g}),(0,emit_1.lensEmitOutcome)("db","info",`a connection held ${secs(a)} and not given back${g[0]?` \u2014 taken ${g[0].replace(/^at /,"at ")}`:""}`,{name:"postgres",kind:"db-pool-hold",heldMs:a,site:g,pool:t.id,generation:t.gen,...counters(n),...t.where},"db:pool-hold",c.ctx)}const d=counters(n),l=t.gen<s&&d.total>0,f=t.peakWaiting>0||t.waitMax>=SLOW_WAIT_MS||t.failures>0||i.length>0;(f||l)&&(0,emit_1.lensEmit)("db","info",l&&!f?`pool of generation ${t.gen} still holds ${d.total} connection(s) \u2014 the app serving now is generation ${o}`:`pool ${d.total}/${d.max} open \xB7 ${t.acquires} checkouts \xB7 wait p95 ${secs(percentile(t.waits,.95))} max ${secs(t.waitMax)}${t.peakWaiting?` \xB7 up to ${t.peakWaiting} waiting`:""}${t.failures?` \xB7 ${t.failures} failed`:""}`,{name:"postgres",kind:"db-pool",pool:t.id,generation:t.gen,serving:o,...d,acquires:t.acquires,waitP95Ms:percentile(t.waits,.95),waitMaxMs:t.waitMax,peakWaiting:t.peakWaiting,peakTotal:t.peakTotal,failures:t.failures,holdMaxMs:t.holdMax,out:t.out.size,longestHeldMs:u,...l?{leftover:!0}:{},windowMs:SAMPLE_MS,pools:r,...t.where},"db:pool",void 0),t.acquires=0,t.waits=[],t.waitMax=0,t.failures=0,t.holdMax=0,t.peakWaiting=d.waiting,t.peakTotal=d.total}}h(sample,"sample"),p(sample,"sample");function startSampling(){timer||(timer=setInterval(()=>{try{sample()}catch{}},SAMPLE_MS),timer.unref?.())}h(startSampling,"startSampling"),p(startSampling,"startSampling");const checkoutSites=new node_async_hooks_1.AsyncLocalStorage,checkoutSite=p(()=>checkoutSites.getStore(),"checkoutSite");exports.checkoutSite=checkoutSite;function pgPoolTap(e){let o=e?.Pool?.prototype??null;for(;o&&!Object.prototype.hasOwnProperty.call(o,"connect");)o=Object.getPrototypeOf(o);const s=o?.connect;if(!o||typeof s!="function")return!1;if(s.__lensmcp)return!0;const r=p(function(t){let n;try{n=statsOf(this)}catch{return s.call(this,t)}const i=Date.now(),u=(0,flow_context_1.flowContext)();let d;try{d=counters(this)}catch{}const l=new Error("pg checkout");n.acquires+=1;const f=p(()=>{try{const a=counters(this);a.waiting>n.peakWaiting&&(n.peakWaiting=a.waiting),a.total>n.peakTotal&&(n.peakTotal=a.total)}catch{}},"note");if(typeof t=="function"){const a=s.call(this,(g,w,M)=>{let m=M;try{g?failed(this,n,g,Date.now()-i,u,d):m=checkedOut(n,w,M,l,u,Date.now()-i)}catch{}checkoutSites.run(l,()=>t(g,w,m))});return f(),a}const c=s.call(this);return f(),!c||typeof c.then!="function"?c:c.then(a=>{try{checkedOut(n,a,a?.release,l,u,Date.now()-i)}catch{}return a},a=>{try{failed(this,n,a,Date.now()-i,u,d)}catch{}throw a})},"wrapped");return r.__lensmcp=!0,o.connect=r,!0}h(pgPoolTap,"pgPoolTap"),p(pgPoolTap,"pgPoolTap");function samplePgPoolsForTests(e){sample(e)}h(samplePgPoolsForTests,"samplePgPoolsForTests"),p(samplePgPoolsForTests,"samplePgPoolsForTests");function resetPgPoolTapForTests(){timer&&clearInterval(timer),timer=void 0,live.splice(0,live.length),nextId=1}h(resetPgPoolTapForTests,"resetPgPoolTapForTests"),p(resetPgPoolTapForTests,"resetPgPoolTapForTests");
package/lib/tap-pg.js CHANGED
@@ -1 +1 @@
1
- "use strict";var H=Object.defineProperty;var u=(t,e)=>H(t,"name",{value:e,configurable:!0});var B=Object.defineProperty,p=u((t,e)=>B(t,"name",{value:e,configurable:!0}),"p"),X=Object.defineProperty,r=p((t,e)=>X(t,"name",{value:e,configurable:!0}),"r");Object.defineProperty(exports,"__esModule",{value:!0}),exports.taggedAppName=taggedAppName,exports.pgTap=pgTap;const redact_1=require("@lensmcp/core/redact"),sql_shape_1=require("@lensmcp/core/sql-shape"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),sql_accounting_1=require("./sql-accounting"),tap_pg_pool_1=require("./tap-pg-pool"),callsite_1=require("./callsite"),active_work_1=require("./active-work"),emit_2=require("./emit"),sql_values_1=require("./sql-values"),SKIP_OPS=new Set(["BEGIN","START","COMMIT","END","ROLLBACK","SAVEPOINT","RELEASE","SET","RESET","SHOW","DEALLOCATE","DISCARD","LISTEN","UNLISTEN"]),STATEMENT_EVERY_MS=10*6e4,STATEMENT_MAX=64*1024,SLOW_SITE_MS=250,sites=new callsite_1.SiteSampler,statementSentAt=new Map,MAX_SHAPES_REMEMBERED=2e3,firstWord=r(t=>(/^\s*(?:(?:\/\*[\s\S]*?\*\/|--[^\n]*\n?)\s*)*(\w+)/.exec(t)?.[1]??"query").toUpperCase(),"firstWord");function parseSql(t){const e=(0,sql_shape_1.sqlShape)(t),n=(e.target??e.tables[0])?.split(".").pop();return{op:e.verb,...n?{table:n}:{},sqlId:e.id,tables:e.tables,...e.name?{name:e.name}:{}}}u(parseSql,"parseSql"),p(parseSql,"parseSql"),r(parseSql,"parseSql");const oneLine=r(t=>t.replace(/\s+/g," ").trim(),"oneLine"),clip=r((t,e)=>t.length>e?t.slice(0,e-1)+"\u2026":t,"clip");function paramPreview(t){if(!(!Array.isArray(t)||t.length===0))return t.slice(0,10).map(e=>{if(e==null)return String(e);const n=typeof e=="string"?e:(()=>{try{return JSON.stringify(e)}catch{return String(e)}})();return clip(n,80)})}u(paramPreview,"paramPreview"),p(paramPreview,"paramPreview"),r(paramPreview,"paramPreview");const rowsOf=r(t=>t?.rowCount??t?.rows?.length??0,"rowsOf");function resultPreview(t){const e=t?.rows;if(!(!Array.isArray(e)||e.length===0))try{return clip(JSON.stringify((0,redact_1.redactDeep)(e.slice(0,2))),240)}catch{return}}u(resultPreview,"resultPreview"),p(resultPreview,"resultPreview"),r(resultPreview,"resultPreview");function connectionOf(t){const e=t,n=e?.connectionParameters,a=typeof e?.database=="string"?e.database:typeof n?.database=="string"?n.database:void 0,s=typeof e?.host=="string"?e.host:typeof n?.host=="string"?n.host:void 0,i=typeof e?.port=="number"||typeof e?.port=="string"?e.port:typeof n?.port=="number"||typeof n?.port=="string"?n.port:5432;return{...a?{database:a}:{},...s?{server:`${s}:${i}`}:{}}}u(connectionOf,"connectionOf"),p(connectionOf,"connectionOf"),r(connectionOf,"connectionOf");const APP_NAME_MAX=63;function taggedAppName(t,e,n,a){const s=` lens:${e.replace(/[^\x21-\x7e]/g,"?").replace(/:/g,"_")}${n>0?`:g${n}`:""}${a?`:p${a}`:""}`.slice(0,APP_NAME_MAX);return`${(t??"node").replace(/[^\x20-\x7e]/g,"?").replace(/ lens:\S+$/,"").slice(0,Math.max(0,APP_NAME_MAX-s.length))}${s}`}u(taggedAppName,"taggedAppName"),p(taggedAppName,"taggedAppName"),r(taggedAppName,"taggedAppName");function tagApplicationName(t){if(process.env.LENSMCP_PG_APP_NAME==="0")return;const e=t.getStartupConf;if(typeof e!="function"||e.__lensmcp)return;const n=r(function(){const a=e.call(this);try{a&&typeof a=="object"&&emit_2.PROJECT&&(a.application_name=taggedAppName(typeof a.application_name=="string"?a.application_name:void 0,emit_2.PROJECT,(0,active_work_1.activeWorkGeneration)(),process.pid))}catch{}return a},"wrapped");n.__lensmcp=!0,t.getStartupConf=n}u(tagApplicationName,"tagApplicationName"),p(tagApplicationName,"tagApplicationName"),r(tagApplicationName,"tagApplicationName");function pgTap(t){const e=t?.Client?.prototype,n=e?.query;if(!e||typeof n!="function")return!1;try{(0,tap_pg_pool_1.pgPoolTap)(t)}catch{}try{tagApplicationName(e)}catch{}if(n.__lensmcp)return!0;const a=r(function(s,i,q){const g=s,m=typeof g=="string"?g:g?.text;if(!m||g&&typeof g=="object"&&typeof g.submit=="function")return n.call(this,s,i,q);if(SKIP_OPS.has(firstWord(m)))return n.call(this,s,i,q);const{op:W,table:c,sqlId:S,tables:O,name:$}=parseSql(m),J=connectionOf(this),y=W.toLowerCase(),V=`db:${y}:${c??"query"}`,f=Date.now(),v=(0,flow_context_1.flowContext)(),G=(0,callsite_1.captureSite)(),C=(0,tap_pg_pool_1.checkoutSite)(),h=(0,flow_context_1.liveFlowContext)();h&&(h.dbCallCount=(h.dbCallCount??0)+1);const w=(0,sql_accounting_1.beginSqlStatement)(h,v,f),M=clip(oneLine(m),500),x=Array.isArray(i)?i:s?.values,I=paramPreview(x),A=I&&(0,redact_1.redactSqlParams)(m,I),P=r((o,d)=>{const l=Date.now()-f,T=f-(statementSentAt.get(S)??-1/0)>=STATEMENT_EVERY_MS;let N;try{N=sites.site(S,G,{force:!!o||T||l>=SLOW_SITE_MS,...C?{fallback:C}:{}})}catch{}const R={sqlId:S,...O.length?{tables:O}:{},...$?{sqlName:$}:{},...J,...N?{site:N}:{},...T?{statement:clip(m.trim(),STATEMENT_MAX)}:{}},E=(0,sql_values_1.newSqlValuesId)(f),k=E?{valuesId:E}:{};let b;if(o)b=(0,emit_1.lensEmitOutcome)("db","error",`${y}${c?" "+c:""} failed (${l}ms)`,{name:"postgres",kind:"db-query",op:y,...c?{table:c}:{},...R,query:M,...A?{params:A}:{},...k,startedAt:f,error:String(o?.message??o),durationMs:l},`db:error:${y}:${c??"query"}`,v);else{const D=rowsOf(d),j=resultPreview(d);b=(0,emit_1.lensEmitOutcome)("db","info",`${y} ${c??"query"} (${D} rows, ${l}ms)`,{name:"postgres",kind:"db-query",op:y,...c?{table:c}:{},...R,query:M,...A?{params:A}:{},...j?{result:j}:{},...k,startedAt:f,rows:D,durationMs:l},V,v)}E&&b==="written"&&(0,sql_values_1.keepSqlValues)(E,f,m,x,o?void 0:d?.rows),T&&b==="written"&&(statementSentAt.delete(S),statementSentAt.set(S,f),statementSentAt.size>MAX_SHAPES_REMEMBERED&&statementSentAt.delete(statementSentAt.keys().next().value)),(0,sql_accounting_1.endSqlStatement)(w,{durationMs:l,failed:!!o,emitted:b})},"done"),L=typeof q=="function"?q:typeof i=="function"?i:void 0;if(L){const o=r((d,l)=>{try{P(d,l)}catch{}L(d,l)},"wrappedCb");try{return typeof i=="function"?n.call(this,s,o):n.call(this,s,i,o)}catch(d){throw(0,sql_accounting_1.abandonSqlStatement)(w),d}}let _;try{_=n.call(this,s,i)}catch(o){throw(0,sql_accounting_1.abandonSqlStatement)(w),o}return _&&typeof _.then=="function"?_.then(o=>P(void 0,o),o=>P(o,void 0)):(0,sql_accounting_1.abandonSqlStatement)(w),_},"wrapped");return a.__lensmcp=!0,e.query=a,!0}u(pgTap,"pgTap"),p(pgTap,"pgTap"),r(pgTap,"pgTap");
1
+ "use strict";var B=Object.defineProperty;var p=(t,e)=>B(t,"name",{value:e,configurable:!0});var X=Object.defineProperty,r=p((t,e)=>X(t,"name",{value:e,configurable:!0}),"r");Object.defineProperty(exports,"__esModule",{value:!0}),exports.taggedAppName=taggedAppName,exports.pgTap=pgTap;const redact_1=require("@lensmcp/core/redact"),sql_shape_1=require("@lensmcp/core/sql-shape"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),sql_accounting_1=require("./sql-accounting"),tap_pg_pool_1=require("./tap-pg-pool"),callsite_1=require("./callsite"),active_work_1=require("./active-work"),emit_2=require("./emit"),sql_values_1=require("./sql-values"),SKIP_OPS=new Set(["BEGIN","START","COMMIT","END","ROLLBACK","SAVEPOINT","RELEASE","SET","RESET","SHOW","DEALLOCATE","DISCARD","LISTEN","UNLISTEN"]),STATEMENT_EVERY_MS=10*6e4,STATEMENT_MAX=64*1024,SLOW_SITE_MS=250,sites=new callsite_1.SiteSampler,statementSentAt=new Map,MAX_SHAPES_REMEMBERED=2e3,firstWord=r(t=>(/^\s*(?:(?:\/\*[\s\S]*?\*\/|--[^\n]*\n?)\s*)*(\w+)/.exec(t)?.[1]??"query").toUpperCase(),"firstWord");function parseSql(t){const e=(0,sql_shape_1.sqlShape)(t),n=(e.target??e.tables[0])?.split(".").pop();return{op:e.verb,...n?{table:n}:{},sqlId:e.id,tables:e.tables,...e.name?{name:e.name}:{}}}p(parseSql,"parseSql"),r(parseSql,"parseSql");const oneLine=r(t=>t.replace(/\s+/g," ").trim(),"oneLine"),clip=r((t,e)=>t.length>e?t.slice(0,e-1)+"\u2026":t,"clip");function paramPreview(t){if(!(!Array.isArray(t)||t.length===0))return t.slice(0,10).map(e=>{if(e==null)return String(e);const n=typeof e=="string"?e:(()=>{try{return JSON.stringify(e)}catch{return String(e)}})();return clip(n,80)})}p(paramPreview,"paramPreview"),r(paramPreview,"paramPreview");const rowsOf=r(t=>t?.rowCount??t?.rows?.length??0,"rowsOf");function resultPreview(t){const e=t?.rows;if(!(!Array.isArray(e)||e.length===0))try{return clip(JSON.stringify((0,redact_1.redactDeep)(e.slice(0,2))),240)}catch{return}}p(resultPreview,"resultPreview"),r(resultPreview,"resultPreview");function connectionOf(t){const e=t,n=e?.connectionParameters,o=typeof e?.database=="string"?e.database:typeof n?.database=="string"?n.database:void 0,s=typeof e?.host=="string"?e.host:typeof n?.host=="string"?n.host:void 0,i=typeof e?.port=="number"||typeof e?.port=="string"?e.port:typeof n?.port=="number"||typeof n?.port=="string"?n.port:5432;return{...o?{database:o}:{},...s?{server:`${s}:${i}`}:{}}}p(connectionOf,"connectionOf"),r(connectionOf,"connectionOf");const APP_NAME_MAX=63;function taggedAppName(t,e,n,o){const s=` lens:${e.replace(/[^\x21-\x7e]/g,"?").replace(/:/g,"_")}${n>0?`:g${n}`:""}${o?`:p${o}`:""}`.slice(0,APP_NAME_MAX);return`${(t??"node").replace(/[^\x20-\x7e]/g,"?").replace(/ lens:\S+$/,"").slice(0,Math.max(0,APP_NAME_MAX-s.length))}${s}`}p(taggedAppName,"taggedAppName"),r(taggedAppName,"taggedAppName");function tagApplicationName(t){if(process.env.LENSMCP_PG_APP_NAME==="0")return;const e=t.getStartupConf;if(typeof e!="function"||e.__lensmcp)return;const n=r(function(){const o=e.call(this);try{o&&typeof o=="object"&&emit_2.PROJECT&&(o.application_name=taggedAppName(typeof o.application_name=="string"?o.application_name:void 0,emit_2.PROJECT,(0,active_work_1.activeWorkGeneration)(),process.pid))}catch{}return o},"wrapped");n.__lensmcp=!0,t.getStartupConf=n}p(tagApplicationName,"tagApplicationName"),r(tagApplicationName,"tagApplicationName");function pgTap(t){const e=t?.Client?.prototype,n=e?.query;if(!e||typeof n!="function")return!1;try{(0,tap_pg_pool_1.pgPoolTap)(t)}catch{}try{tagApplicationName(e)}catch{}if(n.__lensmcp)return!0;const o=r(function(s,i,q){const m=s,d=typeof m=="string"?m:m?.text;if(!d||m&&typeof m=="object"&&typeof m.submit=="function")return n.call(this,s,i,q);if(SKIP_OPS.has(firstWord(d)))return n.call(this,s,i,q);const{op:W,table:l,sqlId:S,tables:$,name:C}=parseSql(d),J=connectionOf(this),y=W.toLowerCase(),V=`db:${y}:${l??"query"}`,u=Date.now(),A=(0,flow_context_1.flowContext)(),j=(0,callsite_1.captureSite)(),M=(0,tap_pg_pool_1.checkoutSite)(),b=(0,flow_context_1.liveFlowContext)();b&&(b.dbCallCount=(b.dbCallCount??0)+1);const w=(0,sql_accounting_1.beginSqlStatement)(b,A,u),N=clip(oneLine(d),500),O=Array.isArray(i)?i:s?.values,x=paramPreview(O),h=x&&(0,redact_1.redactSqlParams)(d,x),v=r((a,f)=>{const c=Date.now()-u,T=u-(statementSentAt.get(S)??-1/0)>=STATEMENT_EVERY_MS;let P;try{P=sites.site(S,j,{force:!!a||T||c>=SLOW_SITE_MS,...M?{fallback:M}:{}})}catch{}const L={sqlId:S,...$.length?{tables:$}:{},...C?{sqlName:C}:{},...J,...P?{site:P}:{},...T?{statement:clip(d.trim(),STATEMENT_MAX)}:{}},E=(0,sql_values_1.newSqlValuesId)(u),R=E?{valuesId:E}:{};let _;if(a)_=(0,emit_1.lensEmitOutcome)("db","error",`${y}${l?" "+l:""} failed (${c}ms)`,{name:"postgres",kind:"db-query",op:y,...l?{table:l}:{},...L,query:N,...h?{params:h}:{},...R,startedAt:u,error:String(a?.message??a),durationMs:c},`db:error:${y}:${l??"query"}`,A);else{const k=rowsOf(f),D=resultPreview(f);_=(0,emit_1.lensEmitOutcome)("db","info",`${y} ${l??"query"} (${k} rows, ${c}ms)`,{name:"postgres",kind:"db-query",op:y,...l?{table:l}:{},...L,query:N,...h?{params:h}:{},...D?{result:D}:{},...R,startedAt:u,rows:k,durationMs:c},V,A)}E&&_==="written"&&(0,sql_values_1.keepSqlValues)(E,u,d,O,a?void 0:f?.rows),T&&_==="written"&&(statementSentAt.delete(S),statementSentAt.set(S,u),statementSentAt.size>MAX_SHAPES_REMEMBERED&&statementSentAt.delete(statementSentAt.keys().next().value)),(0,sql_accounting_1.endSqlStatement)(w,{durationMs:c,failed:!!a,emitted:_})},"done"),I=typeof q=="function"?q:typeof i=="function"?i:void 0;if(I){const a=r((f,c)=>{try{v(f,c)}catch{}I(f,c)},"wrappedCb");try{return typeof i=="function"?n.call(this,s,a):n.call(this,s,i,a)}catch(f){throw(0,sql_accounting_1.abandonSqlStatement)(w),f}}let g;try{g=n.call(this,s,i)}catch(a){throw(0,sql_accounting_1.abandonSqlStatement)(w),a}return g&&typeof g.then=="function"?g.then(a=>v(void 0,a),a=>v(a,void 0)):(0,sql_accounting_1.abandonSqlStatement)(w),g},"wrapped");return o.__lensmcp=!0,e.query=o,!0}p(pgTap,"pgTap"),r(pgTap,"pgTap");
package/lib/tap-redis.js CHANGED
@@ -1 +1 @@
1
- "use strict";var k=Object.defineProperty;var m=(t,e)=>k(t,"name",{value:e,configurable:!0});var $=Object.defineProperty,d=m((t,e)=>$(t,"name",{value:e,configurable:!0}),"d"),E=Object.defineProperty,p=d((t,e)=>E(t,"name",{value:e,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.redisFingerprint=redisFingerprint,exports.redisTap=redisTap;const key_pattern_1=require("@lensmcp/core/key-pattern"),redact_1=require("@lensmcp/core/redact"),redis_expiry_1=require("@lensmcp/core/redis-expiry"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),sql_values_1=require("./sql-values"),HOUSEKEEPING=new Set(["info","ping","hello","auth","select","client","cluster","command","subscribe","psubscribe","unsubscribe","punsubscribe","echo","quit","wait","script","config","debug","memory","readonly","readwrite"]),MAX_PER_SEC=100,MAX_SHAPES=200,SHARED_BUCKET="redis:cache";let emitted=0,windowStart=0,capped=0;const shapes=new Set;function redisFingerprint(t,e){const n=`redis:${t} ${(0,key_pattern_1.foldKeyPattern)(e).slice(0,120)}`;return shapes.has(n)?n:shapes.size>=MAX_SHAPES?SHARED_BUCKET:(shapes.add(n),n)}m(redisFingerprint,"redisFingerprint"),d(redisFingerprint,"redisFingerprint"),p(redisFingerprint,"redisFingerprint");function isBullTraffic(t){const e=String(t.name??"").toLowerCase();if(e==="eval"||e==="evalsha")return!0;const n=t.args??[];for(let r=0;r<Math.min(n.length,4);r++){const s=String(n[r]??"");if(s.startsWith("bull:")||s.startsWith("{bull"))return!0}return!1}m(isBullTraffic,"isBullTraffic"),d(isBullTraffic,"isBullTraffic"),p(isBullTraffic,"isBullTraffic");function redisTap(t){const e=t,n=(e?.default??e)?.prototype,r=n?.sendCommand;if(!n||typeof r!="function")return!1;if(r.__lensmcp)return!0;const s=p(function(i,o){const a=r.call(this,i,o);try{observe(i)}catch{}return a},"wrapped");return s.__lensmcp=!0,n.sendCommand=s,!0}m(redisTap,"redisTap"),d(redisTap,"redisTap"),p(redisTap,"redisTap");const clip=p((t,e)=>t.length>e?t.slice(0,e-1)+"\u2026":t,"clip");function commandLine(t,e){const n=e.slice(0,6).map((r,s)=>{const i=String(r??"");return s>0&&i.length>48?`\u2026(${(i.length/1024).toFixed(1)}kb)`:clip(i,64)});return[t.toUpperCase(),...n].join(" ")}m(commandLine,"commandLine"),d(commandLine,"commandLine"),p(commandLine,"commandLine");function observe(t){const e=String(t?.name??"").toLowerCase();if(!e||HOUSEKEEPING.has(e)||isBullTraffic(t))return;const n=(0,flow_context_1.liveFlowContext)();n&&(n.redisCallCount=(n.redisCallCount??0)+1);const r=Date.now();if(r-windowStart>1e3&&(windowStart=r,emitted=0),++emitted>MAX_PER_SEC){capped+=1;return}const s=t?.args??[],i=String(s[0]??""),o=(0,redact_1.isSecretCacheKey)(i),a=o?(0,key_pattern_1.foldKeyPattern)(i):i,C=(0,flow_context_1.flowContext)(),T=o?`${e.toUpperCase()} ${a} \u2026`:(0,redact_1.redactSecretText)(commandLine(e,s)),b=redisFingerprint(e,i),w=capped;capped=0;const y={name:"cache",kind:"redis-op",op:e,key:a,command:T,startedAt:r,expiry:(0,redis_expiry_1.redisExpiry)(e,s),...o?{secretKey:!0}:{},...w?{capSuppressed:w}:{}},g=s.slice(1);if(e==="get"&&t.promise&&typeof t.promise.then=="function"){const l=r;t.promise.then(h=>{const c=h!=null,u=c&&!o?(0,sql_values_1.newCacheValuesId)(l):void 0,_=(0,emit_1.lensEmitOutcome)("redis","info",`cache ${c?"hit":"miss"} ${a}`,{...y,hit:c,durationMs:Date.now()-l,...c&&!o?{value:clip((0,redact_1.redactSecretText)(String(h).slice(0,4096)),120)}:{},...u?{valuesId:u}:{}},b,C);u&&_==="written"&&(0,sql_values_1.keepCacheValues)(u,l,e,i,g,h)},()=>{});return}const f=o?void 0:(0,sql_values_1.newCacheValuesId)(r),x=f?{valuesId:f}:{};let v;if(e==="set"){const l=s.map(u=>String(u)),h=l.findIndex((u,_)=>_>=2&&u.toUpperCase()==="EX"),c=h>=0?Number(l[h+1]):void 0;v=(0,emit_1.lensEmitOutcome)("redis","info",c?`cache set ${a} (ttl ${c}s)`:`cache set ${a}`,{...y,...c?{ttlSec:c}:{},...x},b,C)}else v=(0,emit_1.lensEmitOutcome)("redis","info",`cache ${e} ${a}`,{...y,...x},b,C);if(!f||v!=="written")return;const S=t.promise;S&&typeof S.then=="function"?S.then(l=>(0,sql_values_1.keepCacheValues)(f,r,e,i,g,l),()=>(0,sql_values_1.keepCacheValues)(f,r,e,i,g)):(0,sql_values_1.keepCacheValues)(f,r,e,i,g)}m(observe,"observe"),d(observe,"observe"),p(observe,"observe");
1
+ "use strict";var $=Object.defineProperty;var d=(t,e)=>$(t,"name",{value:e,configurable:!0});var E=Object.defineProperty,p=d((t,e)=>E(t,"name",{value:e,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.redisFingerprint=redisFingerprint,exports.redisTap=redisTap;const key_pattern_1=require("@lensmcp/core/key-pattern"),redact_1=require("@lensmcp/core/redact"),redis_expiry_1=require("@lensmcp/core/redis-expiry"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),sql_values_1=require("./sql-values"),HOUSEKEEPING=new Set(["info","ping","hello","auth","select","client","cluster","command","subscribe","psubscribe","unsubscribe","punsubscribe","echo","quit","wait","script","config","debug","memory","readonly","readwrite"]),MAX_PER_SEC=100,MAX_SHAPES=200,SHARED_BUCKET="redis:cache";let emitted=0,windowStart=0,capped=0;const shapes=new Set;function redisFingerprint(t,e){const n=`redis:${t} ${(0,key_pattern_1.foldKeyPattern)(e).slice(0,120)}`;return shapes.has(n)?n:shapes.size>=MAX_SHAPES?SHARED_BUCKET:(shapes.add(n),n)}d(redisFingerprint,"redisFingerprint"),p(redisFingerprint,"redisFingerprint");function isBullTraffic(t){const e=String(t.name??"").toLowerCase();if(e==="eval"||e==="evalsha")return!0;const n=t.args??[];for(let r=0;r<Math.min(n.length,4);r++){const i=String(n[r]??"");if(i.startsWith("bull:")||i.startsWith("{bull"))return!0}return!1}d(isBullTraffic,"isBullTraffic"),p(isBullTraffic,"isBullTraffic");function redisTap(t){const e=t,n=(e?.default??e)?.prototype,r=n?.sendCommand;if(!n||typeof r!="function")return!1;if(r.__lensmcp)return!0;const i=p(function(s,o){const a=r.call(this,s,o);try{observe(s)}catch{}return a},"wrapped");return i.__lensmcp=!0,n.sendCommand=i,!0}d(redisTap,"redisTap"),p(redisTap,"redisTap");const clip=p((t,e)=>t.length>e?t.slice(0,e-1)+"\u2026":t,"clip");function commandLine(t,e){const n=e.slice(0,6).map((r,i)=>{const s=String(r??"");return i>0&&s.length>48?`\u2026(${(s.length/1024).toFixed(1)}kb)`:clip(s,64)});return[t.toUpperCase(),...n].join(" ")}d(commandLine,"commandLine"),p(commandLine,"commandLine");function observe(t){const e=String(t?.name??"").toLowerCase();if(!e||HOUSEKEEPING.has(e)||isBullTraffic(t))return;const n=(0,flow_context_1.liveFlowContext)();n&&(n.redisCallCount=(n.redisCallCount??0)+1);const r=Date.now();if(r-windowStart>1e3&&(windowStart=r,emitted=0),++emitted>MAX_PER_SEC){capped+=1;return}const i=t?.args??[],s=String(i[0]??""),o=(0,redact_1.isSecretCacheKey)(s),a=o?(0,key_pattern_1.foldKeyPattern)(s):s,C=(0,flow_context_1.flowContext)(),x=o?`${e.toUpperCase()} ${a} \u2026`:(0,redact_1.redactSecretText)(commandLine(e,i)),g=redisFingerprint(e,s),b=capped;capped=0;const y={name:"cache",kind:"redis-op",op:e,key:a,command:x,startedAt:r,expiry:(0,redis_expiry_1.redisExpiry)(e,i),...o?{secretKey:!0}:{},...b?{capSuppressed:b}:{}},h=i.slice(1);if(e==="get"&&t.promise&&typeof t.promise.then=="function"){const l=r;t.promise.then(f=>{const c=f!=null,u=c&&!o?(0,sql_values_1.newCacheValuesId)(l):void 0,w=(0,emit_1.lensEmitOutcome)("redis","info",`cache ${c?"hit":"miss"} ${a}`,{...y,hit:c,durationMs:Date.now()-l,...c&&!o?{value:clip((0,redact_1.redactSecretText)(String(f).slice(0,4096)),120)}:{},...u?{valuesId:u}:{}},g,C);u&&w==="written"&&(0,sql_values_1.keepCacheValues)(u,l,e,s,h,f)},()=>{});return}const m=o?void 0:(0,sql_values_1.newCacheValuesId)(r),v=m?{valuesId:m}:{};let S;if(e==="set"){const l=i.map(u=>String(u)),f=l.findIndex((u,w)=>w>=2&&u.toUpperCase()==="EX"),c=f>=0?Number(l[f+1]):void 0;S=(0,emit_1.lensEmitOutcome)("redis","info",c?`cache set ${a} (ttl ${c}s)`:`cache set ${a}`,{...y,...c?{ttlSec:c}:{},...v},g,C)}else S=(0,emit_1.lensEmitOutcome)("redis","info",`cache ${e} ${a}`,{...y,...v},g,C);if(!m||S!=="written")return;const _=t.promise;_&&typeof _.then=="function"?_.then(l=>(0,sql_values_1.keepCacheValues)(m,r,e,s,h,l),()=>(0,sql_values_1.keepCacheValues)(m,r,e,s,h)):(0,sql_values_1.keepCacheValues)(m,r,e,s,h)}d(observe,"observe"),p(observe,"observe");
package/lib/tap-stdout.js CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";var _=Object.defineProperty;var a=(e,t)=>_(e,"name",{value:t,configurable:!0});var R=Object.defineProperty,f=a((e,t)=>R(e,"name",{value:t,configurable:!0}),"f"),E=Object.defineProperty,u=f((e,t)=>E(e,"name",{value:t,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.isServiceProcess=isServiceProcess,exports.tapStdout=tapStdout;const emit_1=require("./emit"),tap_nest_logger_1=require("./tap-nest-logger"),ANSI=new RegExp("\x1B\\[[0-9;]*m","g");function severityOf(e,t){return/\bFATAL\b/.test(e)?"fatal":/\bERROR\b/.test(e)?"error":/\bWARN\b/.test(e)?"warning":/\bDEBUG\b/.test(e)||/\bVERBOSE\b/.test(e)?"debug":/\bLOG\b/.test(e)?"info":t}a(severityOf,"severityOf"),f(severityOf,"severityOf"),u(severityOf,"severityOf");const STACK_FRAME=/^\s+(at\s|\.\.\.\s\d+\smore)/,CONTINUATION=/^(\s+\S|[}\])]+[,;]?$)/,CONTINUES_WITHIN_MS=1e3;function emitChunk(e,t,l,c,g){const i=e.split(`
2
- `).map(n=>n.replace(ANSI,"").replace(/\s+$/,""));let s=0,r=l;for(;s<i.length;){const n=i[s];if(s+=1,!n.trim())continue;const o=[];for(;s<i.length&&i[s].trim()&&CONTINUATION.test(i[s]);)o.push(i[s]),s+=1;const b=[n,...o].filter(m=>STACK_FRAME.test(m)),p=CONTINUATION.test(n)&&r&&c-r.at<=CONTINUES_WITHIN_MS?r.severity:void 0,v=severityOf(n,t),O=v!==t||/\b(?:FATAL|ERROR|WARN|DEBUG|VERBOSE|LOG)\b/.test(n),S=p??(O?v:b.length>0?"error":t),d=[n,...o];if(!p&&(0,tap_nest_logger_1.isLoggerEcho)(d.join(`
3
- `),c)){r={severity:S,at:c};continue}(0,emit_1.lensLog)(S,p?n.trim():n,{...b.length>0?{stack:d.join(`
4
- `)}:{},...o.length>0&&b.length<o.length?{text:d.join(`
5
- `)}:{},...p?{continues:!0}:{},stream:g}),r={severity:S,at:c}}return r}a(emitChunk,"emitChunk"),f(emitChunk,"emitChunk"),u(emitChunk,"emitChunk");function isServiceProcess(e=process.env){return e.APP_RUNNER==="1"||!!e.LENSMCP_WORKER}a(isServiceProcess,"isServiceProcess"),f(isServiceProcess,"isServiceProcess"),u(isServiceProcess,"isServiceProcess");function tapStdout(){if(process.env.LENSMCP_LOGS==="0"||!isServiceProcess())return;const e=[[process.stdout,"info","stdout"],[process.stderr,"error","stderr"]];for(const[t,l,c]of e){if(t.write.__lensmcp)continue;const g=t.write.bind(t);let i;const s=u(function(r,...n){try{if(!(0,emit_1.isLensWriting)()){const o=typeof r=="string"?r:Buffer.isBuffer(r)?r.toString("utf8"):"";o&&o.indexOf("[lensmcp]")===-1&&(i=emitChunk(o,l,i,Date.now(),c))}}catch{}return g(r,...n)},"wrapped");s.__lensmcp=!0,t.write=s}}a(tapStdout,"tapStdout"),f(tapStdout,"tapStdout"),u(tapStdout,"tapStdout");
1
+ "use strict";var R=Object.defineProperty;var f=(e,t)=>R(e,"name",{value:t,configurable:!0});var E=Object.defineProperty,u=f((e,t)=>E(e,"name",{value:t,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.isServiceProcess=isServiceProcess,exports.tapStdout=tapStdout;const emit_1=require("./emit"),tap_nest_logger_1=require("./tap-nest-logger"),ANSI=new RegExp("\x1B\\[[0-9;]*m","g");function severityOf(e,t){return/\bFATAL\b/.test(e)?"fatal":/\bERROR\b/.test(e)?"error":/\bWARN\b/.test(e)?"warning":/\bDEBUG\b/.test(e)||/\bVERBOSE\b/.test(e)?"debug":/\bLOG\b/.test(e)?"info":t}f(severityOf,"severityOf"),u(severityOf,"severityOf");const STACK_FRAME=/^\s+(at\s|\.\.\.\s\d+\smore)/,CONTINUATION=/^(\s+\S|[}\])]+[,;]?$)/,CONTINUES_WITHIN_MS=1e3;function emitChunk(e,t,p,c,l){const o=e.split(`
2
+ `).map(r=>r.replace(ANSI,"").replace(/\s+$/,""));let n=0,s=p;for(;n<o.length;){const r=o[n];if(n+=1,!r.trim())continue;const i=[];for(;n<o.length&&o[n].trim()&&CONTINUATION.test(o[n]);)i.push(o[n]),n+=1;const g=[r,...i].filter(O=>STACK_FRAME.test(O)),a=CONTINUATION.test(r)&&s&&c-s.at<=CONTINUES_WITHIN_MS?s.severity:void 0,S=severityOf(r,t),_=S!==t||/\b(?:FATAL|ERROR|WARN|DEBUG|VERBOSE|LOG)\b/.test(r),b=a??(_?S:g.length>0?"error":t),d=[r,...i];if(!a&&(0,tap_nest_logger_1.isLoggerEcho)(d.join(`
3
+ `),c)){s={severity:b,at:c};continue}(0,emit_1.lensLog)(b,a?r.trim():r,{...g.length>0?{stack:d.join(`
4
+ `)}:{},...i.length>0&&g.length<i.length?{text:d.join(`
5
+ `)}:{},...a?{continues:!0}:{},stream:l}),s={severity:b,at:c}}return s}f(emitChunk,"emitChunk"),u(emitChunk,"emitChunk");function isServiceProcess(e=process.env){return e.APP_RUNNER==="1"||!!e.LENSMCP_WORKER}f(isServiceProcess,"isServiceProcess"),u(isServiceProcess,"isServiceProcess");function tapStdout(){if(process.env.LENSMCP_LOGS==="0"||!isServiceProcess())return;const e=[[process.stdout,"info","stdout"],[process.stderr,"error","stderr"]];for(const[t,p,c]of e){if(t.write.__lensmcp)continue;const l=t.write.bind(t);let o;const n=u(function(s,...r){try{if(!(0,emit_1.isLensWriting)()){const i=typeof s=="string"?s:Buffer.isBuffer(s)?s.toString("utf8"):"";i&&i.indexOf("[lensmcp]")===-1&&(o=emitChunk(i,p,o,Date.now(),c))}}catch{}return l(s,...r)},"wrapped");n.__lensmcp=!0,t.write=n}}f(tapStdout,"tapStdout"),u(tapStdout,"tapStdout");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/node-instrumentation",
3
- "version": "1.25.37",
3
+ "version": "1.25.39",
4
4
  "main": "./index.js",
5
5
  "types": "./index.d.ts",
6
6
  "exports": {
@@ -15,9 +15,9 @@
15
15
  }
16
16
  },
17
17
  "dependencies": {
18
- "@lensmcp/core": "1.25.37",
19
- "@lensmcp/nest-instrumentation": "1.25.37",
20
- "@lensmcp/protocol-types": "1.25.37",
18
+ "@lensmcp/core": "1.25.39",
19
+ "@lensmcp/nest-instrumentation": "1.25.39",
20
+ "@lensmcp/protocol-types": "1.25.39",
21
21
  "tslib": "^2.3.0"
22
22
  },
23
23
  "optionalDependencies": {