@invince/node 0.0.0-stage → 0.1.0

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/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var A=Object.create;var l=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var $=(r,e)=>{for(var t in e)l(r,t,{get:e[t],enumerable:!0})},h=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of I(e))!F.call(r,a)&&a!==t&&l(r,a,{get:()=>e[a],enumerable:!(n=k(e,a))||n.enumerable});return r};var O=(r,e,t)=>(t=r!=null?A(P(r)):{},h(e||!r||!r.__esModule?l(t,"default",{value:r,enumerable:!0}):t,r)),B=r=>h(l({},"__esModule",{value:!0}),r);var z={};$(z,{Client:()=>d,addBreadcrumb:()=>j,captureException:()=>N,captureMessage:()=>_,capturePerformance:()=>L,close:()=>J,init:()=>M,setUser:()=>H,startAgentTrace:()=>q,startTransaction:()=>K});module.exports=B(z);var f=class{constructor(e){this.maxSize=e;this.buffer=[]}add(e,t,n="info",a){this.buffer.push({category:e,message:t,level:n,timestamp:new Date().toISOString(),data:a}),this.buffer.length>this.maxSize&&this.buffer.shift()}getAll(){return[...this.buffer]}clear(){this.buffer=[]}};var m=O(require("os"),1);function T(r=""){return{browser:null,browserVersion:null,os:`node ${process.version} (${m.default.platform()})`,osVersion:m.default.release(),url:r,userAgent:null}}function y(r,e){return async t=>{let n=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json","X-Ingest-Key":e},body:JSON.stringify(t)});if(!n.ok)throw new Error(`Event ingestion failed with status ${n.status}`)}}function v(r){return r.replace(/\/errors\/?$/,"/performance")}function w(r,e){return async t=>{let n=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json","X-Ingest-Key":e},body:JSON.stringify(t)});if(!n.ok)throw new Error(`Performance event ingestion failed with status ${n.status}`)}}function E(r){return r.replace(/\/errors\/?$/,"/agent-traces")}function S(r,e){return async t=>{let n=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json","X-Ingest-Key":e},body:JSON.stringify(t)});if(!n.ok)throw new Error(`Agent trace ingestion failed with status ${n.status}`)}}function b(r){let e=n=>{r.captureException(n),setTimeout(()=>process.exit(1),250).unref()},t=n=>{r.captureUnhandledRejection(n)};return process.on("uncaughtException",e),process.on("unhandledRejection",t),()=>{process.off("uncaughtException",e),process.off("unhandledRejection",t)}}function U(r,e){let t=typeof r=="string"?r:r instanceof URL?r.toString():r.url,n=e?.method??(typeof r=="object"&&"method"in r?r.method:"GET");return{url:t,method:(n||"GET").toUpperCase()}}function C(r,e,t){if(typeof globalThis.fetch!="function")return()=>{};let n=globalThis.fetch;return globalThis.fetch=(async(a,p)=>{let{url:s,method:i}=U(a,p);if(t.includes(s))return n(a,p);let o=performance.now();try{let c=await n(a,p);return e&&r.capturePerformance(`fetch:${i} ${s}`,performance.now()-o),r.addBreadcrumb("http",`${i} ${s} -> ${c.status}`,c.ok?"info":"warning",{url:s,method:i,status:c.status}),c.ok||r.captureNetworkFailure(`${i} ${s} failed with status ${c.status}`,{url:s,method:i,status:c.status}),c}catch(c){e&&r.capturePerformance(`fetch:${i} ${s}`,performance.now()-o);let g=c instanceof Error?c.message:"Network request failed";throw r.addBreadcrumb("http",`${i} ${s} -> network error`,"error",{url:s,method:i}),r.captureNetworkFailure(`${i} ${s} failed: ${g}`,{url:s,method:i}),c}}),()=>{globalThis.fetch=n}}var R=50;function x(r){return r instanceof Error?{type:r.name,message:r.message,stack:r.stack??null}:{type:"Error",message:typeof r=="string"?r:D(r),stack:null}}function D(r){try{return JSON.stringify(r)}catch{return String(r)}}var d=class{constructor(e){this.user=null;this.cleanupFns=[];if(!e.ingestKey)throw new Error("[Invince] init() requires an ingestKey.");if(!e.transport&&!e.endpoint)throw new Error("[Invince] init() requires either an endpoint or a custom transport.");this.options=e,this.breadcrumbs=new f(e.maxBreadcrumbs??R),this.transport=e.transport??y(e.endpoint,e.ingestKey);let t=e.performanceEndpoint??(e.endpoint?v(e.endpoint):void 0);this.perfTransport=e.performanceTransport??(t?w(t,e.ingestKey):null);let n=e.agentTraceEndpoint??(e.endpoint?E(e.endpoint):void 0);if(this.agentTraceTransport=e.agentTraceTransport??(n?S(n,e.ingestKey):null),e.autoCaptureProcessErrors!==!1&&this.cleanupFns.push(b(this)),e.autoCaptureFetch!==!1){let a=[e.endpoint,t].filter(p=>!!p);this.cleanupFns.push(C(this,e.autoCapturePerformance!==!1,a))}}setUser(e){this.user=e}addBreadcrumb(e,t,n="info",a){this.breadcrumbs.add(e,t,n,a)}captureException(e,t){let n=x(e);this.dispatch("error","error",n.message,n,t)}captureUnhandledRejection(e,t){let n=x(e);this.dispatch("unhandled_rejection","error",n.message,n,t)}captureNetworkFailure(e,t){this.dispatch("network_failure","error",e,null,t)}captureMessage(e,t="info",n){this.dispatch("message",t,e,null,n)}capturePerformance(e,t){this.perfTransport&&this.perfTransport({name:e,durationMs:t,release:this.options.release??null,environment:this.options.environment??"production",occurredAt:new Date().toISOString()}).catch(n=>{this.options.onTransportError?.(n)})}startTransaction(e){let t=performance.now(),n=!1;return{finish:()=>{n||(n=!0,this.capturePerformance(e,performance.now()-t))}}}startAgentTrace(e,t){let n=new Date().toISOString(),a=t?.externalId??`${n}-${Math.random().toString(36).slice(2,10)}`,p=[],s=!1,i=o=>{s||p.push(o)};return{recordLlmCall:o=>i({type:"llm_call",name:o.name,inputTokens:o.inputTokens??null,outputTokens:o.outputTokens??null,costUsd:o.costUsd??null,durationMs:o.durationMs??null,success:o.success??!0,errorMessage:o.errorMessage??null,metadata:o.metadata??null,occurredAt:new Date().toISOString()}),recordToolCall:o=>i({type:"tool_call",name:o.name,durationMs:o.durationMs??null,success:o.success??!0,errorMessage:o.errorMessage??null,metadata:o.metadata??null,occurredAt:new Date().toISOString()}),recordError:(o,c,g)=>i({type:"error",name:o,success:!1,errorMessage:c,metadata:g??null,occurredAt:new Date().toISOString()}),finish:o=>{s||!this.agentTraceTransport||(s=!0,this.agentTraceTransport({externalId:a,task:e,agentName:t?.agentName??null,status:o,startedAt:n,endedAt:new Date().toISOString(),environment:this.options.environment??"production",steps:p}).catch(c=>{this.options.onTransportError?.(c)}))}}}destroy(){this.cleanupFns.forEach(e=>e()),this.cleanupFns=[]}dispatch(e,t,n,a,p){let s={type:e,severity:t,message:n,exception:a,breadcrumbs:this.breadcrumbs.getAll(),context:T(),release:this.options.release??null,environment:this.options.environment??"production",user:this.user,extra:p??null,occurredAt:new Date().toISOString()};this.transport(s).catch(i=>{this.options.onTransportError?.(i)})}};var u=null;function M(r){u?.destroy(),u=new d(r)}function N(r,e){u?.captureException(r,e)}function _(r,e="info",t){u?.captureMessage(r,e,t)}function j(r,e,t,n){u?.addBreadcrumb(r,e,t,n)}function H(r){u?.setUser(r)}function L(r,e){u?.capturePerformance(r,e)}function K(r){return u?.startTransaction(r)??{finish:()=>{}}}var X={recordLlmCall:()=>{},recordToolCall:()=>{},recordError:()=>{},finish:()=>{}};function q(r,e){return u?.startAgentTrace(r,e)??X}function J(){u?.destroy(),u=null}0&&(module.exports={Client,addBreadcrumb,captureException,captureMessage,capturePerformance,close,init,setUser,startAgentTrace,startTransaction});
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/breadcrumbs.ts","../src/context.ts","../src/transport.ts","../src/integrations/process-errors.ts","../src/integrations/fetch.ts","../src/client.ts"],"sourcesContent":["import { Client } from './client';\nimport type { AgentTraceHandle, BreadcrumbCategory, CapturedUser, ClientOptions, Severity } from './types';\n\nlet currentClient: Client | null = null;\n\n/** Initializes the SDK. Call once, as early as possible in your process. Calling it again replaces the previous client (and uninstalls its listeners first). */\nexport function init(options: ClientOptions): void {\n currentClient?.destroy();\n currentClient = new Client(options);\n}\n\nexport function captureException(error: unknown, extra?: Record<string, unknown>): void {\n currentClient?.captureException(error, extra);\n}\n\nexport function captureMessage(message: string, severity: Severity = 'info', extra?: Record<string, unknown>): void {\n currentClient?.captureMessage(message, severity, extra);\n}\n\nexport function addBreadcrumb(category: BreadcrumbCategory, message: string, level?: Severity, data?: Record<string, unknown>): void {\n currentClient?.addBreadcrumb(category, message, level, data);\n}\n\nexport function setUser(user: CapturedUser | null): void {\n currentClient?.setUser(user);\n}\n\nexport function capturePerformance(name: string, durationMs: number): void {\n currentClient?.capturePerformance(name, durationMs);\n}\n\n/** Times an arbitrary operation: `const t = startTransaction('POST /api/orders'); ...; t.finish();`. A no-op finish() if the SDK isn't initialized. */\nexport function startTransaction(name: string): { finish: () => void } {\n return currentClient?.startTransaction(name) ?? { finish: () => {} };\n}\n\nconst NOOP_AGENT_TRACE_HANDLE: AgentTraceHandle = {\n recordLlmCall: () => {},\n recordToolCall: () => {},\n recordError: () => {},\n finish: () => {},\n};\n\n/** Reports one run of your own agent — see Client.startAgentTrace for the full contract. A no-op handle if the SDK isn't initialized. */\nexport function startAgentTrace(task: string, options?: { agentName?: string; externalId?: string }): AgentTraceHandle {\n return currentClient?.startAgentTrace(task, options) ?? NOOP_AGENT_TRACE_HANDLE;\n}\n\n/** Uninstalls all listeners and stops capturing. Mainly useful for tests. */\nexport function close(): void {\n currentClient?.destroy();\n currentClient = null;\n}\n\nexport { Client };\nexport type {\n AgentTraceHandle,\n AgentTracePayload,\n AgentTraceStep,\n AgentTraceStepType,\n AgentTraceTransport,\n Breadcrumb,\n BreadcrumbCategory,\n CapturedEvent,\n CapturedUser,\n ClientContext,\n ClientOptions,\n EventType,\n ExceptionInfo,\n PerformanceSample,\n PerformanceTransport,\n Severity,\n Transport,\n} from './types';\n","import type { Breadcrumb, BreadcrumbCategory, Severity } from './types';\n\n/** A fixed-size ring buffer of recent breadcrumbs — the oldest is dropped once maxSize is exceeded. Same implementation as the browser SDK's; kept as a plain duplicate rather than a shared package for two files this small. */\nexport class BreadcrumbBuffer {\n private buffer: Breadcrumb[] = [];\n\n constructor(private readonly maxSize: number) {}\n\n add(category: BreadcrumbCategory, message: string, level: Severity = 'info', data?: Record<string, unknown>): void {\n this.buffer.push({ category, message, level, timestamp: new Date().toISOString(), data });\n if (this.buffer.length > this.maxSize) {\n this.buffer.shift();\n }\n }\n\n getAll(): Breadcrumb[] {\n return [...this.buffer];\n }\n\n clear(): void {\n this.buffer = [];\n }\n}\n","import os from 'node:os';\nimport type { ClientContext } from './types';\n\n/**\n * There's no \"browser\" here — `os`/`osVersion` carry the Node runtime and\n * host platform instead, and `browser`/`browserVersion`/`userAgent` are\n * null, which the shared ingest schema already allows. `url` is required\n * by that schema, so callers can pass a request path (e.g. the API route\n * being handled) to populate it meaningfully; it defaults to empty.\n */\nexport function buildContext(url: string = ''): ClientContext {\n return {\n browser: null,\n browserVersion: null,\n os: `node ${process.version} (${os.platform()})`,\n osVersion: os.release(),\n url,\n userAgent: null,\n };\n}\n","import type { AgentTracePayload, AgentTraceTransport, CapturedEvent, PerformanceSample, PerformanceTransport, Transport } from './types';\n\n/** POSTs an event as JSON to the given endpoint, identifying the project via the ingest key header. Uses the global fetch available in Node 18+. */\nexport function createFetchTransport(endpoint: string, ingestKey: string): Transport {\n return async (event: CapturedEvent) => {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Ingest-Key': ingestKey,\n },\n body: JSON.stringify(event),\n });\n\n if (!response.ok) {\n throw new Error(`Event ingestion failed with status ${response.status}`);\n }\n };\n}\n\n/** If the caller didn't set an explicit performanceEndpoint, assume the performance route sits next to the error route — the shape every DocCraft ingest key snippet already follows. */\nexport function deriveDefaultPerformanceEndpoint(errorEndpoint: string): string {\n return errorEndpoint.replace(/\\/errors\\/?$/, '/performance');\n}\n\nexport function createFetchPerformanceTransport(endpoint: string, ingestKey: string): PerformanceTransport {\n return async (sample: PerformanceSample) => {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Ingest-Key': ingestKey,\n },\n body: JSON.stringify(sample),\n });\n\n if (!response.ok) {\n throw new Error(`Performance event ingestion failed with status ${response.status}`);\n }\n };\n}\n\n/** Same \"sits next to the errors route\" assumption as the performance endpoint. */\nexport function deriveDefaultAgentTraceEndpoint(errorEndpoint: string): string {\n return errorEndpoint.replace(/\\/errors\\/?$/, '/agent-traces');\n}\n\nexport function createFetchAgentTraceTransport(endpoint: string, ingestKey: string): AgentTraceTransport {\n return async (payload: AgentTracePayload) => {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Ingest-Key': ingestKey,\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(`Agent trace ingestion failed with status ${response.status}`);\n }\n };\n}\n","import type { Client } from '../client';\n\n// Node's own default behavior for an uncaught exception is to print it and\n// exit(1) — but merely registering a 'uncaughtException' listener (which\n// this SDK must do to report the error at all) silently disables that\n// default. Reporting the error and then leaving the process running in an\n// unknown state would be a worse outcome than the crash Node intended, so\n// this waits briefly for the report to leave (best-effort; not a guaranteed\n// flush) and then exits with the same code Node would have used.\nconst EXIT_FLUSH_DELAY_MS = 250;\n\n/**\n * Captures uncaught exceptions and unhandled promise rejections process-\n * wide. An uncaught exception still crashes the process afterward — this\n * only delays that crash long enough to attempt reporting it, matching\n * Node's own default fail-fast behavior rather than silently overriding it.\n */\nexport function installProcessErrorIntegration(client: Client): () => void {\n const onUncaughtException = (error: Error) => {\n client.captureException(error);\n setTimeout(() => process.exit(1), EXIT_FLUSH_DELAY_MS).unref();\n };\n const onUnhandledRejection = (reason: unknown) => {\n client.captureUnhandledRejection(reason);\n };\n\n process.on('uncaughtException', onUncaughtException);\n process.on('unhandledRejection', onUnhandledRejection);\n\n return () => {\n process.off('uncaughtException', onUncaughtException);\n process.off('unhandledRejection', onUnhandledRejection);\n };\n}\n","import type { Client } from '../client';\n\ntype FetchInput = Parameters<typeof fetch>[0];\ntype FetchInit = Parameters<typeof fetch>[1];\n\nfunction describeRequest(input: FetchInput, init?: FetchInit): { url: string; method: string } {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const method = init?.method ?? (typeof input === 'object' && 'method' in input ? input.method : 'GET');\n return { url, method: (method || 'GET').toUpperCase() };\n}\n\n/**\n * Wraps the global fetch (Node 18+) so every outgoing request leaves a\n * breadcrumb, is timed for Performance, and a failed/erroring request also\n * becomes a captured network_failure event — the server-side equivalent of\n * the browser SDK's network integration.\n *\n * `excludeUrls` must include the SDK's own ingest endpoints — without it,\n * reporting an event is itself a fetch call that would get reported, whose\n * report is itself a fetch call that would get reported, forever. This is\n * the one thing that makes wrapping global fetch safe to do at all here.\n */\nexport function installFetchIntegration(client: Client, capturePerformance: boolean, excludeUrls: string[]): () => void {\n if (typeof globalThis.fetch !== 'function') return () => {};\n\n const originalFetch = globalThis.fetch;\n\n globalThis.fetch = (async (input: FetchInput, init?: FetchInit): Promise<Response> => {\n const { url, method } = describeRequest(input, init);\n if (excludeUrls.includes(url)) return originalFetch(input, init);\n\n const start = performance.now();\n\n try {\n const response = await originalFetch(input, init);\n if (capturePerformance) client.capturePerformance(`fetch:${method} ${url}`, performance.now() - start);\n\n client.addBreadcrumb('http', `${method} ${url} -> ${response.status}`, response.ok ? 'info' : 'warning', {\n url,\n method,\n status: response.status,\n });\n\n if (!response.ok) {\n client.captureNetworkFailure(`${method} ${url} failed with status ${response.status}`, {\n url,\n method,\n status: response.status,\n });\n }\n\n return response;\n } catch (err) {\n if (capturePerformance) client.capturePerformance(`fetch:${method} ${url}`, performance.now() - start);\n const message = err instanceof Error ? err.message : 'Network request failed';\n client.addBreadcrumb('http', `${method} ${url} -> network error`, 'error', { url, method });\n client.captureNetworkFailure(`${method} ${url} failed: ${message}`, { url, method });\n throw err;\n }\n }) as typeof fetch;\n\n return () => {\n globalThis.fetch = originalFetch;\n };\n}\n","import { BreadcrumbBuffer } from './breadcrumbs';\nimport { buildContext } from './context';\nimport {\n createFetchTransport,\n createFetchPerformanceTransport,\n deriveDefaultPerformanceEndpoint,\n createFetchAgentTraceTransport,\n deriveDefaultAgentTraceEndpoint,\n} from './transport';\nimport { installProcessErrorIntegration } from './integrations/process-errors';\nimport { installFetchIntegration } from './integrations/fetch';\nimport type {\n AgentTraceHandle,\n AgentTraceStep,\n AgentTraceTransport,\n BreadcrumbCategory,\n CapturedEvent,\n CapturedUser,\n ClientOptions,\n EventType,\n ExceptionInfo,\n PerformanceTransport,\n Severity,\n Transport,\n} from './types';\n\nconst DEFAULT_MAX_BREADCRUMBS = 50;\n\nfunction normalizeError(error: unknown): ExceptionInfo {\n if (error instanceof Error) {\n return { type: error.name, message: error.message, stack: error.stack ?? null };\n }\n return {\n type: 'Error',\n message: typeof error === 'string' ? error : safeStringify(error),\n stack: null,\n };\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport class Client {\n private readonly options: ClientOptions;\n private readonly breadcrumbs: BreadcrumbBuffer;\n private readonly transport: Transport;\n private readonly perfTransport: PerformanceTransport | null;\n private readonly agentTraceTransport: AgentTraceTransport | null;\n private user: CapturedUser | null = null;\n private cleanupFns: Array<() => void> = [];\n\n constructor(options: ClientOptions) {\n if (!options.ingestKey) {\n throw new Error('[Invince] init() requires an ingestKey.');\n }\n if (!options.transport && !options.endpoint) {\n throw new Error('[Invince] init() requires either an endpoint or a custom transport.');\n }\n\n this.options = options;\n this.breadcrumbs = new BreadcrumbBuffer(options.maxBreadcrumbs ?? DEFAULT_MAX_BREADCRUMBS);\n this.transport = options.transport ?? createFetchTransport(options.endpoint!, options.ingestKey);\n\n const resolvedPerformanceEndpoint = options.performanceEndpoint ?? (options.endpoint ? deriveDefaultPerformanceEndpoint(options.endpoint) : undefined);\n this.perfTransport =\n options.performanceTransport ?? (resolvedPerformanceEndpoint ? createFetchPerformanceTransport(resolvedPerformanceEndpoint, options.ingestKey) : null);\n\n const resolvedAgentTraceEndpoint = options.agentTraceEndpoint ?? (options.endpoint ? deriveDefaultAgentTraceEndpoint(options.endpoint) : undefined);\n this.agentTraceTransport =\n options.agentTraceTransport ?? (resolvedAgentTraceEndpoint ? createFetchAgentTraceTransport(resolvedAgentTraceEndpoint, options.ingestKey) : null);\n\n if (options.autoCaptureProcessErrors !== false) {\n this.cleanupFns.push(installProcessErrorIntegration(this));\n }\n if (options.autoCaptureFetch !== false) {\n // Never let the SDK's own ingest calls be reported as if they were the app's own outgoing traffic — see installFetchIntegration's own comment for why this matters.\n const excludeUrls = [options.endpoint, resolvedPerformanceEndpoint].filter((url): url is string => Boolean(url));\n this.cleanupFns.push(installFetchIntegration(this, options.autoCapturePerformance !== false, excludeUrls));\n }\n }\n\n setUser(user: CapturedUser | null): void {\n this.user = user;\n }\n\n addBreadcrumb(category: BreadcrumbCategory, message: string, level: Severity = 'info', data?: Record<string, unknown>): void {\n this.breadcrumbs.add(category, message, level, data);\n }\n\n captureException(error: unknown, extra?: Record<string, unknown>): void {\n const exception = normalizeError(error);\n this.dispatch('error', 'error', exception.message, exception, extra);\n }\n\n /** Used internally by the unhandledRejection integration — kept as a distinct type from captureException so a rejection is never confused with a thrown/caught error in stored events. */\n captureUnhandledRejection(reason: unknown, extra?: Record<string, unknown>): void {\n const exception = normalizeError(reason);\n this.dispatch('unhandled_rejection', 'error', exception.message, exception, extra);\n }\n\n captureNetworkFailure(message: string, extra?: Record<string, unknown>): void {\n this.dispatch('network_failure', 'error', message, null, extra);\n }\n\n captureMessage(message: string, severity: Severity = 'info', extra?: Record<string, unknown>): void {\n this.dispatch('message', severity, message, null, extra);\n }\n\n /** Reports a single \"this named thing took N ms\" sample — what the auto fetch timing calls under the hood, also usable directly for a custom operation (a request handler, a background job). */\n capturePerformance(name: string, durationMs: number): void {\n if (!this.perfTransport) return;\n this.perfTransport({\n name,\n durationMs,\n release: this.options.release ?? null,\n environment: this.options.environment ?? 'production',\n occurredAt: new Date().toISOString(),\n }).catch((err) => {\n this.options.onTransportError?.(err);\n });\n }\n\n /** Times an arbitrary operation: `const t = client.startTransaction('POST /api/orders'); ...; t.finish();` */\n startTransaction(name: string): { finish: () => void } {\n const start = performance.now();\n let finished = false;\n return {\n finish: () => {\n if (finished) return;\n finished = true;\n this.capturePerformance(name, performance.now() - start);\n },\n };\n }\n\n /**\n * Reports one run of your own agent — every LLM/tool call recorded on\n * the returned handle is buffered locally and sent as a single request\n * when you call `finish()`, matching the async \"report after the fact\"\n * model the whole SDK uses (never a blocking proxy in your agent's\n * request path). `externalId` defaults to a random id; pass your own\n * run id if you have one, e.g. to update the same run's status later.\n */\n startAgentTrace(task: string, options?: { agentName?: string; externalId?: string }): AgentTraceHandle {\n const startedAt = new Date().toISOString();\n const externalId = options?.externalId ?? `${startedAt}-${Math.random().toString(36).slice(2, 10)}`;\n const steps: AgentTraceStep[] = [];\n let finished = false;\n\n const record = (step: AgentTraceStep) => {\n if (finished) return;\n steps.push(step);\n };\n\n return {\n recordLlmCall: (input) =>\n record({\n type: 'llm_call',\n name: input.name,\n inputTokens: input.inputTokens ?? null,\n outputTokens: input.outputTokens ?? null,\n costUsd: input.costUsd ?? null,\n durationMs: input.durationMs ?? null,\n success: input.success ?? true,\n errorMessage: input.errorMessage ?? null,\n metadata: input.metadata ?? null,\n occurredAt: new Date().toISOString(),\n }),\n recordToolCall: (input) =>\n record({\n type: 'tool_call',\n name: input.name,\n durationMs: input.durationMs ?? null,\n success: input.success ?? true,\n errorMessage: input.errorMessage ?? null,\n metadata: input.metadata ?? null,\n occurredAt: new Date().toISOString(),\n }),\n recordError: (name, errorMessage, metadata) =>\n record({ type: 'error', name, success: false, errorMessage, metadata: metadata ?? null, occurredAt: new Date().toISOString() }),\n finish: (status) => {\n if (finished || !this.agentTraceTransport) return;\n finished = true;\n this.agentTraceTransport({\n externalId,\n task,\n agentName: options?.agentName ?? null,\n status,\n startedAt,\n endedAt: new Date().toISOString(),\n environment: this.options.environment ?? 'production',\n steps,\n }).catch((err) => {\n this.options.onTransportError?.(err);\n });\n },\n };\n }\n\n destroy(): void {\n this.cleanupFns.forEach((fn) => fn());\n this.cleanupFns = [];\n }\n\n private dispatch(\n type: EventType,\n severity: Severity,\n message: string,\n exception: ExceptionInfo | null,\n extra?: Record<string, unknown>\n ): void {\n const event: CapturedEvent = {\n type,\n severity,\n message,\n exception,\n breadcrumbs: this.breadcrumbs.getAll(),\n context: buildContext(),\n release: this.options.release ?? null,\n environment: this.options.environment ?? 'production',\n user: this.user,\n extra: extra ?? null,\n occurredAt: new Date().toISOString(),\n };\n\n this.transport(event).catch((err) => {\n this.options.onTransportError?.(err);\n });\n }\n}\n"],"mappings":"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","names":["index_exports","__export","Client","addBreadcrumb","captureException","captureMessage","capturePerformance","close","init","setUser","startAgentTrace","startTransaction","__toCommonJS","BreadcrumbBuffer","maxSize","category","message","level","data","import_node_os","buildContext","url","os","createFetchTransport","endpoint","ingestKey","event","response","deriveDefaultPerformanceEndpoint","errorEndpoint","createFetchPerformanceTransport","sample","deriveDefaultAgentTraceEndpoint","createFetchAgentTraceTransport","payload","installProcessErrorIntegration","client","onUncaughtException","error","onUnhandledRejection","reason","describeRequest","input","init","url","method","installFetchIntegration","client","capturePerformance","excludeUrls","originalFetch","start","response","err","message","DEFAULT_MAX_BREADCRUMBS","normalizeError","error","safeStringify","value","Client","options","BreadcrumbBuffer","createFetchTransport","resolvedPerformanceEndpoint","deriveDefaultPerformanceEndpoint","createFetchPerformanceTransport","resolvedAgentTraceEndpoint","deriveDefaultAgentTraceEndpoint","createFetchAgentTraceTransport","installProcessErrorIntegration","excludeUrls","url","installFetchIntegration","user","category","message","level","data","extra","exception","reason","severity","name","durationMs","err","start","finished","task","startedAt","externalId","steps","record","step","input","errorMessage","metadata","status","fn","type","event","buildContext","currentClient","init","options","Client","captureException","error","extra","captureMessage","message","severity","addBreadcrumb","category","level","data","setUser","user","capturePerformance","name","durationMs","startTransaction","NOOP_AGENT_TRACE_HANDLE","startAgentTrace","task","close"]}
@@ -0,0 +1,185 @@
1
+ type EventType = 'error' | 'unhandled_rejection' | 'network_failure' | 'message';
2
+ type BreadcrumbCategory = 'http' | 'custom';
3
+ type Severity = 'debug' | 'info' | 'warning' | 'error' | 'fatal';
4
+ interface Breadcrumb {
5
+ category: BreadcrumbCategory;
6
+ message: string;
7
+ level: Severity;
8
+ timestamp: string;
9
+ data?: Record<string, unknown>;
10
+ }
11
+ interface ExceptionInfo {
12
+ type: string;
13
+ message: string;
14
+ stack: string | null;
15
+ }
16
+ interface ClientContext {
17
+ browser: string | null;
18
+ browserVersion: string | null;
19
+ os: string | null;
20
+ osVersion: string | null;
21
+ url: string;
22
+ userAgent: string | null;
23
+ }
24
+ interface CapturedUser {
25
+ id?: string;
26
+ email?: string;
27
+ }
28
+ interface CapturedEvent {
29
+ type: EventType;
30
+ severity: Severity;
31
+ message: string;
32
+ exception: ExceptionInfo | null;
33
+ breadcrumbs: Breadcrumb[];
34
+ context: ClientContext;
35
+ release: string | null;
36
+ environment: string;
37
+ user: CapturedUser | null;
38
+ extra: Record<string, unknown> | null;
39
+ occurredAt: string;
40
+ }
41
+ type Transport = (event: CapturedEvent) => Promise<void>;
42
+ interface PerformanceSample {
43
+ name: string;
44
+ durationMs: number;
45
+ release: string | null;
46
+ environment: string;
47
+ occurredAt: string;
48
+ }
49
+ type PerformanceTransport = (sample: PerformanceSample) => Promise<void>;
50
+ type AgentTraceStepType = 'llm_call' | 'tool_call' | 'error';
51
+ interface AgentTraceStep {
52
+ type: AgentTraceStepType;
53
+ name: string;
54
+ inputTokens?: number | null;
55
+ outputTokens?: number | null;
56
+ /** You report this — an arbitrary model/provider's cost can't be priced by the ingest server itself. */
57
+ costUsd?: number | null;
58
+ durationMs?: number | null;
59
+ success?: boolean;
60
+ errorMessage?: string | null;
61
+ metadata?: Record<string, unknown> | null;
62
+ occurredAt: string;
63
+ }
64
+ interface AgentTracePayload {
65
+ externalId: string;
66
+ task: string;
67
+ agentName?: string | null;
68
+ status: 'running' | 'completed' | 'failed';
69
+ startedAt: string;
70
+ endedAt?: string | null;
71
+ environment: string;
72
+ steps: AgentTraceStep[];
73
+ }
74
+ type AgentTraceTransport = (payload: AgentTracePayload) => Promise<void>;
75
+ interface AgentTraceHandle {
76
+ /** Records a call to an LLM. costUsd is yours to compute — this SDK doesn't know your provider's pricing. */
77
+ recordLlmCall(input: {
78
+ name: string;
79
+ inputTokens?: number;
80
+ outputTokens?: number;
81
+ costUsd?: number;
82
+ durationMs?: number;
83
+ success?: boolean;
84
+ errorMessage?: string;
85
+ metadata?: Record<string, unknown>;
86
+ }): void;
87
+ /** Records a call to a tool/function the agent invoked. */
88
+ recordToolCall(input: {
89
+ name: string;
90
+ durationMs?: number;
91
+ success?: boolean;
92
+ errorMessage?: string;
93
+ metadata?: Record<string, unknown>;
94
+ }): void;
95
+ /** Records a standalone error not tied to a specific LLM/tool call. */
96
+ recordError(name: string, errorMessage: string, metadata?: Record<string, unknown>): void;
97
+ /** Sends the full run to the ingest endpoint. Call exactly once, when the run ends. */
98
+ finish(status: 'completed' | 'failed'): void;
99
+ }
100
+ interface ClientOptions {
101
+ /** Identifies which project events belong to — the same ingest key shown in the project's Errors page setup snippet. */
102
+ ingestKey: string;
103
+ /** The error-ingest endpoint, e.g. `https://your-app.example.com/api/ingest/errors`. Required unless a custom `transport` is provided. */
104
+ endpoint?: string;
105
+ release?: string;
106
+ environment?: string;
107
+ maxBreadcrumbs?: number;
108
+ /** Install `process.on('uncaughtException')` and `process.on('unhandledRejection')` handlers. Defaults to true. Handlers re-throw/re-reject after reporting so Node's own default crash behavior is unchanged. */
109
+ autoCaptureProcessErrors?: boolean;
110
+ /** Wrap the global fetch so every outgoing request is timed (reported to Performance) and failures are captured as events. Defaults to true. Requires Node 18+ (global fetch). */
111
+ autoCaptureFetch?: boolean;
112
+ /** Override the default fetch-based transport — e.g. for testing, or a non-HTTP sink. */
113
+ transport?: Transport;
114
+ /** Called with a network/transport error when an event fails to send. Never throws. */
115
+ onTransportError?: (error: unknown) => void;
116
+ /** Where performance samples are sent. Defaults to `endpoint` with a trailing `/errors` swapped for `/performance`. */
117
+ performanceEndpoint?: string;
118
+ /** Override the default fetch-based performance transport. */
119
+ performanceTransport?: PerformanceTransport;
120
+ /** Automatically time every outgoing fetch() call. Defaults to true. */
121
+ autoCapturePerformance?: boolean;
122
+ /** Where agent trace runs are sent. Defaults to `endpoint` with a trailing `/errors` swapped for `/agent-traces`. */
123
+ agentTraceEndpoint?: string;
124
+ /** Override the default fetch-based agent trace transport. */
125
+ agentTraceTransport?: AgentTraceTransport;
126
+ }
127
+
128
+ declare class Client {
129
+ private readonly options;
130
+ private readonly breadcrumbs;
131
+ private readonly transport;
132
+ private readonly perfTransport;
133
+ private readonly agentTraceTransport;
134
+ private user;
135
+ private cleanupFns;
136
+ constructor(options: ClientOptions);
137
+ setUser(user: CapturedUser | null): void;
138
+ addBreadcrumb(category: BreadcrumbCategory, message: string, level?: Severity, data?: Record<string, unknown>): void;
139
+ captureException(error: unknown, extra?: Record<string, unknown>): void;
140
+ /** Used internally by the unhandledRejection integration — kept as a distinct type from captureException so a rejection is never confused with a thrown/caught error in stored events. */
141
+ captureUnhandledRejection(reason: unknown, extra?: Record<string, unknown>): void;
142
+ captureNetworkFailure(message: string, extra?: Record<string, unknown>): void;
143
+ captureMessage(message: string, severity?: Severity, extra?: Record<string, unknown>): void;
144
+ /** Reports a single "this named thing took N ms" sample — what the auto fetch timing calls under the hood, also usable directly for a custom operation (a request handler, a background job). */
145
+ capturePerformance(name: string, durationMs: number): void;
146
+ /** Times an arbitrary operation: `const t = client.startTransaction('POST /api/orders'); ...; t.finish();` */
147
+ startTransaction(name: string): {
148
+ finish: () => void;
149
+ };
150
+ /**
151
+ * Reports one run of your own agent — every LLM/tool call recorded on
152
+ * the returned handle is buffered locally and sent as a single request
153
+ * when you call `finish()`, matching the async "report after the fact"
154
+ * model the whole SDK uses (never a blocking proxy in your agent's
155
+ * request path). `externalId` defaults to a random id; pass your own
156
+ * run id if you have one, e.g. to update the same run's status later.
157
+ */
158
+ startAgentTrace(task: string, options?: {
159
+ agentName?: string;
160
+ externalId?: string;
161
+ }): AgentTraceHandle;
162
+ destroy(): void;
163
+ private dispatch;
164
+ }
165
+
166
+ /** Initializes the SDK. Call once, as early as possible in your process. Calling it again replaces the previous client (and uninstalls its listeners first). */
167
+ declare function init(options: ClientOptions): void;
168
+ declare function captureException(error: unknown, extra?: Record<string, unknown>): void;
169
+ declare function captureMessage(message: string, severity?: Severity, extra?: Record<string, unknown>): void;
170
+ declare function addBreadcrumb(category: BreadcrumbCategory, message: string, level?: Severity, data?: Record<string, unknown>): void;
171
+ declare function setUser(user: CapturedUser | null): void;
172
+ declare function capturePerformance(name: string, durationMs: number): void;
173
+ /** Times an arbitrary operation: `const t = startTransaction('POST /api/orders'); ...; t.finish();`. A no-op finish() if the SDK isn't initialized. */
174
+ declare function startTransaction(name: string): {
175
+ finish: () => void;
176
+ };
177
+ /** Reports one run of your own agent — see Client.startAgentTrace for the full contract. A no-op handle if the SDK isn't initialized. */
178
+ declare function startAgentTrace(task: string, options?: {
179
+ agentName?: string;
180
+ externalId?: string;
181
+ }): AgentTraceHandle;
182
+ /** Uninstalls all listeners and stops capturing. Mainly useful for tests. */
183
+ declare function close(): void;
184
+
185
+ export { type AgentTraceHandle, type AgentTracePayload, type AgentTraceStep, type AgentTraceStepType, type AgentTraceTransport, type Breadcrumb, type BreadcrumbCategory, type CapturedEvent, type CapturedUser, Client, type ClientContext, type ClientOptions, type EventType, type ExceptionInfo, type PerformanceSample, type PerformanceTransport, type Severity, type Transport, addBreadcrumb, captureException, captureMessage, capturePerformance, close, init, setUser, startAgentTrace, startTransaction };
@@ -0,0 +1,185 @@
1
+ type EventType = 'error' | 'unhandled_rejection' | 'network_failure' | 'message';
2
+ type BreadcrumbCategory = 'http' | 'custom';
3
+ type Severity = 'debug' | 'info' | 'warning' | 'error' | 'fatal';
4
+ interface Breadcrumb {
5
+ category: BreadcrumbCategory;
6
+ message: string;
7
+ level: Severity;
8
+ timestamp: string;
9
+ data?: Record<string, unknown>;
10
+ }
11
+ interface ExceptionInfo {
12
+ type: string;
13
+ message: string;
14
+ stack: string | null;
15
+ }
16
+ interface ClientContext {
17
+ browser: string | null;
18
+ browserVersion: string | null;
19
+ os: string | null;
20
+ osVersion: string | null;
21
+ url: string;
22
+ userAgent: string | null;
23
+ }
24
+ interface CapturedUser {
25
+ id?: string;
26
+ email?: string;
27
+ }
28
+ interface CapturedEvent {
29
+ type: EventType;
30
+ severity: Severity;
31
+ message: string;
32
+ exception: ExceptionInfo | null;
33
+ breadcrumbs: Breadcrumb[];
34
+ context: ClientContext;
35
+ release: string | null;
36
+ environment: string;
37
+ user: CapturedUser | null;
38
+ extra: Record<string, unknown> | null;
39
+ occurredAt: string;
40
+ }
41
+ type Transport = (event: CapturedEvent) => Promise<void>;
42
+ interface PerformanceSample {
43
+ name: string;
44
+ durationMs: number;
45
+ release: string | null;
46
+ environment: string;
47
+ occurredAt: string;
48
+ }
49
+ type PerformanceTransport = (sample: PerformanceSample) => Promise<void>;
50
+ type AgentTraceStepType = 'llm_call' | 'tool_call' | 'error';
51
+ interface AgentTraceStep {
52
+ type: AgentTraceStepType;
53
+ name: string;
54
+ inputTokens?: number | null;
55
+ outputTokens?: number | null;
56
+ /** You report this — an arbitrary model/provider's cost can't be priced by the ingest server itself. */
57
+ costUsd?: number | null;
58
+ durationMs?: number | null;
59
+ success?: boolean;
60
+ errorMessage?: string | null;
61
+ metadata?: Record<string, unknown> | null;
62
+ occurredAt: string;
63
+ }
64
+ interface AgentTracePayload {
65
+ externalId: string;
66
+ task: string;
67
+ agentName?: string | null;
68
+ status: 'running' | 'completed' | 'failed';
69
+ startedAt: string;
70
+ endedAt?: string | null;
71
+ environment: string;
72
+ steps: AgentTraceStep[];
73
+ }
74
+ type AgentTraceTransport = (payload: AgentTracePayload) => Promise<void>;
75
+ interface AgentTraceHandle {
76
+ /** Records a call to an LLM. costUsd is yours to compute — this SDK doesn't know your provider's pricing. */
77
+ recordLlmCall(input: {
78
+ name: string;
79
+ inputTokens?: number;
80
+ outputTokens?: number;
81
+ costUsd?: number;
82
+ durationMs?: number;
83
+ success?: boolean;
84
+ errorMessage?: string;
85
+ metadata?: Record<string, unknown>;
86
+ }): void;
87
+ /** Records a call to a tool/function the agent invoked. */
88
+ recordToolCall(input: {
89
+ name: string;
90
+ durationMs?: number;
91
+ success?: boolean;
92
+ errorMessage?: string;
93
+ metadata?: Record<string, unknown>;
94
+ }): void;
95
+ /** Records a standalone error not tied to a specific LLM/tool call. */
96
+ recordError(name: string, errorMessage: string, metadata?: Record<string, unknown>): void;
97
+ /** Sends the full run to the ingest endpoint. Call exactly once, when the run ends. */
98
+ finish(status: 'completed' | 'failed'): void;
99
+ }
100
+ interface ClientOptions {
101
+ /** Identifies which project events belong to — the same ingest key shown in the project's Errors page setup snippet. */
102
+ ingestKey: string;
103
+ /** The error-ingest endpoint, e.g. `https://your-app.example.com/api/ingest/errors`. Required unless a custom `transport` is provided. */
104
+ endpoint?: string;
105
+ release?: string;
106
+ environment?: string;
107
+ maxBreadcrumbs?: number;
108
+ /** Install `process.on('uncaughtException')` and `process.on('unhandledRejection')` handlers. Defaults to true. Handlers re-throw/re-reject after reporting so Node's own default crash behavior is unchanged. */
109
+ autoCaptureProcessErrors?: boolean;
110
+ /** Wrap the global fetch so every outgoing request is timed (reported to Performance) and failures are captured as events. Defaults to true. Requires Node 18+ (global fetch). */
111
+ autoCaptureFetch?: boolean;
112
+ /** Override the default fetch-based transport — e.g. for testing, or a non-HTTP sink. */
113
+ transport?: Transport;
114
+ /** Called with a network/transport error when an event fails to send. Never throws. */
115
+ onTransportError?: (error: unknown) => void;
116
+ /** Where performance samples are sent. Defaults to `endpoint` with a trailing `/errors` swapped for `/performance`. */
117
+ performanceEndpoint?: string;
118
+ /** Override the default fetch-based performance transport. */
119
+ performanceTransport?: PerformanceTransport;
120
+ /** Automatically time every outgoing fetch() call. Defaults to true. */
121
+ autoCapturePerformance?: boolean;
122
+ /** Where agent trace runs are sent. Defaults to `endpoint` with a trailing `/errors` swapped for `/agent-traces`. */
123
+ agentTraceEndpoint?: string;
124
+ /** Override the default fetch-based agent trace transport. */
125
+ agentTraceTransport?: AgentTraceTransport;
126
+ }
127
+
128
+ declare class Client {
129
+ private readonly options;
130
+ private readonly breadcrumbs;
131
+ private readonly transport;
132
+ private readonly perfTransport;
133
+ private readonly agentTraceTransport;
134
+ private user;
135
+ private cleanupFns;
136
+ constructor(options: ClientOptions);
137
+ setUser(user: CapturedUser | null): void;
138
+ addBreadcrumb(category: BreadcrumbCategory, message: string, level?: Severity, data?: Record<string, unknown>): void;
139
+ captureException(error: unknown, extra?: Record<string, unknown>): void;
140
+ /** Used internally by the unhandledRejection integration — kept as a distinct type from captureException so a rejection is never confused with a thrown/caught error in stored events. */
141
+ captureUnhandledRejection(reason: unknown, extra?: Record<string, unknown>): void;
142
+ captureNetworkFailure(message: string, extra?: Record<string, unknown>): void;
143
+ captureMessage(message: string, severity?: Severity, extra?: Record<string, unknown>): void;
144
+ /** Reports a single "this named thing took N ms" sample — what the auto fetch timing calls under the hood, also usable directly for a custom operation (a request handler, a background job). */
145
+ capturePerformance(name: string, durationMs: number): void;
146
+ /** Times an arbitrary operation: `const t = client.startTransaction('POST /api/orders'); ...; t.finish();` */
147
+ startTransaction(name: string): {
148
+ finish: () => void;
149
+ };
150
+ /**
151
+ * Reports one run of your own agent — every LLM/tool call recorded on
152
+ * the returned handle is buffered locally and sent as a single request
153
+ * when you call `finish()`, matching the async "report after the fact"
154
+ * model the whole SDK uses (never a blocking proxy in your agent's
155
+ * request path). `externalId` defaults to a random id; pass your own
156
+ * run id if you have one, e.g. to update the same run's status later.
157
+ */
158
+ startAgentTrace(task: string, options?: {
159
+ agentName?: string;
160
+ externalId?: string;
161
+ }): AgentTraceHandle;
162
+ destroy(): void;
163
+ private dispatch;
164
+ }
165
+
166
+ /** Initializes the SDK. Call once, as early as possible in your process. Calling it again replaces the previous client (and uninstalls its listeners first). */
167
+ declare function init(options: ClientOptions): void;
168
+ declare function captureException(error: unknown, extra?: Record<string, unknown>): void;
169
+ declare function captureMessage(message: string, severity?: Severity, extra?: Record<string, unknown>): void;
170
+ declare function addBreadcrumb(category: BreadcrumbCategory, message: string, level?: Severity, data?: Record<string, unknown>): void;
171
+ declare function setUser(user: CapturedUser | null): void;
172
+ declare function capturePerformance(name: string, durationMs: number): void;
173
+ /** Times an arbitrary operation: `const t = startTransaction('POST /api/orders'); ...; t.finish();`. A no-op finish() if the SDK isn't initialized. */
174
+ declare function startTransaction(name: string): {
175
+ finish: () => void;
176
+ };
177
+ /** Reports one run of your own agent — see Client.startAgentTrace for the full contract. A no-op handle if the SDK isn't initialized. */
178
+ declare function startAgentTrace(task: string, options?: {
179
+ agentName?: string;
180
+ externalId?: string;
181
+ }): AgentTraceHandle;
182
+ /** Uninstalls all listeners and stops capturing. Mainly useful for tests. */
183
+ declare function close(): void;
184
+
185
+ export { type AgentTraceHandle, type AgentTracePayload, type AgentTraceStep, type AgentTraceStepType, type AgentTraceTransport, type Breadcrumb, type BreadcrumbCategory, type CapturedEvent, type CapturedUser, Client, type ClientContext, type ClientOptions, type EventType, type ExceptionInfo, type PerformanceSample, type PerformanceTransport, type Severity, type Transport, addBreadcrumb, captureException, captureMessage, capturePerformance, close, init, setUser, startAgentTrace, startTransaction };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ var d=class{constructor(e){this.maxSize=e;this.buffer=[]}add(e,n,t="info",c){this.buffer.push({category:e,message:n,level:t,timestamp:new Date().toISOString(),data:c}),this.buffer.length>this.maxSize&&this.buffer.shift()}getAll(){return[...this.buffer]}clear(){this.buffer=[]}};import g from"os";function m(r=""){return{browser:null,browserVersion:null,os:`node ${process.version} (${g.platform()})`,osVersion:g.release(),url:r,userAgent:null}}function h(r,e){return async n=>{let t=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json","X-Ingest-Key":e},body:JSON.stringify(n)});if(!t.ok)throw new Error(`Event ingestion failed with status ${t.status}`)}}function T(r){return r.replace(/\/errors\/?$/,"/performance")}function y(r,e){return async n=>{let t=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json","X-Ingest-Key":e},body:JSON.stringify(n)});if(!t.ok)throw new Error(`Performance event ingestion failed with status ${t.status}`)}}function v(r){return r.replace(/\/errors\/?$/,"/agent-traces")}function w(r,e){return async n=>{let t=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json","X-Ingest-Key":e},body:JSON.stringify(n)});if(!t.ok)throw new Error(`Agent trace ingestion failed with status ${t.status}`)}}function E(r){let e=t=>{r.captureException(t),setTimeout(()=>process.exit(1),250).unref()},n=t=>{r.captureUnhandledRejection(t)};return process.on("uncaughtException",e),process.on("unhandledRejection",n),()=>{process.off("uncaughtException",e),process.off("unhandledRejection",n)}}function C(r,e){let n=typeof r=="string"?r:r instanceof URL?r.toString():r.url,t=e?.method??(typeof r=="object"&&"method"in r?r.method:"GET");return{url:n,method:(t||"GET").toUpperCase()}}function S(r,e,n){if(typeof globalThis.fetch!="function")return()=>{};let t=globalThis.fetch;return globalThis.fetch=(async(c,p)=>{let{url:a,method:s}=C(c,p);if(n.includes(a))return t(c,p);let o=performance.now();try{let i=await t(c,p);return e&&r.capturePerformance(`fetch:${s} ${a}`,performance.now()-o),r.addBreadcrumb("http",`${s} ${a} -> ${i.status}`,i.ok?"info":"warning",{url:a,method:s,status:i.status}),i.ok||r.captureNetworkFailure(`${s} ${a} failed with status ${i.status}`,{url:a,method:s,status:i.status}),i}catch(i){e&&r.capturePerformance(`fetch:${s} ${a}`,performance.now()-o);let f=i instanceof Error?i.message:"Network request failed";throw r.addBreadcrumb("http",`${s} ${a} -> network error`,"error",{url:a,method:s}),r.captureNetworkFailure(`${s} ${a} failed: ${f}`,{url:a,method:s}),i}}),()=>{globalThis.fetch=t}}var x=50;function b(r){return r instanceof Error?{type:r.name,message:r.message,stack:r.stack??null}:{type:"Error",message:typeof r=="string"?r:A(r),stack:null}}function A(r){try{return JSON.stringify(r)}catch{return String(r)}}var l=class{constructor(e){this.user=null;this.cleanupFns=[];if(!e.ingestKey)throw new Error("[Invince] init() requires an ingestKey.");if(!e.transport&&!e.endpoint)throw new Error("[Invince] init() requires either an endpoint or a custom transport.");this.options=e,this.breadcrumbs=new d(e.maxBreadcrumbs??x),this.transport=e.transport??h(e.endpoint,e.ingestKey);let n=e.performanceEndpoint??(e.endpoint?T(e.endpoint):void 0);this.perfTransport=e.performanceTransport??(n?y(n,e.ingestKey):null);let t=e.agentTraceEndpoint??(e.endpoint?v(e.endpoint):void 0);if(this.agentTraceTransport=e.agentTraceTransport??(t?w(t,e.ingestKey):null),e.autoCaptureProcessErrors!==!1&&this.cleanupFns.push(E(this)),e.autoCaptureFetch!==!1){let c=[e.endpoint,n].filter(p=>!!p);this.cleanupFns.push(S(this,e.autoCapturePerformance!==!1,c))}}setUser(e){this.user=e}addBreadcrumb(e,n,t="info",c){this.breadcrumbs.add(e,n,t,c)}captureException(e,n){let t=b(e);this.dispatch("error","error",t.message,t,n)}captureUnhandledRejection(e,n){let t=b(e);this.dispatch("unhandled_rejection","error",t.message,t,n)}captureNetworkFailure(e,n){this.dispatch("network_failure","error",e,null,n)}captureMessage(e,n="info",t){this.dispatch("message",n,e,null,t)}capturePerformance(e,n){this.perfTransport&&this.perfTransport({name:e,durationMs:n,release:this.options.release??null,environment:this.options.environment??"production",occurredAt:new Date().toISOString()}).catch(t=>{this.options.onTransportError?.(t)})}startTransaction(e){let n=performance.now(),t=!1;return{finish:()=>{t||(t=!0,this.capturePerformance(e,performance.now()-n))}}}startAgentTrace(e,n){let t=new Date().toISOString(),c=n?.externalId??`${t}-${Math.random().toString(36).slice(2,10)}`,p=[],a=!1,s=o=>{a||p.push(o)};return{recordLlmCall:o=>s({type:"llm_call",name:o.name,inputTokens:o.inputTokens??null,outputTokens:o.outputTokens??null,costUsd:o.costUsd??null,durationMs:o.durationMs??null,success:o.success??!0,errorMessage:o.errorMessage??null,metadata:o.metadata??null,occurredAt:new Date().toISOString()}),recordToolCall:o=>s({type:"tool_call",name:o.name,durationMs:o.durationMs??null,success:o.success??!0,errorMessage:o.errorMessage??null,metadata:o.metadata??null,occurredAt:new Date().toISOString()}),recordError:(o,i,f)=>s({type:"error",name:o,success:!1,errorMessage:i,metadata:f??null,occurredAt:new Date().toISOString()}),finish:o=>{a||!this.agentTraceTransport||(a=!0,this.agentTraceTransport({externalId:c,task:e,agentName:n?.agentName??null,status:o,startedAt:t,endedAt:new Date().toISOString(),environment:this.options.environment??"production",steps:p}).catch(i=>{this.options.onTransportError?.(i)}))}}}destroy(){this.cleanupFns.forEach(e=>e()),this.cleanupFns=[]}dispatch(e,n,t,c,p){let a={type:e,severity:n,message:t,exception:c,breadcrumbs:this.breadcrumbs.getAll(),context:m(),release:this.options.release??null,environment:this.options.environment??"production",user:this.user,extra:p??null,occurredAt:new Date().toISOString()};this.transport(a).catch(s=>{this.options.onTransportError?.(s)})}};var u=null;function H(r){u?.destroy(),u=new l(r)}function L(r,e){u?.captureException(r,e)}function K(r,e="info",n){u?.captureMessage(r,e,n)}function X(r,e,n,t){u?.addBreadcrumb(r,e,n,t)}function q(r){u?.setUser(r)}function J(r,e){u?.capturePerformance(r,e)}function z(r){return u?.startTransaction(r)??{finish:()=>{}}}var k={recordLlmCall:()=>{},recordToolCall:()=>{},recordError:()=>{},finish:()=>{}};function G(r,e){return u?.startAgentTrace(r,e)??k}function V(){u?.destroy(),u=null}export{l as Client,X as addBreadcrumb,L as captureException,K as captureMessage,J as capturePerformance,V as close,H as init,q as setUser,G as startAgentTrace,z as startTransaction};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/breadcrumbs.ts","../src/context.ts","../src/transport.ts","../src/integrations/process-errors.ts","../src/integrations/fetch.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["import type { Breadcrumb, BreadcrumbCategory, Severity } from './types';\n\n/** A fixed-size ring buffer of recent breadcrumbs — the oldest is dropped once maxSize is exceeded. Same implementation as the browser SDK's; kept as a plain duplicate rather than a shared package for two files this small. */\nexport class BreadcrumbBuffer {\n private buffer: Breadcrumb[] = [];\n\n constructor(private readonly maxSize: number) {}\n\n add(category: BreadcrumbCategory, message: string, level: Severity = 'info', data?: Record<string, unknown>): void {\n this.buffer.push({ category, message, level, timestamp: new Date().toISOString(), data });\n if (this.buffer.length > this.maxSize) {\n this.buffer.shift();\n }\n }\n\n getAll(): Breadcrumb[] {\n return [...this.buffer];\n }\n\n clear(): void {\n this.buffer = [];\n }\n}\n","import os from 'node:os';\nimport type { ClientContext } from './types';\n\n/**\n * There's no \"browser\" here — `os`/`osVersion` carry the Node runtime and\n * host platform instead, and `browser`/`browserVersion`/`userAgent` are\n * null, which the shared ingest schema already allows. `url` is required\n * by that schema, so callers can pass a request path (e.g. the API route\n * being handled) to populate it meaningfully; it defaults to empty.\n */\nexport function buildContext(url: string = ''): ClientContext {\n return {\n browser: null,\n browserVersion: null,\n os: `node ${process.version} (${os.platform()})`,\n osVersion: os.release(),\n url,\n userAgent: null,\n };\n}\n","import type { AgentTracePayload, AgentTraceTransport, CapturedEvent, PerformanceSample, PerformanceTransport, Transport } from './types';\n\n/** POSTs an event as JSON to the given endpoint, identifying the project via the ingest key header. Uses the global fetch available in Node 18+. */\nexport function createFetchTransport(endpoint: string, ingestKey: string): Transport {\n return async (event: CapturedEvent) => {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Ingest-Key': ingestKey,\n },\n body: JSON.stringify(event),\n });\n\n if (!response.ok) {\n throw new Error(`Event ingestion failed with status ${response.status}`);\n }\n };\n}\n\n/** If the caller didn't set an explicit performanceEndpoint, assume the performance route sits next to the error route — the shape every DocCraft ingest key snippet already follows. */\nexport function deriveDefaultPerformanceEndpoint(errorEndpoint: string): string {\n return errorEndpoint.replace(/\\/errors\\/?$/, '/performance');\n}\n\nexport function createFetchPerformanceTransport(endpoint: string, ingestKey: string): PerformanceTransport {\n return async (sample: PerformanceSample) => {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Ingest-Key': ingestKey,\n },\n body: JSON.stringify(sample),\n });\n\n if (!response.ok) {\n throw new Error(`Performance event ingestion failed with status ${response.status}`);\n }\n };\n}\n\n/** Same \"sits next to the errors route\" assumption as the performance endpoint. */\nexport function deriveDefaultAgentTraceEndpoint(errorEndpoint: string): string {\n return errorEndpoint.replace(/\\/errors\\/?$/, '/agent-traces');\n}\n\nexport function createFetchAgentTraceTransport(endpoint: string, ingestKey: string): AgentTraceTransport {\n return async (payload: AgentTracePayload) => {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Ingest-Key': ingestKey,\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(`Agent trace ingestion failed with status ${response.status}`);\n }\n };\n}\n","import type { Client } from '../client';\n\n// Node's own default behavior for an uncaught exception is to print it and\n// exit(1) — but merely registering a 'uncaughtException' listener (which\n// this SDK must do to report the error at all) silently disables that\n// default. Reporting the error and then leaving the process running in an\n// unknown state would be a worse outcome than the crash Node intended, so\n// this waits briefly for the report to leave (best-effort; not a guaranteed\n// flush) and then exits with the same code Node would have used.\nconst EXIT_FLUSH_DELAY_MS = 250;\n\n/**\n * Captures uncaught exceptions and unhandled promise rejections process-\n * wide. An uncaught exception still crashes the process afterward — this\n * only delays that crash long enough to attempt reporting it, matching\n * Node's own default fail-fast behavior rather than silently overriding it.\n */\nexport function installProcessErrorIntegration(client: Client): () => void {\n const onUncaughtException = (error: Error) => {\n client.captureException(error);\n setTimeout(() => process.exit(1), EXIT_FLUSH_DELAY_MS).unref();\n };\n const onUnhandledRejection = (reason: unknown) => {\n client.captureUnhandledRejection(reason);\n };\n\n process.on('uncaughtException', onUncaughtException);\n process.on('unhandledRejection', onUnhandledRejection);\n\n return () => {\n process.off('uncaughtException', onUncaughtException);\n process.off('unhandledRejection', onUnhandledRejection);\n };\n}\n","import type { Client } from '../client';\n\ntype FetchInput = Parameters<typeof fetch>[0];\ntype FetchInit = Parameters<typeof fetch>[1];\n\nfunction describeRequest(input: FetchInput, init?: FetchInit): { url: string; method: string } {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const method = init?.method ?? (typeof input === 'object' && 'method' in input ? input.method : 'GET');\n return { url, method: (method || 'GET').toUpperCase() };\n}\n\n/**\n * Wraps the global fetch (Node 18+) so every outgoing request leaves a\n * breadcrumb, is timed for Performance, and a failed/erroring request also\n * becomes a captured network_failure event — the server-side equivalent of\n * the browser SDK's network integration.\n *\n * `excludeUrls` must include the SDK's own ingest endpoints — without it,\n * reporting an event is itself a fetch call that would get reported, whose\n * report is itself a fetch call that would get reported, forever. This is\n * the one thing that makes wrapping global fetch safe to do at all here.\n */\nexport function installFetchIntegration(client: Client, capturePerformance: boolean, excludeUrls: string[]): () => void {\n if (typeof globalThis.fetch !== 'function') return () => {};\n\n const originalFetch = globalThis.fetch;\n\n globalThis.fetch = (async (input: FetchInput, init?: FetchInit): Promise<Response> => {\n const { url, method } = describeRequest(input, init);\n if (excludeUrls.includes(url)) return originalFetch(input, init);\n\n const start = performance.now();\n\n try {\n const response = await originalFetch(input, init);\n if (capturePerformance) client.capturePerformance(`fetch:${method} ${url}`, performance.now() - start);\n\n client.addBreadcrumb('http', `${method} ${url} -> ${response.status}`, response.ok ? 'info' : 'warning', {\n url,\n method,\n status: response.status,\n });\n\n if (!response.ok) {\n client.captureNetworkFailure(`${method} ${url} failed with status ${response.status}`, {\n url,\n method,\n status: response.status,\n });\n }\n\n return response;\n } catch (err) {\n if (capturePerformance) client.capturePerformance(`fetch:${method} ${url}`, performance.now() - start);\n const message = err instanceof Error ? err.message : 'Network request failed';\n client.addBreadcrumb('http', `${method} ${url} -> network error`, 'error', { url, method });\n client.captureNetworkFailure(`${method} ${url} failed: ${message}`, { url, method });\n throw err;\n }\n }) as typeof fetch;\n\n return () => {\n globalThis.fetch = originalFetch;\n };\n}\n","import { BreadcrumbBuffer } from './breadcrumbs';\nimport { buildContext } from './context';\nimport {\n createFetchTransport,\n createFetchPerformanceTransport,\n deriveDefaultPerformanceEndpoint,\n createFetchAgentTraceTransport,\n deriveDefaultAgentTraceEndpoint,\n} from './transport';\nimport { installProcessErrorIntegration } from './integrations/process-errors';\nimport { installFetchIntegration } from './integrations/fetch';\nimport type {\n AgentTraceHandle,\n AgentTraceStep,\n AgentTraceTransport,\n BreadcrumbCategory,\n CapturedEvent,\n CapturedUser,\n ClientOptions,\n EventType,\n ExceptionInfo,\n PerformanceTransport,\n Severity,\n Transport,\n} from './types';\n\nconst DEFAULT_MAX_BREADCRUMBS = 50;\n\nfunction normalizeError(error: unknown): ExceptionInfo {\n if (error instanceof Error) {\n return { type: error.name, message: error.message, stack: error.stack ?? null };\n }\n return {\n type: 'Error',\n message: typeof error === 'string' ? error : safeStringify(error),\n stack: null,\n };\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport class Client {\n private readonly options: ClientOptions;\n private readonly breadcrumbs: BreadcrumbBuffer;\n private readonly transport: Transport;\n private readonly perfTransport: PerformanceTransport | null;\n private readonly agentTraceTransport: AgentTraceTransport | null;\n private user: CapturedUser | null = null;\n private cleanupFns: Array<() => void> = [];\n\n constructor(options: ClientOptions) {\n if (!options.ingestKey) {\n throw new Error('[Invince] init() requires an ingestKey.');\n }\n if (!options.transport && !options.endpoint) {\n throw new Error('[Invince] init() requires either an endpoint or a custom transport.');\n }\n\n this.options = options;\n this.breadcrumbs = new BreadcrumbBuffer(options.maxBreadcrumbs ?? DEFAULT_MAX_BREADCRUMBS);\n this.transport = options.transport ?? createFetchTransport(options.endpoint!, options.ingestKey);\n\n const resolvedPerformanceEndpoint = options.performanceEndpoint ?? (options.endpoint ? deriveDefaultPerformanceEndpoint(options.endpoint) : undefined);\n this.perfTransport =\n options.performanceTransport ?? (resolvedPerformanceEndpoint ? createFetchPerformanceTransport(resolvedPerformanceEndpoint, options.ingestKey) : null);\n\n const resolvedAgentTraceEndpoint = options.agentTraceEndpoint ?? (options.endpoint ? deriveDefaultAgentTraceEndpoint(options.endpoint) : undefined);\n this.agentTraceTransport =\n options.agentTraceTransport ?? (resolvedAgentTraceEndpoint ? createFetchAgentTraceTransport(resolvedAgentTraceEndpoint, options.ingestKey) : null);\n\n if (options.autoCaptureProcessErrors !== false) {\n this.cleanupFns.push(installProcessErrorIntegration(this));\n }\n if (options.autoCaptureFetch !== false) {\n // Never let the SDK's own ingest calls be reported as if they were the app's own outgoing traffic — see installFetchIntegration's own comment for why this matters.\n const excludeUrls = [options.endpoint, resolvedPerformanceEndpoint].filter((url): url is string => Boolean(url));\n this.cleanupFns.push(installFetchIntegration(this, options.autoCapturePerformance !== false, excludeUrls));\n }\n }\n\n setUser(user: CapturedUser | null): void {\n this.user = user;\n }\n\n addBreadcrumb(category: BreadcrumbCategory, message: string, level: Severity = 'info', data?: Record<string, unknown>): void {\n this.breadcrumbs.add(category, message, level, data);\n }\n\n captureException(error: unknown, extra?: Record<string, unknown>): void {\n const exception = normalizeError(error);\n this.dispatch('error', 'error', exception.message, exception, extra);\n }\n\n /** Used internally by the unhandledRejection integration — kept as a distinct type from captureException so a rejection is never confused with a thrown/caught error in stored events. */\n captureUnhandledRejection(reason: unknown, extra?: Record<string, unknown>): void {\n const exception = normalizeError(reason);\n this.dispatch('unhandled_rejection', 'error', exception.message, exception, extra);\n }\n\n captureNetworkFailure(message: string, extra?: Record<string, unknown>): void {\n this.dispatch('network_failure', 'error', message, null, extra);\n }\n\n captureMessage(message: string, severity: Severity = 'info', extra?: Record<string, unknown>): void {\n this.dispatch('message', severity, message, null, extra);\n }\n\n /** Reports a single \"this named thing took N ms\" sample — what the auto fetch timing calls under the hood, also usable directly for a custom operation (a request handler, a background job). */\n capturePerformance(name: string, durationMs: number): void {\n if (!this.perfTransport) return;\n this.perfTransport({\n name,\n durationMs,\n release: this.options.release ?? null,\n environment: this.options.environment ?? 'production',\n occurredAt: new Date().toISOString(),\n }).catch((err) => {\n this.options.onTransportError?.(err);\n });\n }\n\n /** Times an arbitrary operation: `const t = client.startTransaction('POST /api/orders'); ...; t.finish();` */\n startTransaction(name: string): { finish: () => void } {\n const start = performance.now();\n let finished = false;\n return {\n finish: () => {\n if (finished) return;\n finished = true;\n this.capturePerformance(name, performance.now() - start);\n },\n };\n }\n\n /**\n * Reports one run of your own agent — every LLM/tool call recorded on\n * the returned handle is buffered locally and sent as a single request\n * when you call `finish()`, matching the async \"report after the fact\"\n * model the whole SDK uses (never a blocking proxy in your agent's\n * request path). `externalId` defaults to a random id; pass your own\n * run id if you have one, e.g. to update the same run's status later.\n */\n startAgentTrace(task: string, options?: { agentName?: string; externalId?: string }): AgentTraceHandle {\n const startedAt = new Date().toISOString();\n const externalId = options?.externalId ?? `${startedAt}-${Math.random().toString(36).slice(2, 10)}`;\n const steps: AgentTraceStep[] = [];\n let finished = false;\n\n const record = (step: AgentTraceStep) => {\n if (finished) return;\n steps.push(step);\n };\n\n return {\n recordLlmCall: (input) =>\n record({\n type: 'llm_call',\n name: input.name,\n inputTokens: input.inputTokens ?? null,\n outputTokens: input.outputTokens ?? null,\n costUsd: input.costUsd ?? null,\n durationMs: input.durationMs ?? null,\n success: input.success ?? true,\n errorMessage: input.errorMessage ?? null,\n metadata: input.metadata ?? null,\n occurredAt: new Date().toISOString(),\n }),\n recordToolCall: (input) =>\n record({\n type: 'tool_call',\n name: input.name,\n durationMs: input.durationMs ?? null,\n success: input.success ?? true,\n errorMessage: input.errorMessage ?? null,\n metadata: input.metadata ?? null,\n occurredAt: new Date().toISOString(),\n }),\n recordError: (name, errorMessage, metadata) =>\n record({ type: 'error', name, success: false, errorMessage, metadata: metadata ?? null, occurredAt: new Date().toISOString() }),\n finish: (status) => {\n if (finished || !this.agentTraceTransport) return;\n finished = true;\n this.agentTraceTransport({\n externalId,\n task,\n agentName: options?.agentName ?? null,\n status,\n startedAt,\n endedAt: new Date().toISOString(),\n environment: this.options.environment ?? 'production',\n steps,\n }).catch((err) => {\n this.options.onTransportError?.(err);\n });\n },\n };\n }\n\n destroy(): void {\n this.cleanupFns.forEach((fn) => fn());\n this.cleanupFns = [];\n }\n\n private dispatch(\n type: EventType,\n severity: Severity,\n message: string,\n exception: ExceptionInfo | null,\n extra?: Record<string, unknown>\n ): void {\n const event: CapturedEvent = {\n type,\n severity,\n message,\n exception,\n breadcrumbs: this.breadcrumbs.getAll(),\n context: buildContext(),\n release: this.options.release ?? null,\n environment: this.options.environment ?? 'production',\n user: this.user,\n extra: extra ?? null,\n occurredAt: new Date().toISOString(),\n };\n\n this.transport(event).catch((err) => {\n this.options.onTransportError?.(err);\n });\n }\n}\n","import { Client } from './client';\nimport type { AgentTraceHandle, BreadcrumbCategory, CapturedUser, ClientOptions, Severity } from './types';\n\nlet currentClient: Client | null = null;\n\n/** Initializes the SDK. Call once, as early as possible in your process. Calling it again replaces the previous client (and uninstalls its listeners first). */\nexport function init(options: ClientOptions): void {\n currentClient?.destroy();\n currentClient = new Client(options);\n}\n\nexport function captureException(error: unknown, extra?: Record<string, unknown>): void {\n currentClient?.captureException(error, extra);\n}\n\nexport function captureMessage(message: string, severity: Severity = 'info', extra?: Record<string, unknown>): void {\n currentClient?.captureMessage(message, severity, extra);\n}\n\nexport function addBreadcrumb(category: BreadcrumbCategory, message: string, level?: Severity, data?: Record<string, unknown>): void {\n currentClient?.addBreadcrumb(category, message, level, data);\n}\n\nexport function setUser(user: CapturedUser | null): void {\n currentClient?.setUser(user);\n}\n\nexport function capturePerformance(name: string, durationMs: number): void {\n currentClient?.capturePerformance(name, durationMs);\n}\n\n/** Times an arbitrary operation: `const t = startTransaction('POST /api/orders'); ...; t.finish();`. A no-op finish() if the SDK isn't initialized. */\nexport function startTransaction(name: string): { finish: () => void } {\n return currentClient?.startTransaction(name) ?? { finish: () => {} };\n}\n\nconst NOOP_AGENT_TRACE_HANDLE: AgentTraceHandle = {\n recordLlmCall: () => {},\n recordToolCall: () => {},\n recordError: () => {},\n finish: () => {},\n};\n\n/** Reports one run of your own agent — see Client.startAgentTrace for the full contract. A no-op handle if the SDK isn't initialized. */\nexport function startAgentTrace(task: string, options?: { agentName?: string; externalId?: string }): AgentTraceHandle {\n return currentClient?.startAgentTrace(task, options) ?? NOOP_AGENT_TRACE_HANDLE;\n}\n\n/** Uninstalls all listeners and stops capturing. Mainly useful for tests. */\nexport function close(): void {\n currentClient?.destroy();\n currentClient = null;\n}\n\nexport { Client };\nexport type {\n AgentTraceHandle,\n AgentTracePayload,\n AgentTraceStep,\n AgentTraceStepType,\n AgentTraceTransport,\n Breadcrumb,\n BreadcrumbCategory,\n CapturedEvent,\n CapturedUser,\n ClientContext,\n ClientOptions,\n EventType,\n ExceptionInfo,\n PerformanceSample,\n PerformanceTransport,\n Severity,\n Transport,\n} from './types';\n"],"mappings":"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","names":["BreadcrumbBuffer","maxSize","category","message","level","data","os","buildContext","url","createFetchTransport","endpoint","ingestKey","event","response","deriveDefaultPerformanceEndpoint","errorEndpoint","createFetchPerformanceTransport","sample","deriveDefaultAgentTraceEndpoint","createFetchAgentTraceTransport","payload","installProcessErrorIntegration","client","onUncaughtException","error","onUnhandledRejection","reason","describeRequest","input","init","url","method","installFetchIntegration","client","capturePerformance","excludeUrls","originalFetch","start","response","err","message","DEFAULT_MAX_BREADCRUMBS","normalizeError","error","safeStringify","value","Client","options","BreadcrumbBuffer","createFetchTransport","resolvedPerformanceEndpoint","deriveDefaultPerformanceEndpoint","createFetchPerformanceTransport","resolvedAgentTraceEndpoint","deriveDefaultAgentTraceEndpoint","createFetchAgentTraceTransport","installProcessErrorIntegration","excludeUrls","url","installFetchIntegration","user","category","message","level","data","extra","exception","reason","severity","name","durationMs","err","start","finished","task","startedAt","externalId","steps","record","step","input","errorMessage","metadata","status","fn","type","event","buildContext","currentClient","init","options","Client","captureException","error","extra","captureMessage","message","severity","addBreadcrumb","category","level","data","setUser","user","capturePerformance","name","durationMs","startTransaction","NOOP_AGENT_TRACE_HANDLE","startAgentTrace","task","close"]}
package/package.json CHANGED
@@ -1,6 +1,39 @@
1
1
  {
2
2
  "name": "@invince/node",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Server-side error and performance monitoring SDK for Invince — captures exceptions, unhandled rejections, outgoing HTTP call timing, and custom transactions.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "sideEffects": false,
20
+ "license": "MIT",
21
+ "homepage": "https://invince.dev",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/invince-dev/invince",
25
+ "directory": "packages/node"
26
+ },
27
+ "keywords": ["error-monitoring", "node", "invince", "observability", "server"],
28
+ "scripts": {
29
+ "build": "tsup",
30
+ "test": "vitest run",
31
+ "typecheck": "tsc --noEmit"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^22.0.0",
35
+ "tsup": "^8.5.1",
36
+ "typescript": "^5.6.0",
37
+ "vitest": "^5.0.0"
38
+ }
39
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.