@morsehq-dev/sdk 0.5.1-rc.1 → 0.6.0-rc.1
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/anthropic/index.cjs +11 -11
- package/dist/anthropic/index.d.cts +1 -1
- package/dist/anthropic/index.d.ts +1 -1
- package/dist/anthropic/index.js +4 -4
- package/dist/anthropic-agent-sdk/index.cjs +44 -40
- package/dist/anthropic-agent-sdk/index.cjs.map +1 -1
- package/dist/anthropic-agent-sdk/index.d.cts +1 -1
- package/dist/anthropic-agent-sdk/index.d.ts +1 -1
- package/dist/anthropic-agent-sdk/index.js +10 -6
- package/dist/anthropic-agent-sdk/index.js.map +1 -1
- package/dist/browser/anthropic/index.cjs +11 -11
- package/dist/browser/anthropic/index.js +4 -4
- package/dist/browser/anthropic-agent-sdk/index.cjs +44 -40
- package/dist/browser/anthropic-agent-sdk/index.cjs.map +1 -1
- package/dist/browser/anthropic-agent-sdk/index.js +10 -6
- package/dist/browser/anthropic-agent-sdk/index.js.map +1 -1
- package/dist/browser/{chunk-ZOOYJTDT.cjs → chunk-33WDUUKZ.cjs} +18 -18
- package/dist/browser/{chunk-ZOOYJTDT.cjs.map → chunk-33WDUUKZ.cjs.map} +1 -1
- package/dist/browser/{chunk-E6WORBIU.cjs → chunk-3I7IGP3P.cjs} +5 -5
- package/dist/browser/chunk-3I7IGP3P.cjs.map +1 -0
- package/dist/{chunk-FHQGPQFR.js → browser/chunk-3OYHDDOJ.js} +27 -5
- package/dist/browser/chunk-3OYHDDOJ.js.map +1 -0
- package/dist/browser/{chunk-HJTUPXNE.cjs → chunk-4IUHXUCJ.cjs} +21 -4
- package/dist/browser/chunk-4IUHXUCJ.cjs.map +1 -0
- package/dist/browser/{chunk-AX6NEG6X.js → chunk-5TYTCLKA.js} +4 -4
- package/dist/browser/{chunk-AX6NEG6X.js.map → chunk-5TYTCLKA.js.map} +1 -1
- package/dist/browser/{chunk-5IMBYZUB.js → chunk-6JHMFFPE.js} +3 -3
- package/dist/browser/chunk-6JHMFFPE.js.map +1 -0
- package/dist/{chunk-2UFTRWUS.cjs → browser/chunk-FKYI3N5N.cjs} +7 -7
- package/dist/browser/{chunk-FYIQARMI.cjs.map → chunk-FKYI3N5N.cjs.map} +1 -1
- package/dist/browser/{chunk-TIMAH323.js → chunk-FPTUHYDJ.js} +3 -3
- package/dist/browser/{chunk-TIMAH323.js.map → chunk-FPTUHYDJ.js.map} +1 -1
- package/dist/browser/{chunk-YXCWAU36.cjs → chunk-IDKQZ4X5.cjs} +38 -15
- package/dist/browser/chunk-IDKQZ4X5.cjs.map +1 -0
- package/dist/browser/{chunk-HNOHWDK3.cjs → chunk-LIP3XCTK.cjs} +12 -12
- package/dist/browser/{chunk-HNOHWDK3.cjs.map → chunk-LIP3XCTK.cjs.map} +1 -1
- package/dist/browser/{chunk-RDNSY73W.js → chunk-OUQAH27A.js} +3 -3
- package/dist/browser/{chunk-RDNSY73W.js.map → chunk-OUQAH27A.js.map} +1 -1
- package/dist/browser/{chunk-Z26QGUMP.cjs → chunk-PSNZZBQJ.cjs} +6 -6
- package/dist/browser/{chunk-Z26QGUMP.cjs.map → chunk-PSNZZBQJ.cjs.map} +1 -1
- package/dist/browser/{chunk-7G266PKE.js → chunk-PXHTLCEU.js} +21 -5
- package/dist/browser/chunk-PXHTLCEU.js.map +1 -0
- package/dist/browser/{chunk-VSHCKROM.js → chunk-TRVACYUN.js} +5 -5
- package/dist/browser/{chunk-VSHCKROM.js.map → chunk-TRVACYUN.js.map} +1 -1
- package/dist/browser/index.cjs +99 -99
- package/dist/browser/index.js +8 -8
- package/dist/browser/integrations/pino.cjs +4 -4
- package/dist/browser/integrations/pino.js +3 -3
- package/dist/browser/langchain/index.cjs +28 -26
- package/dist/browser/langchain/index.cjs.map +1 -1
- package/dist/browser/langchain/index.js +13 -11
- package/dist/browser/langchain/index.js.map +1 -1
- package/dist/browser/langgraph/index.cjs +32 -30
- package/dist/browser/langgraph/index.cjs.map +1 -1
- package/dist/browser/langgraph/index.js +10 -8
- package/dist/browser/langgraph/index.js.map +1 -1
- package/dist/browser/openai/index.cjs +11 -11
- package/dist/browser/openai/index.js +2 -2
- package/dist/browser/openai-agents/index.cjs +63 -35
- package/dist/browser/openai-agents/index.cjs.map +1 -1
- package/dist/browser/openai-agents/index.js +33 -5
- package/dist/browser/openai-agents/index.js.map +1 -1
- package/dist/browser/vercel-ai/index.cjs +14 -14
- package/dist/browser/vercel-ai/index.js +3 -3
- package/dist/{chunk-ZTBAMSCC.cjs → chunk-7DALGJL2.cjs} +72 -20
- package/dist/chunk-7DALGJL2.cjs.map +1 -0
- package/dist/{chunk-KALB7HJ5.cjs → chunk-B7TGG62X.cjs} +12 -12
- package/dist/{chunk-KALB7HJ5.cjs.map → chunk-B7TGG62X.cjs.map} +1 -1
- package/dist/{chunk-GATTHW3X.cjs → chunk-COZFARLL.cjs} +5 -5
- package/dist/chunk-COZFARLL.cjs.map +1 -0
- package/dist/{chunk-XBI4AMCW.cjs → chunk-DXTNU2KT.cjs} +38 -15
- package/dist/chunk-DXTNU2KT.cjs.map +1 -0
- package/dist/{chunk-5MJS5ECA.js → chunk-ERH3TNXZ.js} +3 -3
- package/dist/{chunk-5MJS5ECA.js.map → chunk-ERH3TNXZ.js.map} +1 -1
- package/dist/{chunk-QLJAATBR.cjs → chunk-ESJJXXB6.cjs} +6 -6
- package/dist/{chunk-QLJAATBR.cjs.map → chunk-ESJJXXB6.cjs.map} +1 -1
- package/dist/{chunk-HCN6Z56N.cjs → chunk-ETRNCI5Z.cjs} +18 -18
- package/dist/{chunk-HCN6Z56N.cjs.map → chunk-ETRNCI5Z.cjs.map} +1 -1
- package/dist/{browser/chunk-PIZVCAW7.js → chunk-GULJAURY.js} +27 -5
- package/dist/chunk-GULJAURY.js.map +1 -0
- package/dist/{chunk-YGKEP2GY.js → chunk-HJV35HWL.js} +72 -21
- package/dist/chunk-HJV35HWL.js.map +1 -0
- package/dist/{chunk-ZMRXUZ5L.js → chunk-L7AD4KUD.js} +3 -3
- package/dist/chunk-L7AD4KUD.js.map +1 -0
- package/dist/{chunk-GQVNZPRF.js → chunk-QBDTQTMN.js} +3 -3
- package/dist/{chunk-GQVNZPRF.js.map → chunk-QBDTQTMN.js.map} +1 -1
- package/dist/{browser/chunk-FYIQARMI.cjs → chunk-WG4H5JC6.cjs} +7 -7
- package/dist/{chunk-2UFTRWUS.cjs.map → chunk-WG4H5JC6.cjs.map} +1 -1
- package/dist/{chunk-62FWHZXN.js → chunk-XS4P7XPV.js} +5 -5
- package/dist/{chunk-62FWHZXN.js.map → chunk-XS4P7XPV.js.map} +1 -1
- package/dist/{chunk-4WUG3RMJ.js → chunk-YVLEDBN7.js} +4 -4
- package/dist/{chunk-4WUG3RMJ.js.map → chunk-YVLEDBN7.js.map} +1 -1
- package/dist/index.cjs +106 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -9
- package/dist/index.js.map +1 -1
- package/dist/integrations/pino.cjs +4 -4
- package/dist/integrations/pino.js +3 -3
- package/dist/langchain/index.cjs +28 -26
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.d.cts +3 -3
- package/dist/langchain/index.d.ts +3 -3
- package/dist/langchain/index.js +13 -11
- package/dist/langchain/index.js.map +1 -1
- package/dist/langgraph/index.cjs +32 -30
- package/dist/langgraph/index.cjs.map +1 -1
- package/dist/langgraph/index.d.cts +3 -3
- package/dist/langgraph/index.d.ts +3 -3
- package/dist/langgraph/index.js +10 -8
- package/dist/langgraph/index.js.map +1 -1
- package/dist/openai/index.cjs +11 -11
- package/dist/openai/index.js +2 -2
- package/dist/openai-agents/index.cjs +63 -35
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.d.cts +13 -4
- package/dist/openai-agents/index.d.ts +13 -4
- package/dist/openai-agents/index.js +33 -5
- package/dist/openai-agents/index.js.map +1 -1
- package/dist/{spans-DZtMuBvc.d.cts → spans-CBMWNg2C.d.cts} +1 -0
- package/dist/{spans-DZtMuBvc.d.ts → spans-CBMWNg2C.d.ts} +1 -0
- package/dist/{tracing-J8ZgxVzU.d.ts → tracing-BMWTyexr.d.ts} +1 -1
- package/dist/{tracing-CNlre8TK.d.cts → tracing-Bh-cbvr6.d.cts} +1 -1
- package/dist/vercel-ai/index.cjs +14 -14
- package/dist/vercel-ai/index.js +3 -3
- package/package.json +1 -1
- package/dist/browser/chunk-5IMBYZUB.js.map +0 -1
- package/dist/browser/chunk-7G266PKE.js.map +0 -1
- package/dist/browser/chunk-E6WORBIU.cjs.map +0 -1
- package/dist/browser/chunk-HJTUPXNE.cjs.map +0 -1
- package/dist/browser/chunk-PIZVCAW7.js.map +0 -1
- package/dist/browser/chunk-YXCWAU36.cjs.map +0 -1
- package/dist/chunk-FHQGPQFR.js.map +0 -1
- package/dist/chunk-GATTHW3X.cjs.map +0 -1
- package/dist/chunk-XBI4AMCW.cjs.map +0 -1
- package/dist/chunk-YGKEP2GY.js.map +0 -1
- package/dist/chunk-ZMRXUZ5L.js.map +0 -1
- package/dist/chunk-ZTBAMSCC.cjs.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkPSNZZBQJ_cjs = require('./chunk-PSNZZBQJ.cjs');
|
|
4
|
+
var chunk4IUHXUCJ_cjs = require('./chunk-4IUHXUCJ.cjs');
|
|
5
5
|
|
|
6
6
|
// src/log.ts
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
chunk4IUHXUCJ_cjs.init_redaction();
|
|
8
|
+
chunk4IUHXUCJ_cjs.init_tracing();
|
|
9
9
|
var DEFAULT_SERVICE_NAME = "morse-sdk-ts";
|
|
10
10
|
var ensureInitialized = () => {
|
|
11
11
|
};
|
|
@@ -14,14 +14,14 @@ function _setEnsureInitialized(fn) {
|
|
|
14
14
|
}
|
|
15
15
|
function logImpl(message, options = {}) {
|
|
16
16
|
ensureInitialized();
|
|
17
|
-
const transport =
|
|
17
|
+
const transport = chunk4IUHXUCJ_cjs.getTransport();
|
|
18
18
|
if (transport === null) {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
let traceId = options.traceId ?? null;
|
|
22
22
|
let spanId = options.spanId ?? null;
|
|
23
23
|
if (traceId === null || spanId === null) {
|
|
24
|
-
const state =
|
|
24
|
+
const state = chunk4IUHXUCJ_cjs.getActiveTraceState();
|
|
25
25
|
if (state !== null) {
|
|
26
26
|
if (traceId === null) traceId = state.traceId;
|
|
27
27
|
if (spanId === null && state.spanStack.length > 0) {
|
|
@@ -31,10 +31,10 @@ function logImpl(message, options = {}) {
|
|
|
31
31
|
}
|
|
32
32
|
const severity = (options.severity ?? "info").toUpperCase();
|
|
33
33
|
const serviceName = options.serviceName ?? DEFAULT_SERVICE_NAME;
|
|
34
|
-
const config =
|
|
34
|
+
const config = chunk4IUHXUCJ_cjs.getRedactionConfig();
|
|
35
35
|
const rawAttributes = options.attributes ?? {};
|
|
36
|
-
const redactedAttributes = config.enabled ?
|
|
37
|
-
const redactedBody = config.enabled ?
|
|
36
|
+
const redactedAttributes = config.enabled ? chunk4IUHXUCJ_cjs.redactValue(rawAttributes, config) : rawAttributes;
|
|
37
|
+
const redactedBody = config.enabled ? chunk4IUHXUCJ_cjs.redactValue(String(message), config) : String(message);
|
|
38
38
|
const record = {
|
|
39
39
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40
40
|
severity,
|
|
@@ -46,11 +46,11 @@ function logImpl(message, options = {}) {
|
|
|
46
46
|
};
|
|
47
47
|
transport.track({ logs: [record] });
|
|
48
48
|
}
|
|
49
|
-
var log =
|
|
49
|
+
var log = chunkPSNZZBQJ_cjs.absorbErrorsSync(logImpl, {
|
|
50
50
|
fingerprint: "morse.log"
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
exports._setEnsureInitialized = _setEnsureInitialized;
|
|
54
54
|
exports.log = log;
|
|
55
|
-
//# sourceMappingURL=chunk-
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
55
|
+
//# sourceMappingURL=chunk-LIP3XCTK.cjs.map
|
|
56
|
+
//# sourceMappingURL=chunk-LIP3XCTK.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/log.ts"],"names":["init_redaction","init_tracing","getTransport","getActiveTraceState","getRedactionConfig","redactValue","absorbErrorsSync"],"mappings":";;;;;;AA8BAA,gCAAA,EAAA;AACAC,8BAAA,EAAA;AA2BA,IAAM,oBAAA,GAAuB,cAAA;AAS7B,IAAI,oBAAgC,MAAM;AAE1C,CAAA;AAGO,SAAS,sBAAsB,EAAA,EAAsB;AAC1D,EAAA,iBAAA,GAAoB,EAAA;AACtB;AAEA,SAAS,OAAA,CAAQ,OAAA,EAAiB,OAAA,GAAsB,EAAC,EAAS;AAGhE,EAAA,iBAAA,EAAkB;AAClB,EAAA,MAAM,YAAkCC,8BAAA,EAAa;AACrD,EAAA,IAAI,cAAc,IAAA,EAAM;AAGtB,IAAA;AAAA,EACF;AAMA,EAAA,IAAI,OAAA,GAAyB,QAAQ,OAAA,IAAW,IAAA;AAChD,EAAA,IAAI,MAAA,GAAwB,QAAQ,MAAA,IAAU,IAAA;AAC9C,EAAA,IAAI,OAAA,KAAY,IAAA,IAAQ,MAAA,KAAW,IAAA,EAAM;AACvC,IAAA,MAAM,QAAQC,qCAAA,EAAoB;AAClC,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,IAAI,OAAA,KAAY,IAAA,EAAM,OAAA,GAAU,KAAA,CAAM,OAAA;AACtC,MAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,KAAA,CAAM,SAAA,CAAU,SAAS,CAAA,EAAG;AACjD,QAAA,MAAA,GAAS,MAAM,SAAA,CAAU,KAAA,CAAM,SAAA,CAAU,MAAA,GAAS,CAAC,CAAA,CAAG,OAAA;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAA,CAAY,OAAA,CAAQ,QAAA,IAAY,MAAA,EAAQ,WAAA,EAAY;AAC1D,EAAA,MAAM,WAAA,GAAc,QAAQ,WAAA,IAAe,oBAAA;AAK3C,EAAA,MAAM,SAASC,oCAAA,EAAmB;AAClC,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,UAAA,IAAc,EAAC;AAC7C,EAAA,MAAM,qBAAqB,MAAA,CAAO,OAAA,GAC7BC,6BAAA,CAAY,aAAA,EAAe,MAAM,CAAA,GAClC,aAAA;AACJ,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,OAAA,GACvBA,6BAAA,CAAY,MAAA,CAAO,OAAO,CAAA,EAAG,MAAM,CAAA,GACpC,MAAA,CAAO,OAAO,CAAA;AAElB,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,QAAA;AAAA,IACA,YAAA,EAAc,WAAA;AAAA,IACd,IAAA,EAAM,YAAA;AAAA,IACN,UAAA,EAAY,kBAAA;AAAA,IACZ,QAAA,EAAU,OAAA;AAAA,IACV,OAAA,EAAS;AAAA,GACX;AAEA,EAAA,SAAA,CAAU,MAAM,EAAE,IAAA,EAAM,CAAC,MAAM,GAAG,CAAA;AACpC;AAmCO,IAAM,GAAA,GAAMC,mCAAiB,OAAA,EAAS;AAAA,EAC3C,WAAA,EAAa;AACf,CAAC","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../../src/log.ts"],"names":["init_redaction","init_tracing","getTransport","getActiveTraceState","getRedactionConfig","redactValue","absorbErrorsSync"],"mappings":";;;;;;AA8BAA,gCAAA,EAAA;AACAC,8BAAA,EAAA;AA2BA,IAAM,oBAAA,GAAuB,cAAA;AAS7B,IAAI,oBAAgC,MAAM;AAE1C,CAAA;AAGO,SAAS,sBAAsB,EAAA,EAAsB;AAC1D,EAAA,iBAAA,GAAoB,EAAA;AACtB;AAEA,SAAS,OAAA,CAAQ,OAAA,EAAiB,OAAA,GAAsB,EAAC,EAAS;AAGhE,EAAA,iBAAA,EAAkB;AAClB,EAAA,MAAM,YAAkCC,8BAAA,EAAa;AACrD,EAAA,IAAI,cAAc,IAAA,EAAM;AAGtB,IAAA;AAAA,EACF;AAMA,EAAA,IAAI,OAAA,GAAyB,QAAQ,OAAA,IAAW,IAAA;AAChD,EAAA,IAAI,MAAA,GAAwB,QAAQ,MAAA,IAAU,IAAA;AAC9C,EAAA,IAAI,OAAA,KAAY,IAAA,IAAQ,MAAA,KAAW,IAAA,EAAM;AACvC,IAAA,MAAM,QAAQC,qCAAA,EAAoB;AAClC,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,IAAI,OAAA,KAAY,IAAA,EAAM,OAAA,GAAU,KAAA,CAAM,OAAA;AACtC,MAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,KAAA,CAAM,SAAA,CAAU,SAAS,CAAA,EAAG;AACjD,QAAA,MAAA,GAAS,MAAM,SAAA,CAAU,KAAA,CAAM,SAAA,CAAU,MAAA,GAAS,CAAC,CAAA,CAAG,OAAA;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAA,CAAY,OAAA,CAAQ,QAAA,IAAY,MAAA,EAAQ,WAAA,EAAY;AAC1D,EAAA,MAAM,WAAA,GAAc,QAAQ,WAAA,IAAe,oBAAA;AAK3C,EAAA,MAAM,SAASC,oCAAA,EAAmB;AAClC,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,UAAA,IAAc,EAAC;AAC7C,EAAA,MAAM,qBAAqB,MAAA,CAAO,OAAA,GAC7BC,6BAAA,CAAY,aAAA,EAAe,MAAM,CAAA,GAClC,aAAA;AACJ,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,OAAA,GACvBA,6BAAA,CAAY,MAAA,CAAO,OAAO,CAAA,EAAG,MAAM,CAAA,GACpC,MAAA,CAAO,OAAO,CAAA;AAElB,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,QAAA;AAAA,IACA,YAAA,EAAc,WAAA;AAAA,IACd,IAAA,EAAM,YAAA;AAAA,IACN,UAAA,EAAY,kBAAA;AAAA,IACZ,QAAA,EAAU,OAAA;AAAA,IACV,OAAA,EAAS;AAAA,GACX;AAEA,EAAA,SAAA,CAAU,MAAM,EAAE,IAAA,EAAM,CAAC,MAAM,GAAG,CAAA;AACpC;AAmCO,IAAM,GAAA,GAAMC,mCAAiB,OAAA,EAAS;AAAA,EAC3C,WAAA,EAAa;AACf,CAAC","file":"chunk-LIP3XCTK.cjs","sourcesContent":["/**\n * Phase 12.5 Tier 1.2 — TypeScript SDK `log()` export.\n *\n * Closes the TS side of Feature #4 \"Gap A\": before this module, customers\n * using the TS SDK had no way to populate the Logs tab of a trace's\n * Correlation panel without standing up their own OTel collector. The\n * Python SDK already had `morse.log(...)` (AGE-240); this is the\n * cross-language peer.\n *\n * Semantics mirror Python's `morse.log()`\n * (`apps/sdk/python/src/morse/__init__.py:360-411`):\n *\n * - Default severity: \"info\" (case-normalised to upper on the wire).\n * - Default service_name: \"morse-sdk-ts\" (overridable).\n * - Auto-reads the active trace_id + span_id from the SDK's existing\n * `node:async_hooks.AsyncLocalStorage` context (re-uses\n * `getActiveTraceState()` — the same primitive `run()`/`span()` use).\n * - Batched: the record is enqueued on the existing `BatchTransport`,\n * which flushes it to `/api/v1/logs/ingest` (derived from the traces\n * batch endpoint) on the next tick. NO synchronous fetch per call.\n * - Internal errors are absorbed via `absorbErrorsSync` so they never\n * propagate into the customer's logging call. Mirrors the Python\n * `@absorb_errors` decorator pattern.\n *\n * Wire shape: `{ logs: [{ timestamp, severity, service_name, body,\n * attributes, trace_id, span_id }] }`. See `apps/api/apps/logs/\n * controllers.py:66-134` for the API contract.\n */\n\nimport { absorbErrorsSync } from \"./_internal/errors\";\nimport { redactValue } from \"./_internal/redaction\";\nimport {\n getActiveTraceState,\n getRedactionConfig,\n getTransport,\n type TransportLike,\n} from \"./_internal/tracing\";\n\n/** Log severity — case-insensitive on input, upper-cased on the wire. */\nexport type LogSeverity = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n\n/** Options accepted by `log()`. */\nexport interface LogOptions {\n /** Default: `\"info\"`. Upper-cased server-side. */\n severity?: LogSeverity;\n /** Free-form structured fields persisted on the record. */\n attributes?: Record<string, unknown>;\n /**\n * Override the auto-detected trace_id. Use only when emitting on\n * behalf of a known external trace (rare).\n */\n traceId?: string;\n /** Override the auto-detected span_id. Same caveat as `traceId`. */\n spanId?: string;\n /** Logical service tag. Default: `\"morse-sdk-ts\"`. */\n serviceName?: string;\n}\n\nconst DEFAULT_SERVICE_NAME = \"morse-sdk-ts\";\n\n/**\n * Lazy-init hook injected by `index.ts`. Allows `log()` to participate\n * in env-driven auto-init (matching the behaviour of `track()` /\n * `record()`) without `log.ts` reaching into the singleton state.\n *\n * @internal\n */\nlet ensureInitialized: () => void = () => {\n /* default no-op; replaced from index.ts */\n};\n\n/** @internal */\nexport function _setEnsureInitialized(fn: () => void): void {\n ensureInitialized = fn;\n}\n\nfunction logImpl(message: string, options: LogOptions = {}): void {\n // Match Python semantics: env-driven auto-init kicks in if the SDK\n // hasn't been explicitly init()'d yet but MORSE_API_KEY is set.\n ensureInitialized();\n const transport: TransportLike | null = getTransport();\n if (transport === null) {\n // SDK not initialised — silent no-op. Matches Python behaviour\n // (`_ensure_initialized()` short-circuit).\n return;\n }\n\n // Auto-pull trace + span IDs from the active context. Re-uses the\n // exact same context primitive that `track()` / `run()` / `span()`\n // use, so a `log()` call inside an `await run(...)` callback will\n // see the active trace's IDs.\n let traceId: string | null = options.traceId ?? null;\n let spanId: string | null = options.spanId ?? null;\n if (traceId === null || spanId === null) {\n const state = getActiveTraceState();\n if (state !== null) {\n if (traceId === null) traceId = state.traceId;\n if (spanId === null && state.spanStack.length > 0) {\n spanId = state.spanStack[state.spanStack.length - 1]!.span_id;\n }\n }\n }\n\n const severity = (options.severity ?? \"info\").toUpperCase();\n const serviceName = options.serviceName ?? DEFAULT_SERVICE_NAME;\n\n // PII redaction reuses the trace path's allow-list config. Mirrors\n // the Python client's `self._redaction_config.redact_value(payload)`\n // call.\n const config = getRedactionConfig();\n const rawAttributes = options.attributes ?? {};\n const redactedAttributes = config.enabled\n ? (redactValue(rawAttributes, config) as Record<string, unknown>)\n : rawAttributes;\n const redactedBody = config.enabled\n ? (redactValue(String(message), config) as string)\n : String(message);\n\n const record = {\n timestamp: new Date().toISOString(),\n severity,\n service_name: serviceName,\n body: redactedBody,\n attributes: redactedAttributes,\n trace_id: traceId,\n span_id: spanId,\n };\n\n transport.track({ logs: [record] });\n}\n\n/**\n * Emit a log record correlated to the current trace context.\n *\n * Auto-correlates to the surrounding `morse.run()` /\n * `morse.span()` if one is active. Inside a trace, the record's\n * `trace_id` + `span_id` are filled in from `AsyncLocalStorage`;\n * outside a trace, both fields are `null` and the record is still\n * accepted by the backend (it surfaces in the service-wide Logs view\n * but not on any individual trace's Correlation panel).\n *\n * Non-blocking. Batched alongside trace events on the existing\n * transport — flushes at the SDK's configured interval (default 2s).\n * Internal errors are absorbed; this call never throws.\n *\n * Silent no-op when the SDK isn't initialised (no `MORSE_API_KEY`\n * and no explicit `init()` call).\n *\n * @example\n * ```ts\n * import { init, runTraced, log } from \"@morsehq-dev/sdk\";\n *\n * init({ apiKey: process.env.MORSE_API_KEY });\n *\n * await runTraced({ agentName: \"lead-qualifier\" }, async () => {\n * log(\"starting search\", { attributes: { query: \"morse\" } });\n * const results = await search();\n * log(\"search complete\", {\n * severity: \"info\",\n * attributes: { result_count: results.length },\n * });\n * });\n * ```\n */\nexport const log = absorbErrorsSync(logImpl, {\n fingerprint: \"morse.log\",\n});\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { init_diagnostics, report } from './chunk-
|
|
1
|
+
import { init_diagnostics, report } from './chunk-PXHTLCEU.js';
|
|
2
2
|
|
|
3
3
|
// src/_internal/errors.ts
|
|
4
4
|
init_diagnostics();
|
|
@@ -24,5 +24,5 @@ function absorbErrorsAsync(fn, options) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export { absorbErrorsAsync, absorbErrorsSync };
|
|
27
|
-
//# sourceMappingURL=chunk-
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
27
|
+
//# sourceMappingURL=chunk-OUQAH27A.js.map
|
|
28
|
+
//# sourceMappingURL=chunk-OUQAH27A.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/_internal/errors.ts"],"names":[],"mappings":";;;AAsBA,gBAAA,EAAA;AAiBO,SAAS,gBAAA,CACd,IACA,OAAA,EACyC;AACzC,EAAA,OAAO,IAAI,IAAA,KAAqC;AAC9C,IAAA,IAAI;AACF,MAAA,OAAO,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACnB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA;AACF;AAOO,SAAS,iBAAA,CACd,IACA,OAAA,EACkD;AAClD,EAAA,OAAO,UAAU,IAAA,KAA8C;AAC7D,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACzB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../../src/_internal/errors.ts"],"names":[],"mappings":";;;AAsBA,gBAAA,EAAA;AAiBO,SAAS,gBAAA,CACd,IACA,OAAA,EACyC;AACzC,EAAA,OAAO,IAAI,IAAA,KAAqC;AAC9C,IAAA,IAAI;AACF,MAAA,OAAO,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACnB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA;AACF;AAOO,SAAS,iBAAA,CACd,IACA,OAAA,EACkD;AAClD,EAAA,OAAO,UAAU,IAAA,KAA8C;AAC7D,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACzB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA;AACF","file":"chunk-OUQAH27A.js","sourcesContent":["/**\n * Non-invasive error isolation — the foundational SDK guarantee.\n *\n * Mirrors Python's `_internal/errors.py` `@absorb_errors` decorator. Every\n * public SDK function and every adapter-installed wrapper is wrapped with\n * `absorbErrors()`. The wrapper catches all exceptions and reports them\n * out-of-band to Morse's own diagnostics endpoint, then returns a benign value\n * (typically `undefined`) instead of propagating.\n *\n * Foundational principle:\n *\n * Telemetry must never break the host application.\n *\n * The customer's call returns its original result (or `undefined`)\n * regardless of whether the SDK's recording path succeeded.\n *\n * Note on async: TypeScript-land has no `KeyboardInterrupt` equivalent —\n * the analogue is \"no exceptions are special\". We absorb everything,\n * and rely on Node's `process.exit` / browser navigation to tear down\n * the runtime cleanly.\n */\n\nimport { report } from \"./diagnostics\";\n\nexport interface AbsorbErrorsOptions {\n /**\n * Stable identifier for grouping. Used for server-side grouping and\n * the rate limiter (max 100 events per fingerprint per minute).\n */\n fingerprint: string;\n /** Optional metadata attached to the report; scrubbed against an allow-list. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Wrap a synchronous function so that any thrown exception is absorbed\n * (reported out-of-band) instead of propagating. Returns `undefined` on\n * absorbed error.\n */\nexport function absorbErrorsSync<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn,\n options: AbsorbErrorsOptions,\n): (...args: TArgs) => TReturn | undefined {\n return (...args: TArgs): TReturn | undefined => {\n try {\n return fn(...args);\n } catch (err) {\n report(err, options);\n return undefined;\n }\n };\n}\n\n/**\n * Wrap an async function so that any rejection or thrown exception is\n * absorbed (reported out-of-band) instead of propagating. Returns\n * `undefined` on absorbed error.\n */\nexport function absorbErrorsAsync<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => Promise<TReturn>,\n options: AbsorbErrorsOptions,\n): (...args: TArgs) => Promise<TReturn | undefined> {\n return async (...args: TArgs): Promise<TReturn | undefined> => {\n try {\n return await fn(...args);\n } catch (err) {\n report(err, options);\n return undefined;\n }\n };\n}\n\n/**\n * Higher-order alias chosen to read like the Python decorator: pass a\n * function in, get a wrapped version back. Resolves to the sync or async\n * variant based on the runtime return value (a Promise). Defaults to\n * sync at the type level; use `absorbErrorsAsync` directly for proper\n * async typing.\n */\nexport const absorbErrors = absorbErrorsSync;\n"]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk4IUHXUCJ_cjs = require('./chunk-4IUHXUCJ.cjs');
|
|
4
4
|
|
|
5
5
|
// src/_internal/errors.ts
|
|
6
|
-
|
|
6
|
+
chunk4IUHXUCJ_cjs.init_diagnostics();
|
|
7
7
|
function absorbErrorsSync(fn, options) {
|
|
8
8
|
return (...args) => {
|
|
9
9
|
try {
|
|
10
10
|
return fn(...args);
|
|
11
11
|
} catch (err) {
|
|
12
|
-
|
|
12
|
+
chunk4IUHXUCJ_cjs.report(err, options);
|
|
13
13
|
return void 0;
|
|
14
14
|
}
|
|
15
15
|
};
|
|
@@ -19,7 +19,7 @@ function absorbErrorsAsync(fn, options) {
|
|
|
19
19
|
try {
|
|
20
20
|
return await fn(...args);
|
|
21
21
|
} catch (err) {
|
|
22
|
-
|
|
22
|
+
chunk4IUHXUCJ_cjs.report(err, options);
|
|
23
23
|
return void 0;
|
|
24
24
|
}
|
|
25
25
|
};
|
|
@@ -27,5 +27,5 @@ function absorbErrorsAsync(fn, options) {
|
|
|
27
27
|
|
|
28
28
|
exports.absorbErrorsAsync = absorbErrorsAsync;
|
|
29
29
|
exports.absorbErrorsSync = absorbErrorsSync;
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
31
|
-
//# sourceMappingURL=chunk-
|
|
30
|
+
//# sourceMappingURL=chunk-PSNZZBQJ.cjs.map
|
|
31
|
+
//# sourceMappingURL=chunk-PSNZZBQJ.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/_internal/errors.ts"],"names":["init_diagnostics","report"],"mappings":";;;;;AAsBAA,kCAAA,EAAA;AAiBO,SAAS,gBAAA,CACd,IACA,OAAA,EACyC;AACzC,EAAA,OAAO,IAAI,IAAA,KAAqC;AAC9C,IAAA,IAAI;AACF,MAAA,OAAO,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACnB,SAAS,GAAA,EAAK;AACZ,MAAAC,wBAAA,CAAO,KAAK,OAAO,CAAA;AACnB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA;AACF;AAOO,SAAS,iBAAA,CACd,IACA,OAAA,EACkD;AAClD,EAAA,OAAO,UAAU,IAAA,KAA8C;AAC7D,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACzB,SAAS,GAAA,EAAK;AACZ,MAAAA,wBAAA,CAAO,KAAK,OAAO,CAAA;AACnB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../../src/_internal/errors.ts"],"names":["init_diagnostics","report"],"mappings":";;;;;AAsBAA,kCAAA,EAAA;AAiBO,SAAS,gBAAA,CACd,IACA,OAAA,EACyC;AACzC,EAAA,OAAO,IAAI,IAAA,KAAqC;AAC9C,IAAA,IAAI;AACF,MAAA,OAAO,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACnB,SAAS,GAAA,EAAK;AACZ,MAAAC,wBAAA,CAAO,KAAK,OAAO,CAAA;AACnB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA;AACF;AAOO,SAAS,iBAAA,CACd,IACA,OAAA,EACkD;AAClD,EAAA,OAAO,UAAU,IAAA,KAA8C;AAC7D,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACzB,SAAS,GAAA,EAAK;AACZ,MAAAA,wBAAA,CAAO,KAAK,OAAO,CAAA;AACnB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA;AACF","file":"chunk-PSNZZBQJ.cjs","sourcesContent":["/**\n * Non-invasive error isolation — the foundational SDK guarantee.\n *\n * Mirrors Python's `_internal/errors.py` `@absorb_errors` decorator. Every\n * public SDK function and every adapter-installed wrapper is wrapped with\n * `absorbErrors()`. The wrapper catches all exceptions and reports them\n * out-of-band to Morse's own diagnostics endpoint, then returns a benign value\n * (typically `undefined`) instead of propagating.\n *\n * Foundational principle:\n *\n * Telemetry must never break the host application.\n *\n * The customer's call returns its original result (or `undefined`)\n * regardless of whether the SDK's recording path succeeded.\n *\n * Note on async: TypeScript-land has no `KeyboardInterrupt` equivalent —\n * the analogue is \"no exceptions are special\". We absorb everything,\n * and rely on Node's `process.exit` / browser navigation to tear down\n * the runtime cleanly.\n */\n\nimport { report } from \"./diagnostics\";\n\nexport interface AbsorbErrorsOptions {\n /**\n * Stable identifier for grouping. Used for server-side grouping and\n * the rate limiter (max 100 events per fingerprint per minute).\n */\n fingerprint: string;\n /** Optional metadata attached to the report; scrubbed against an allow-list. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Wrap a synchronous function so that any thrown exception is absorbed\n * (reported out-of-band) instead of propagating. Returns `undefined` on\n * absorbed error.\n */\nexport function absorbErrorsSync<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn,\n options: AbsorbErrorsOptions,\n): (...args: TArgs) => TReturn | undefined {\n return (...args: TArgs): TReturn | undefined => {\n try {\n return fn(...args);\n } catch (err) {\n report(err, options);\n return undefined;\n }\n };\n}\n\n/**\n * Wrap an async function so that any rejection or thrown exception is\n * absorbed (reported out-of-band) instead of propagating. Returns\n * `undefined` on absorbed error.\n */\nexport function absorbErrorsAsync<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => Promise<TReturn>,\n options: AbsorbErrorsOptions,\n): (...args: TArgs) => Promise<TReturn | undefined> {\n return async (...args: TArgs): Promise<TReturn | undefined> => {\n try {\n return await fn(...args);\n } catch (err) {\n report(err, options);\n return undefined;\n }\n };\n}\n\n/**\n * Higher-order alias chosen to read like the Python decorator: pass a\n * function in, get a wrapped version back. Resolves to the sync or async\n * variant based on the runtime return value (a Promise). Defaults to\n * sync at the type level; use `absorbErrorsAsync` directly for proper\n * async typing.\n */\nexport const absorbErrors = absorbErrorsSync;\n"]}
|
|
@@ -437,6 +437,7 @@ function recordDrop(reason, category, quantity = 1) {
|
|
|
437
437
|
if (checkBucket(localLogBuckets, `drop:${key}`, LOCAL_LOG_LIMIT_PER_WINDOW, LOCAL_LOG_WINDOW_MS)) {
|
|
438
438
|
console.warn(`morse: dropped ${quantity} ${category} (${reason}) \u2014 telemetry is being lost`);
|
|
439
439
|
}
|
|
440
|
+
if (transmissionAllowed()) ensureTimer();
|
|
440
441
|
} catch {
|
|
441
442
|
}
|
|
442
443
|
}
|
|
@@ -610,7 +611,7 @@ var init_diagnostics = __esm({
|
|
|
610
611
|
"src/_internal/diagnostics.ts"() {
|
|
611
612
|
init_env();
|
|
612
613
|
init_redaction();
|
|
613
|
-
SDK_VERSION = "0.
|
|
614
|
+
SDK_VERSION = "0.6.0-rc.1" ;
|
|
614
615
|
LEVEL_OFF = "off";
|
|
615
616
|
LEVEL_ERROR = "error";
|
|
616
617
|
LEVEL_DEBUG = "debug";
|
|
@@ -760,7 +761,10 @@ var init_spans = __esm({
|
|
|
760
761
|
// MHQ-482: matches Python's `SpanType.RETRIEVER` (apps/sdk/python/src/morse_ai/spans.py).
|
|
761
762
|
// @beta — retriever span type is subject to change before SDK v1.0 (see
|
|
762
763
|
// the plain-LangChain adapter's on_retriever_* callbacks in src/langchain/).
|
|
763
|
-
RETRIEVER: "retriever"
|
|
764
|
+
RETRIEVER: "retriever",
|
|
765
|
+
// MHQ-1025: matches Python's `SpanType.HANDOFF`. One span per routing
|
|
766
|
+
// decision between two agents, with `from_agent` / `to_agent` metadata.
|
|
767
|
+
HANDOFF: "handoff"
|
|
764
768
|
};
|
|
765
769
|
}
|
|
766
770
|
});
|
|
@@ -1086,6 +1090,18 @@ function setContext(dims) {
|
|
|
1086
1090
|
if (state.userMetadata === void 0) state.userMetadata = {};
|
|
1087
1091
|
Object.assign(state.userMetadata, coerceDims(dims, "morse.tracing.set_context"));
|
|
1088
1092
|
}
|
|
1093
|
+
function adoptThreadId(value) {
|
|
1094
|
+
const state = getActiveTraceState();
|
|
1095
|
+
if (state === null || state.threadId !== void 0 || value === null || value === void 0) {
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
try {
|
|
1099
|
+
const s = String(value);
|
|
1100
|
+
if (s !== "") state.threadId = s;
|
|
1101
|
+
} catch (err) {
|
|
1102
|
+
report(err, { fingerprint: "morse.tracing.adopt_thread_id" });
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1089
1105
|
function coerceDims(dims, fingerprint) {
|
|
1090
1106
|
const out = {};
|
|
1091
1107
|
for (const k of Object.keys(dims)) {
|
|
@@ -1286,6 +1302,6 @@ var init_propagation = __esm({
|
|
|
1286
1302
|
}
|
|
1287
1303
|
});
|
|
1288
1304
|
|
|
1289
|
-
export { DEFAULT_ENDPOINT, REASON_AUTH_REJECTED, REASON_ENCODE_FAILED, REASON_ENDPOINT_REJECTED, REASON_QUEUE_FULL, REASON_QUOTA_REJECTED, REASON_RETRY_EXHAUSTED, REASON_SEND_FAILED, REASON_SHUTDOWN_DROP, SpanType, W3C_TRACEPARENT_HEADER, _resetForTesting, _resetForTesting2, buildRedactionConfig, buildTraceEntry, extractTraceparent, flushOnce, formatTraceparent, generateSpanId, generateTraceId, getActiveTraceState, getApiKey, getEndpoint, getEngine, getFlushIntervalSeconds, getInternalSource, getLastTrace, getMaxBatchSize, getMaxFieldBytes, getMaxQueueSize, getRedactionConfig, getSampleRate, getTransport, init_diagnostics, init_env, init_otel_provider_browser, init_propagation, init_redaction, init_spans, init_tracing, injectIntoRequestInit, injectTraceparent, isDisabled, isValidInternalSource, nowIso, recordDrop, redactValue, report, runAsync, runSync, sendTrace, setContext, setDiagnosticsClientConfig, setLevel, setRedactionConfig2 as setRedactionConfig, setSource, setTransport, spanAsync, spanSync, startSpan };
|
|
1290
|
-
//# sourceMappingURL=chunk-
|
|
1291
|
-
//# sourceMappingURL=chunk-
|
|
1305
|
+
export { DEFAULT_ENDPOINT, REASON_AUTH_REJECTED, REASON_ENCODE_FAILED, REASON_ENDPOINT_REJECTED, REASON_QUEUE_FULL, REASON_QUOTA_REJECTED, REASON_RETRY_EXHAUSTED, REASON_SEND_FAILED, REASON_SHUTDOWN_DROP, SpanType, W3C_TRACEPARENT_HEADER, _resetForTesting, _resetForTesting2, adoptThreadId, buildRedactionConfig, buildTraceEntry, extractTraceparent, flushOnce, formatTraceparent, generateSpanId, generateTraceId, getActiveTraceState, getApiKey, getEndpoint, getEngine, getFlushIntervalSeconds, getInternalSource, getLastTrace, getMaxBatchSize, getMaxFieldBytes, getMaxQueueSize, getRedactionConfig, getSampleRate, getTransport, init_diagnostics, init_env, init_otel_provider_browser, init_propagation, init_redaction, init_spans, init_tracing, injectIntoRequestInit, injectTraceparent, isDisabled, isValidInternalSource, nowIso, recordDrop, redactValue, report, runAsync, runSync, sendTrace, setContext, setDiagnosticsClientConfig, setLevel, setRedactionConfig2 as setRedactionConfig, setSource, setTransport, spanAsync, spanSync, startSpan };
|
|
1306
|
+
//# sourceMappingURL=chunk-PXHTLCEU.js.map
|
|
1307
|
+
//# sourceMappingURL=chunk-PXHTLCEU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/_internal/env.ts","../../src/_internal/redaction.ts","../../src/_internal/diagnostics.ts","../../src/_internal/otel-provider.browser.ts","../../src/_internal/spans.ts","../../src/_internal/tracing.ts","../../src/propagation.ts"],"names":["setRedactionConfig","out","extractTraceparent","_resetForTesting"],"mappings":"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","file":"chunk-PXHTLCEU.js","sourcesContent":["/**\n * Environment variable resolution for SDK auto-init.\n *\n * The V2 TS SDK supports zero-setup integration: the customer sets\n * `MORSE_API_KEY` in their process environment (Node) or supplies\n * it via build-time replacement (browser bundler), and the SDK\n * auto-initializes on first use. This module centralises the env-var\n * contract so the rules stay in one place.\n *\n * Env vars (all optional unless noted) — must mirror the Python SDK's\n * `_internal/env.py`:\n *\n * - `MORSE_API_KEY` — triggers auto-init when set; absent = SDK dormant\n * - `MORSE_ENDPOINT` — override default ingestion URL\n * - `MORSE_FLUSH_INTERVAL_SECONDS` — override default 2.0s flush interval\n * - `MORSE_DISABLED` — \"1\"/\"true\" makes all SDK calls no-op\n * - `MORSE_SDK_DEBUG` — \"1\"/\"true\" raises internal-error log level\n * - `MORSE_SDK_DISABLE_TELEMETRY` — \"1\"/\"true\" suppresses out-of-band SDK\n * self-diagnostics (errors + delivery counters). Local logging is\n * unaffected — see SDKDIAG-10.\n * - `MORSE_DISABLE_AUTO_DETECT` — (MHQ-482, mirrors Python's `MORSE_DISABLE_AUTO_DETECT`)\n * \"1\"/\"true\" skips the zero-config adapter auto-detect scan\n * - `MORSE_SAMPLE_RATE` — (MHQ-482, mirrors Python MHQ-668/671) deterministic\n * trace-ID head sampling rate in [0.0, 1.0], default 1.0.\n * - `MORSE_MAX_FIELD_BYTES` — (MHQ-482) byte cap applied to input_data / output_data /\n * context_segments / custom metadata at attribute-set\n * time, default 65536.\n * - `MORSE_MAX_QUEUE_SIZE` — (MHQ-482) OTel BatchSpanProcessor queue size, default\n * 2048 (OTel SDK default).\n * - `MORSE_MAX_BATCH_SIZE` — (MHQ-482) OTel BatchSpanProcessor max export batch\n * size, default 512 (OTel SDK default).\n * - `MORSE_LEGACY_TRANSPORT` — (MHQ-482) \"1\"/\"true\" reverts run()/span()/runTraced()\n * to the pre-OTel JSON batch transport instead of OTLP.\n * Escape hatch for the migration window only;\n * record()/log() always use the JSON path.\n * - `MORSE_CAPTURE_DB` — (MHQ-482, mirrors Python's `infra_capture.py`)\n * \"1\"/\"true\" enables zero-config `db` span\n * auto-capture (pg / mysql2 / better-sqlite3).\n * Opt-in, same as the Python SDK.\n * - `MORSE_CAPTURE_INFRA` — (MHQ-482) \"1\"/\"true\" convenience alias that enables\n * ALL infra auto-capture (currently just DB — mirrors\n * Python's combined flag; HTTP capture is a separate\n * port not yet landed in the TS SDK).\n */\n\n/**\n * Default ingestion endpoint.\n *\n * Phase 6c targets the Railway dev URL until the custom domain is wired up\n * in Phase 6d. Mirrors the Python SDK constant in\n * `apps/sdk/python/src/morse/client.py`.\n */\nexport const DEFAULT_ENDPOINT = \"https://api.morsehq.dev/api/v1/traces/batch\";\n\n/**\n * Read an env var in a runtime-agnostic way.\n *\n * Handles Node (`process.env`), Deno (`Deno.env`), and browser\n * environments where `process` is undefined. In the browser the value\n * typically comes from a bundler-time replacement (Next.js inlines\n * `process.env.MORSE_API_KEY` at build time when the var is\n * exposed via `next.config.ts`).\n */\nfunction readEnv(key: string): string | undefined {\n // Node / Next.js (server / build-time replaced)\n if (typeof process !== \"undefined\" && process.env) {\n const v = process.env[key];\n if (typeof v === \"string\") return v;\n }\n // Deno\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const denoGlobal = (globalThis as any).Deno as\n | { env: { get(k: string): string | undefined } }\n | undefined;\n if (denoGlobal?.env?.get) {\n try {\n const v = denoGlobal.env.get(key);\n if (typeof v === \"string\") return v;\n } catch {\n // Permission denied — fall through.\n }\n }\n return undefined;\n}\n\nfunction truthy(value: string | undefined): boolean {\n if (!value) return false;\n return [\"1\", \"true\", \"yes\", \"on\"].includes(value.trim().toLowerCase());\n}\n\nexport function getApiKey(): string | undefined {\n const raw = readEnv(\"MORSE_API_KEY\");\n if (!raw) return undefined;\n const trimmed = raw.trim();\n return trimmed || undefined;\n}\n\nexport function getEndpoint(): string | undefined {\n const raw = readEnv(\"MORSE_ENDPOINT\");\n if (!raw) return undefined;\n const trimmed = raw.trim();\n return trimmed || undefined;\n}\n\nexport function getFlushIntervalSeconds(defaultSeconds = 2.0): number {\n const raw = readEnv(\"MORSE_FLUSH_INTERVAL_SECONDS\");\n if (!raw) return defaultSeconds;\n const parsed = Number.parseFloat(raw.trim());\n if (!Number.isFinite(parsed) || parsed <= 0) return defaultSeconds;\n return parsed;\n}\n\nexport function isDisabled(): boolean {\n return truthy(readEnv(\"MORSE_DISABLED\"));\n}\n\nexport function isDebug(): boolean {\n return truthy(readEnv(\"MORSE_SDK_DEBUG\"));\n}\n\nexport function isTelemetryDisabled(): boolean {\n return truthy(readEnv(\"MORSE_SDK_DISABLE_TELEMETRY\"));\n}\n\n/**\n * True when `MORSE_DISABLE_AUTO_DETECT=1` — the zero-config adapter scan\n * (`_internal/auto-detect.ts`) is skipped entirely. Mirrors the Python SDK's\n * `is_auto_detect_disabled()`. Customers can still call the adapter\n * `wrapX()` / `instrumentX()` functions directly.\n */\nexport function isAutoDetectDisabled(): boolean {\n return truthy(readEnv(\"MORSE_DISABLE_AUTO_DETECT\"));\n}\n\n/**\n * Resource-level \"source\" label for Morse's own dogfood emitters.\n *\n * Mirrors the Python SDK's `get_internal_source()` (PR #90). Only the\n * accepted whitelist values are honoured — any other value is treated\n * as unset so a typo in a customer's environment never accidentally\n * tags their data as internal.\n */\nconst VALID_INTERNAL_SOURCES = new Set([\"copilot\", \"investigator\", \"refagent\", \"ui-bot\"]);\n\nexport function getInternalSource(): string | undefined {\n const raw = readEnv(\"MORSE_INTERNAL_SOURCE\");\n if (!raw) return undefined;\n const trimmed = raw.trim().toLowerCase();\n if (!trimmed) return undefined;\n return VALID_INTERNAL_SOURCES.has(trimmed) ? trimmed : undefined;\n}\n\nexport function isValidInternalSource(value: string | null | undefined): boolean {\n return typeof value === \"string\" && VALID_INTERNAL_SOURCES.has(value);\n}\n\n/**\n * Deterministic trace-ID head sampling rate for the OTel export pipeline\n * (MHQ-482, mirrors Python `_internal/env.py::get_sample_rate`). Out-of-range\n * or unparseable values fall back to `default`.\n */\nexport function getSampleRate(defaultRate = 1.0): number {\n const raw = readEnv(\"MORSE_SAMPLE_RATE\");\n if (!raw) return defaultRate;\n const parsed = Number.parseFloat(raw.trim());\n if (!Number.isFinite(parsed) || parsed < 0.0 || parsed > 1.0) return defaultRate;\n return parsed;\n}\n\n/** Byte cap for input_data/output_data/context_segments/metadata attribute values. */\nexport function getMaxFieldBytes(defaultBytes = 65536): number {\n const raw = readEnv(\"MORSE_MAX_FIELD_BYTES\");\n if (!raw) return defaultBytes;\n const parsed = Number.parseInt(raw.trim(), 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultBytes;\n}\n\n/** OTel BatchSpanProcessor queue size (OTel SDK default: 2048). */\nexport function getMaxQueueSize(defaultSize = 2048): number {\n const raw = readEnv(\"MORSE_MAX_QUEUE_SIZE\");\n if (!raw) return defaultSize;\n const parsed = Number.parseInt(raw.trim(), 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultSize;\n}\n\n/** OTel BatchSpanProcessor max export batch size (OTel SDK default: 512). */\nexport function getMaxBatchSize(defaultSize = 512): number {\n const raw = readEnv(\"MORSE_MAX_BATCH_SIZE\");\n if (!raw) return defaultSize;\n const parsed = Number.parseInt(raw.trim(), 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultSize;\n}\n\n/**\n * Escape hatch: `run()`/`span()`/`runTraced()` revert to the pre-OTel JSON\n * batch transport instead of OTLP when set. `record()`/`log()` always use\n * the JSON path regardless of this flag.\n */\nexport function isLegacyTransport(): boolean {\n return truthy(readEnv(\"MORSE_LEGACY_TRANSPORT\"));\n}\n\n/**\n * DB auto-capture opt-in (MHQ-482, mirrors Python's `infra_capture.py`'s\n * `MORSE_CAPTURE_DB` / `MORSE_CAPTURE_INFRA` env flags — see\n * `maybe_enable_from_env`). Opt-in while the approach is proven across\n * drivers, same posture as the Python SDK.\n */\nexport function isDbCaptureEnabled(): boolean {\n return truthy(readEnv(\"MORSE_CAPTURE_DB\")) || truthy(readEnv(\"MORSE_CAPTURE_INFRA\"));\n}\n","/**\n * Client-side PII redaction for the TypeScript SDK.\n *\n * Phase 6f Wave B G-02. Mirrors:\n * - `apps/sdk/python/src/morse/redaction.py` (Python SDK)\n * - `apps/api/apps/core/redaction/patterns.py` (server-side floor)\n *\n * The eight pattern catalogue is canonical across all three implementations.\n * The parity corpus at\n * `openspec/changes/phase-6f-g02-pii-redaction/tests/parity_corpus.json`\n * pins identical input → output behaviour on every row.\n *\n * Redaction runs default-on inside the SDK process so that sensitive strings\n * never leave the customer's runtime. Customers can:\n * - disable the whole SDK layer (`redaction.enabled = false`),\n * - turn off non-mandatory built-ins (`disabledPatterns`),\n * - inject custom regexes (`extraPatterns`).\n *\n * The four mandatory keys (`api_key_prefixed`, `jwt`, `credit_card`,\n * `ssn_us`) cannot be disabled at the SDK — attempting to do so throws at\n * `init()`. Disabling everything at the SDK still leaves the server-side\n * mandatory floor in place.\n */\n\n/* ------------------------------------------------------------------------ */\n/* Pattern catalogue */\n/* ------------------------------------------------------------------------ */\n\n/**\n * Canonical pattern keys. The redactor walks them in this order; once a\n * substring is replaced by a `[REDACTED:...]` marker, later patterns see\n * the replacement and don't re-match digit/word fragments inside it.\n *\n * Order MUST match `apps/api/apps/core/redaction/patterns.py` and\n * `apps/sdk/python/.../redaction.py` so the parity corpus produces\n * identical output across implementations.\n */\nexport const PATTERN_ORDER: readonly string[] = [\n \"api_key_prefixed\",\n \"jwt\",\n \"credit_card\",\n \"email\",\n \"phone_us\",\n \"phone_e164\",\n \"ssn_us\",\n \"ip_address\",\n // Last: the value-shaped patterns above are more specific, so a JWT inside\n // `authorization: Bearer eyJ...` gets its own tag before this one runs.\n \"secret_assignment\",\n] as const;\n\n/** Patterns that customers cannot disable at the SDK layer. */\nexport const MANDATORY_PATTERNS: ReadonlySet<string> = new Set([\n \"api_key_prefixed\",\n \"jwt\",\n \"credit_card\",\n \"ssn_us\",\n]);\n\n/** Patterns that ship disabled by default (opt-in). */\nexport const DEFAULT_OFF_PATTERNS: ReadonlySet<string> = new Set([\"ip_address\"]);\n\n/**\n * Short replacement keys. The replacement format is `[REDACTED:<short>]`.\n * `phone_us` and `phone_e164` collapse to `phone`.\n */\nconst SHORT_KEYS: Record<string, string> = {\n api_key_prefixed: \"api_key\",\n jwt: \"jwt\",\n credit_card: \"credit_card\",\n email: \"email\",\n phone_us: \"phone\",\n phone_e164: \"phone\",\n ssn_us: \"ssn\",\n ip_address: \"ip\",\n secret_assignment: \"secret\", // pragma: allowlist secret — a label, not a value\n};\n\n/**\n * Compiled regexes for each pattern. The `g` flag is required so the\n * `String.replace(regex, ...)` call walks the whole string. `i` flag is\n * applied where the canonical Python form is case-insensitive (email,\n * ip_address) for lowercase IPv6 + uppercase email parity.\n *\n * NB: the Luhn-validating credit_card pattern returns *candidate* matches;\n * `redactString` runs Luhn before deciding to replace.\n */\n/**\n * Source for the `secret_assignment` pattern, exported so the diagnostics\n * channel can compile its own instance and apply it unconditionally (MHQ-973).\n *\n * Exported as a STRING, not a RegExp: a `g`-flagged RegExp carries `lastIndex`\n * state, and sharing one instance across call sites is a well-known way to get\n * intermittently-skipped matches.\n */\nexport const SECRET_ASSIGNMENT_SOURCE =\n // Compound keys accept `=` or `:`; bare `secret` requires `=`, because with\n // `:` it is more often a marker (`k8s-secret: mounted`) than an assignment.\n \"(?:(?:password|passwd|pwd|client[-_]?secret|secret[-_]?key|\" +\n \"private[-_]?key|access[-_]?key|api[-_]?key|auth[-_]?token|\" +\n \"access[-_]?token|refresh[-_]?token|id[-_]?token|session[-_]?token|\" +\n \"authorization|credentials?)[\\\"']?\\\\s*[=:]\" +\n \"|\\\\bsecret[\\\"']?\\\\s*=)\" +\n \"\\\\s*(?:bearer\\\\s+)?(?:\\\"[^\\\"]*\\\"|'[^']*'|\\\\S+)\";\n\nconst PATTERNS: Record<string, RegExp> = {\n api_key_prefixed: new RegExp(\n \"\\\\b(?:\" +\n \"sk-[A-Za-z0-9_-]{20,}\" +\n \"|sk_(?:live|test)_[A-Za-z0-9]{20,}\" +\n \"|mhq_[A-Za-z0-9]{20,}\" +\n \"|av_[A-Za-z0-9]{20,}\" +\n \"|ghp_[A-Za-z0-9]{36}\" +\n \"|gho_[A-Za-z0-9]{36}\" +\n \"|ghu_[A-Za-z0-9]{36}\" +\n \"|ghs_[A-Za-z0-9]{36}\" +\n \"|ghr_[A-Za-z0-9]{36}\" +\n \"|xox[bopsa]-[0-9A-Za-z\\\\-]{10,}\" +\n \"|(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}\" +\n \")\\\\b\",\n \"g\",\n ),\n jwt: new RegExp(\n \"\\\\beyJ[A-Za-z0-9_=-]{16,}\\\\.eyJ[A-Za-z0-9_=-]{16,}\\\\.[A-Za-z0-9_=-]{16,}\\\\b\",\n \"g\",\n ),\n credit_card: new RegExp(\"\\\\b(?:\\\\d[ -]?){12,18}\\\\d\\\\b\", \"g\"),\n email: new RegExp(\"\\\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,}\\\\b\", \"gi\"),\n // The leading `(?<!\\d)` and trailing `(?!\\d)` lookarounds prevent\n // the phone matcher from carving a 10-digit substring out of a longer\n // continuous digit run (e.g., a 16-digit credit-card-shaped number that\n // failed Luhn). Without them, `1234567890123456` would emit a\n // `[REDACTED:phone]` for digits 7-16 even though the whole run was\n // never a real phone number. The canonical Python regex needs the same\n // shim — see redaction.py.\n phone_us: new RegExp(\n \"(?<!\\\\d)(?:\\\\+?1[ \\\\-.])?\\\\(?[2-9]\\\\d{2}\\\\)?[ \\\\-.]?\\\\d{3}[ \\\\-.]?\\\\d{4}(?!\\\\d)\",\n \"g\",\n ),\n phone_e164: new RegExp(\"(?<!\\\\d)\\\\+(?:[0-9][ \\\\-.]?){8,14}[0-9](?!\\\\d)\", \"g\"),\n ssn_us: new RegExp(\n \"\\\\b(?!000|666|9\\\\d{2})\\\\d{3}[ \\\\-.](?!00)\\\\d{2}[ \\\\-.](?!0000)\\\\d{4}\\\\b\",\n \"g\",\n ),\n ip_address: new RegExp(\n \"\\\\b(?:\" +\n \"(?:25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)\" +\n \"(?:\\\\.(?:25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)){3}\" +\n \"|(?:[A-F0-9]{1,4}:){2,7}[A-F0-9]{1,4}\" +\n \")\\\\b\",\n \"gi\",\n ),\n // MHQ-973 — key-context secret assignment. Every pattern above is\n // VALUE-shaped: it recognises a credential by its own format. That cannot\n // catch `password=hunter2` — `hunter2` is an ordinary word, and only the KEY\n // marks it as a secret.\n //\n // Deliberately excludes a bare `token`: this is an LLM-observability SDK, and\n // `input_tokens=100` / `max_tokens=4096` are core telemetry. Only unambiguous\n // `*_token` compounds match. No leading `\\\\b` either, so `PGPASSWORD=` and\n // `MYSQL_PWD=` are caught; the `[=:]` anchor is what prevents false positives.\n secret_assignment: new RegExp(SECRET_ASSIGNMENT_SOURCE, \"gi\"),\n};\n\n/* ------------------------------------------------------------------------ */\n/* Configuration */\n/* ------------------------------------------------------------------------ */\n\n/** Public SDK option. Mirrors `redaction` in `init()`. */\nexport interface RedactionOptions {\n /** Master switch. Default: `true`. */\n enabled?: boolean;\n /** Pattern keys to selectively disable (mandatory keys rejected). */\n disabledPatterns?: string[];\n /** Customer-supplied regex strings (ECMAScript syntax). */\n extraPatterns?: string[];\n}\n\n/** Validated, frozen config fed into `redactString` / `redactValue`. */\nexport interface RedactionConfig {\n enabled: boolean;\n /** Keys actually applied, in stable order. */\n enabledPatterns: ReadonlySet<string>;\n /** Custom compiled regexes — applied last, with `[REDACTED:custom]`. */\n extraCompiled: readonly RegExp[];\n}\n\n/** Hard caps mirroring server-side validation. */\nconst EXTRA_PATTERN_CAP = 10;\nconst EXTRA_PATTERN_CHAR_CAP = 256;\n\n/**\n * Validate raw user options and return a normalised config. Throws on:\n * - disabling a mandatory pattern,\n * - more than 10 extra patterns,\n * - any extra pattern over 256 chars,\n * - any extra pattern that fails to compile via `new RegExp(...)`.\n *\n * `enabled = false` short-circuits — no patterns are applied.\n */\nexport function buildRedactionConfig(options?: RedactionOptions): RedactionConfig {\n const opts = options ?? {};\n const enabled = opts.enabled !== false;\n\n if (!enabled) {\n return {\n enabled: false,\n enabledPatterns: new Set<string>(),\n extraCompiled: [],\n };\n }\n\n // Mandatory-pattern lock-down.\n const disabled = new Set(opts.disabledPatterns ?? []);\n for (const key of disabled) {\n if (MANDATORY_PATTERNS.has(key)) {\n throw new Error(`redaction pattern '${key}' cannot be disabled (server-side mandatory)`);\n }\n }\n\n // Active set: every catalogue key NOT in default-off NOT in disabled.\n const active = new Set<string>();\n for (const key of PATTERN_ORDER) {\n if (DEFAULT_OFF_PATTERNS.has(key)) continue;\n if (disabled.has(key)) continue;\n active.add(key);\n }\n // Re-add any default-off pattern the user explicitly opted in to via a\n // `disabledPatterns` membership check is the wrong direction — the only\n // way to enable `ip_address` from the SDK today is through a future\n // `enabledPatterns` option. The spec keeps it default-off; tests pass\n // an explicit `enabledPatterns` set via the lower-level `redactString`.\n\n // Custom regex validation.\n const extraInput = opts.extraPatterns ?? [];\n if (extraInput.length > EXTRA_PATTERN_CAP) {\n throw new Error(\n `too many redaction extra patterns: ${extraInput.length} (max ${EXTRA_PATTERN_CAP})`,\n );\n }\n const extraCompiled: RegExp[] = [];\n for (const raw of extraInput) {\n if (typeof raw !== \"string\") {\n throw new Error(`redaction extra pattern must be a string, got ${typeof raw}`);\n }\n if (raw.length > EXTRA_PATTERN_CHAR_CAP) {\n throw new Error(`redaction extra pattern exceeds ${EXTRA_PATTERN_CHAR_CAP} chars`);\n }\n let compiled: RegExp;\n try {\n compiled = new RegExp(raw, \"g\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new Error(`redaction extra pattern failed to compile: ${JSON.stringify(raw)} — ${msg}`);\n }\n extraCompiled.push(compiled);\n }\n\n return {\n enabled: true,\n enabledPatterns: active,\n extraCompiled,\n };\n}\n\n/* ------------------------------------------------------------------------ */\n/* Luhn check */\n/* ------------------------------------------------------------------------ */\n\n/** Standard mod-10 Luhn check on the digits of `s` (ignores spaces/dashes). */\nfunction luhnValid(s: string): boolean {\n let sum = 0;\n let alt = false;\n let digits = 0;\n for (let i = s.length - 1; i >= 0; i--) {\n const ch = s.charCodeAt(i);\n if (ch < 48 || ch > 57) continue; // skip non-digits (spaces, dashes)\n let n = ch - 48;\n if (alt) {\n n *= 2;\n if (n > 9) n -= 9;\n }\n sum += n;\n alt = !alt;\n digits++;\n }\n if (digits < 13 || digits > 19) return false;\n return sum % 10 === 0;\n}\n\n/* ------------------------------------------------------------------------ */\n/* String redactor */\n/* ------------------------------------------------------------------------ */\n\n/**\n * Internal: compute the active enabled set when callers pass an explicit\n * `enabledPatterns` (parity-corpus tests do this) vs. defaults.\n */\nfunction resolveEnabled(\n config: RedactionConfig,\n override?: ReadonlySet<string>,\n): ReadonlySet<string> {\n if (override !== undefined) return override;\n return config.enabledPatterns;\n}\n\n/**\n * Core redactor: walk patterns in canonical order, replace matches.\n *\n * `enabledOverride` allows tests (and the parity corpus) to specify an\n * exact enabled set, bypassing the config's default-on/off decisions.\n *\n * Customers calling through the SDK never see the override path — they\n * always pass through `RedactionConfig.enabledPatterns`.\n */\nexport function redactString(\n s: string,\n config: RedactionConfig,\n enabledOverride?: ReadonlySet<string>,\n): string {\n if (!config.enabled && enabledOverride === undefined) {\n return s;\n }\n if (s.length === 0) return s;\n\n const enabled = resolveEnabled(config, enabledOverride);\n let out = s;\n\n for (const key of PATTERN_ORDER) {\n if (!enabled.has(key)) continue;\n const re = PATTERNS[key];\n if (re === undefined) continue;\n // Reset `lastIndex` defensively (shared global regex state).\n re.lastIndex = 0;\n const replacement = `[REDACTED:${SHORT_KEYS[key]}]`;\n if (key === \"credit_card\") {\n out = out.replace(re, (m) => (luhnValid(m) ? replacement : m));\n } else {\n out = out.replace(re, replacement);\n }\n }\n\n // Custom patterns last.\n for (const re of config.extraCompiled) {\n re.lastIndex = 0;\n out = out.replace(re, \"[REDACTED:custom]\");\n }\n\n return out;\n}\n\n/* ------------------------------------------------------------------------ */\n/* JSON walker */\n/* ------------------------------------------------------------------------ */\n\nconst MAX_DEPTH = 10;\n\n/**\n * Recursively redact string leaves inside an arbitrary JSON-like value.\n * Booleans, numbers, nulls, undefined are passed through untouched.\n * Recursion is bounded at `MAX_DEPTH` to defend against pathological\n * payloads — beyond that, sub-trees are returned as-is.\n *\n * Arrays return new arrays; plain objects return new shallow-cloned\n * objects; non-plain objects (Date, Map, etc.) are returned as-is so we\n * don't accidentally serialise customer-internal types.\n */\nexport function redactValue(value: unknown, config: RedactionConfig, depth = 0): unknown {\n if (!config.enabled) return value;\n if (value === null || value === undefined) return value;\n if (typeof value === \"string\") return redactString(value, config);\n if (typeof value === \"number\" || typeof value === \"boolean\") return value;\n if (depth >= MAX_DEPTH) return value;\n\n if (Array.isArray(value)) {\n return value.map((item) => redactValue(item, config, depth + 1));\n }\n\n // Only walk plain objects (prototype is Object.prototype or null).\n if (typeof value === \"object\") {\n const proto = Object.getPrototypeOf(value);\n if (proto === Object.prototype || proto === null) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = redactValue(v, config, depth + 1);\n }\n return out;\n }\n }\n\n return value;\n}\n","/**\n * SDK self-diagnostics — Morse-owned internal error reporting (MHQ-908).\n *\n * Mirrors the Python SDK's `_internal/diagnostics.py`. Replaces the Sentry\n * reporter: when the SDK absorbs an internal exception (per the non-invasive\n * guarantee in `_internal/errors.ts`), it reports to Morse's own\n * `/api/v1/diagnostics/sdk` rather than to a third party the customer may not\n * have installed.\n *\n * Two channels, both silent on a healthy install:\n *\n * - **errors** — one absorbed exception with a *Morse-scoped* stack. Frames\n * inside this package go in full; every run of frames outside it collapses\n * to a count. No local variables, at any verbosity level.\n * - **counters** (SDKDIAG-09) — aggregate `{reason, category, quantity}` for\n * telemetry we discarded, adopted from Sentry's client reports, which is\n * what that vendor chose to send *instead of* SDK stack traces.\n *\n * **Transport is deliberately its own** (founder decision, 2026-08-03, Option\n * B): a bounded buffer plus a timer, created on the FIRST report and never\n * before. Routing through the shared transport would have been a smaller diff,\n * but that queue is bounded and drops, so a diagnostic storm would evict the\n * customer's telemetry. Lazy creation matters more in JS than in Python: an\n * armed timer keeps the Node event loop alive, so a healthy process must not\n * arm one. The timer is `unref()`d where available for the same reason.\n *\n * **Nothing here is private from the host.** Everything transmitted is also\n * written to the console, rate-limited, whether or not transmission succeeds\n * and even when the customer has opted out entirely (SDKDIAG-10).\n *\n * **Never throws.** A failure anywhere is swallowed — never retried, never\n * reported about itself (SDKDIAG-06).\n */\n\nimport { getApiKey, getEndpoint, isDebug, isDisabled, isTelemetryDisabled } from \"./env\";\nimport { type RedactionConfig, SECRET_ASSIGNMENT_SOURCE, redactValue } from \"./redaction\";\n\n// Build-time define, same as transport.ts. Declared rather than imported so\n// this module stays a leaf — transport imports us for the drop counters, and a\n// cycle here would be resolved at module-init time on the error path.\ndeclare const __SDK_VERSION__: string | undefined;\nconst SDK_VERSION = typeof __SDK_VERSION__ === \"string\" ? __SDK_VERSION__ : \"0.0.0-dev\";\n\nexport const LEVEL_OFF = \"off\";\nexport const LEVEL_ERROR = \"error\";\nexport const LEVEL_DEBUG = \"debug\";\nconst VALID_LEVELS: ReadonlySet<string> = new Set([LEVEL_OFF, LEVEL_ERROR, LEVEL_DEBUG]);\n\n/**\n * Learned from the `X-Morse-Diagnostics` response header on traffic the SDK is\n * already sending. `error` until a header says otherwise — matching the server\n * model's default, so behaviour before the first response matches after.\n */\nlet level: string = LEVEL_ERROR;\n\nconst RATE_WINDOW_MS = 60_000;\nconst RATE_LIMIT_PER_WINDOW = 100;\n/** `debug` relaxes the send budget; it never relaxes what may be sent. */\nconst RATE_LIMIT_PER_WINDOW_DEBUG = 1000;\nconst rateBuckets: Map<string, number[]> = new Map();\n\n/**\n * Local emission is limited separately from transmission so our send budget is\n * never the host's visibility ceiling (SDKDIAG-10).\n */\nconst LOCAL_LOG_WINDOW_MS = 60_000;\nexport const LOCAL_LOG_LIMIT_PER_WINDOW = 10;\nconst localLogBuckets: Map<string, number[]> = new Map();\n\n// Payload caps — mirror apps/api/apps/diagnostics/schemas.py.\nexport const MAX_STACK_ENTRIES = 64;\nexport const MAX_MESSAGE_CHARS = 4096;\nexport const MAX_BATCH_EVENTS = 32;\nconst ALLOWED_EXTRA_KEYS: ReadonlySet<string> = new Set([\n \"adapter\",\n \"module\",\n \"function\",\n \"operation\",\n \"endpoint_host\",\n]);\n\nconst DIAGNOSTICS_PATH = \"/api/v1/diagnostics/sdk\";\nconst MAX_PENDING = 100;\nconst FLUSH_INTERVAL_MS = 5000;\nconst BREAKER_THRESHOLD = 3;\nconst BREAKER_COOLDOWN_MS = 300_000;\n\n// --- Delivery counters (SDKDIAG-09) ----------------------------------------\n\nexport const REASON_QUEUE_FULL = \"queue_full\";\n/** Retryable failure, attempts made and used up (3, per MHQ-1001). */\nexport const REASON_RETRY_EXHAUSTED = \"retry_exhausted\";\nexport const REASON_QUOTA_REJECTED = \"quota_rejected\";\n/** A genuine serialisation failure — JSON.stringify threw. */\nexport const REASON_ENCODE_FAILED = \"encode_failed\";\nexport const REASON_SHUTDOWN_DROP = \"shutdown_drop\";\n/** 401/403 — key revoked, expired, or missing a scope. */\nexport const REASON_AUTH_REJECTED = \"auth_rejected\";\n/** Other non-429 4xx — wrong URL, or a payload the server will never accept. */\nexport const REASON_ENDPOINT_REJECTED = \"endpoint_rejected\";\n/** A send failed and the batch was dropped without further attempts. */\nexport const REASON_SEND_FAILED = \"send_failed\";\n// No breaker-open reason: the customer-telemetry transport has no circuit\n// breaker, and the breaker that does exist — this module's own — may not\n// report on itself (SDKDIAG-06). A constant here would be unreachable by\n// construction. See SDKDIAG-09.\n\ninterface CounterEntry {\n reason: string;\n category: string;\n quantity: number;\n}\n\nconst counters: Map<string, CounterEntry> = new Map();\n\ninterface DiagnosticEvent {\n kind: \"error\" | \"counters\";\n fingerprint: string;\n error_type?: string;\n message?: string;\n stack?: Array<Record<string, unknown>>;\n counters?: CounterEntry[];\n sdk_language: string;\n sdk_version: string;\n runtime_version?: string;\n platform?: string;\n extra?: Record<string, string>;\n}\n\n/**\n * Active redaction config, PUSHED here by `tracing.setRedactionConfig`.\n *\n * Push rather than pull so this module imports nothing but `env` and\n * `redaction`. A static import of `tracing` would close a cycle\n * (transport → diagnostics → tracing → transport) that resolves at module-init\n * time, and the error path is the worst place to discover a half-initialised\n * module.\n */\nlet activeRedactionConfig: RedactionConfig | null = null;\n\nexport function setRedactionConfig(config: RedactionConfig | null): void {\n activeRedactionConfig = config;\n}\n\nlet pending: DiagnosticEvent[] = [];\nlet timer: ReturnType<typeof setInterval> | null = null;\nlet consecutiveFailures = 0;\nlet breakerOpenUntil = 0;\n/** Re-entrancy fence (SDKDIAG-06). */\nlet reporting = false;\n\nexport function setLevel(raw: string | null | undefined): void {\n if (!raw) return;\n const value = String(raw).trim().toLowerCase();\n // Unrecognised values are ignored rather than treated as `off` — a future\n // server value must not silently mute an old SDK.\n if (!VALID_LEVELS.has(value)) return;\n level = value;\n}\n\nexport function getLevel(): string {\n return level;\n}\n\n/**\n * True when this process may put diagnostics on the wire. The customer's kill\n * switch beats every server-side setting — that ordering is the whole point of\n * having a client-side switch.\n */\nexport function transmissionAllowed(): boolean {\n if (isTelemetryDisabled() || isDisabled()) return false;\n return level !== LEVEL_OFF;\n}\n\nfunction checkBucket(\n buckets: Map<string, number[]>,\n key: string,\n limit: number,\n windowMs: number,\n): boolean {\n const now = Date.now();\n const bucket = buckets.get(key) ?? [];\n const cutoff = now - windowMs;\n while (bucket.length > 0 && (bucket[0] as number) < cutoff) bucket.shift();\n if (bucket.length >= limit) {\n buckets.set(key, bucket);\n return false;\n }\n bucket.push(now);\n buckets.set(key, bucket);\n return true;\n}\n\nexport function checkRateLimit(fingerprint: string): boolean {\n const limit = level === LEVEL_DEBUG ? RATE_LIMIT_PER_WINDOW_DEBUG : RATE_LIMIT_PER_WINDOW;\n return checkBucket(rateBuckets, fingerprint, limit, RATE_WINDOW_MS);\n}\n\n// --- Morse-scoped stack (SDKDIAG-02) ---------------------------------------\n\n/**\n * Frames mentioning this package are ours; everything else is the host's.\n *\n * Matching on the module path is a heuristic (a bundled build flattens paths),\n * and it fails CLOSED: an unrecognised frame is treated as the host's and\n * elided. Over-eliding costs us a debugging detail; under-eliding would ship\n * the customer's file layout.\n *\n * **Both package names must be listed.** The in-repo `package.json` name is\n * `@morsehq/sdk` (the pnpm workspace identifier), but `release-typescript.yml`\n * rewrites it to `@morsehq-dev/sdk` — the real npm scope — immediately before\n * publish. So EVERY customer install lives at `@morsehq-dev/sdk/...` and the\n * in-repo name never appears in a production stack trace.\n *\n * Listing only the in-repo name is what shipped through 0.5.0-rc.4: no frame\n * in any published build was recognised as ours, so every stack collapsed to\n * `[{elided: n}]` and diagnostics could not say where the SDK broke. Verified\n * against the published rc4 artifact on 2026-08-07.\n *\n * Matched as exact scoped-package substrings rather than a bare `morsehq`, to\n * keep the fail-closed property: a customer directory that merely contains our\n * name must not cause their frames to be transmitted in full.\n */\nconst MORSE_PATH_MARKERS = [\"@morsehq/sdk\", \"@morsehq-dev/sdk\", \"morse-sdk\", \"/morse/\", \"morse_ai\"];\n\nfunction isMorseFrame(line: string): boolean {\n return MORSE_PATH_MARKERS.some((marker) => line.includes(marker));\n}\n\n/** Parse `at fn (file:line:col)` into its parts, best-effort. */\nfunction parseFrame(line: string): { file?: string; lineNo?: number; fn?: string } {\n const withParens = /^\\s*at\\s+(.+?)\\s+\\((.+?):(\\d+):(\\d+)\\)\\s*$/.exec(line);\n if (withParens) {\n return {\n fn: withParens[1],\n file: withParens[2],\n lineNo: Number(withParens[3]),\n };\n }\n const bare = /^\\s*at\\s+(.+?):(\\d+):(\\d+)\\s*$/.exec(line);\n if (bare) return { file: bare[1], lineNo: Number(bare[2]) };\n return {};\n}\n\nexport function buildScopedStack(error: unknown): Array<Record<string, unknown>> {\n const frames: Array<Record<string, unknown>> = [];\n try {\n const stack = error instanceof Error ? (error.stack ?? \"\") : \"\";\n if (!stack) return frames;\n let elided = 0;\n for (const raw of stack.split(\"\\n\")) {\n if (!raw.trim().startsWith(\"at \")) continue; // the message line\n if (isMorseFrame(raw)) {\n if (elided > 0) {\n frames.push({ elided });\n elided = 0;\n }\n const { file, lineNo, fn } = parseFrame(raw);\n const frame: Record<string, unknown> = {};\n // Keep only the tail of the path: an absolute path leaks the host's\n // directory layout (usernames, deploy paths).\n if (file) frame.file = file.split(/[\\\\/]/).slice(-3).join(\"/\");\n if (typeof lineNo === \"number\" && !Number.isNaN(lineNo)) frame.line = lineNo;\n if (fn) frame.function = fn.slice(0, 255);\n frames.push(frame);\n } else {\n elided += 1;\n }\n }\n if (elided > 0) frames.push({ elided });\n } catch {\n // A partial stack beats no diagnostic.\n }\n return frames.length > MAX_STACK_ENTRIES ? frames.slice(-MAX_STACK_ENTRIES) : frames;\n}\n\n/**\n * Exception message, redacted and capped.\n *\n * An exception message is not automatically safe — it can name a customer key\n * or echo content — so it goes through the same redaction the telemetry path\n * uses, and then through the secret-assignment pattern a second time,\n * unconditionally. A redactor fault returns a placeholder rather than the raw\n * string: failing closed is the only acceptable direction here.\n *\n * The second pass is the point (MHQ-973). `secret_assignment` is disableable,\n * because an org may legitimately want raw `password=` values in *their own*\n * spans. This channel is different: the published disclosure (SDKDIAG-02)\n * promises Morse receives no customer data, and that promise must not be\n * defeatable by someone's telemetry preference. Over-redacting our own error\n * text costs a little debuggability; under-redacting leaks a credential to us.\n */\nfunction redactedMessage(error: unknown): string {\n let raw: string;\n try {\n raw = error instanceof Error ? error.message : String(error);\n } catch {\n return \"\";\n }\n try {\n if (activeRedactionConfig) {\n const out = redactValue(raw, activeRedactionConfig);\n raw = typeof out === \"string\" ? out : String(out);\n }\n // Fresh RegExp per call: a `g`-flagged instance carries `lastIndex`.\n raw = raw.replace(new RegExp(SECRET_ASSIGNMENT_SOURCE, \"gi\"), \"[REDACTED:secret]\");\n } catch {\n return \"<redaction unavailable>\";\n }\n return raw.slice(0, MAX_MESSAGE_CHARS);\n}\n\nexport function scrubExtra(extra: Record<string, unknown> | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!extra) return out;\n for (const [key, value] of Object.entries(extra)) {\n if (ALLOWED_EXTRA_KEYS.has(key) && value != null) {\n out[key] = String(value).slice(0, 255);\n }\n }\n return out;\n}\n\n/**\n * Count telemetry we discarded. Never throws, never sends immediately.\n *\n * Delivery loss is what the customer's on-call most needs to know, so it is a\n * `console.warn` locally even though it is only a counter on the wire.\n */\nexport function recordDrop(reason: string, category: string, quantity = 1): void {\n try {\n if (quantity <= 0) return;\n const key = `${reason}:${category}`;\n const existing = counters.get(key);\n if (existing) existing.quantity += quantity;\n else counters.set(key, { reason, category, quantity });\n\n if (\n checkBucket(localLogBuckets, `drop:${key}`, LOCAL_LOG_LIMIT_PER_WINDOW, LOCAL_LOG_WINDOW_MS)\n ) {\n console.warn(`morse: dropped ${quantity} ${category} (${reason}) — telemetry is being lost`);\n }\n // MHQ-1030: arm the flush timer so the count goes out on the normal\n // cadence. Counters alone used to arm nothing, so a process that lost\n // telemetry but never threw reported it only at `shutdown()` — i.e. never,\n // for a long-lived server or one killed outright. The timer is `unref`'d,\n // so this still cannot hold the process open.\n if (transmissionAllowed()) ensureTimer();\n } catch {\n // Counter bookkeeping must never break a caller.\n }\n}\n\nexport function drainCounters(): CounterEntry[] {\n if (counters.size === 0) return [];\n const drained = [...counters.values()];\n counters.clear();\n return drained;\n}\n\nexport interface ReportOptions {\n fingerprint: string;\n extra?: Record<string, unknown>;\n}\n\n/**\n * Report an absorbed internal SDK error. Never throws.\n *\n * Signature is unchanged from the Sentry reporter it replaces, so every\n * `absorbErrors` call site keeps working untouched.\n */\nexport function report(error: unknown, options: ReportOptions): void {\n if (reporting) return; // SDKDIAG-06\n reporting = true;\n try {\n const errClass = error instanceof Error ? error.name : \"Error\";\n const errMessage = error instanceof Error ? error.message : String(error);\n\n // SDKDIAG-10: local FIRST, gated only by its own limiter. Transmission may\n // be off, blocked, or failing — the host still sees it.\n if (\n checkBucket(\n localLogBuckets,\n options.fingerprint,\n LOCAL_LOG_LIMIT_PER_WINDOW,\n LOCAL_LOG_WINDOW_MS,\n )\n ) {\n const line = `morse internal error [${options.fingerprint}]: ${errClass}: ${errMessage}`;\n if (isDebug()) console.error(line, error);\n else console.warn(line);\n }\n\n if (!transmissionAllowed()) return;\n if (!checkRateLimit(options.fingerprint)) return;\n\n enqueue({\n kind: \"error\",\n fingerprint: options.fingerprint.slice(0, 255),\n error_type: errClass.slice(0, 255),\n message: redactedMessage(error),\n stack: buildScopedStack(error),\n sdk_language: \"typescript\",\n sdk_version: sdkVersion(),\n runtime_version: runtimeVersion(),\n platform: platformLabel(),\n extra: scrubExtra(options.extra),\n });\n } catch {\n // Absolute last-resort: nothing here may propagate.\n } finally {\n reporting = false;\n }\n}\n\nfunction sdkVersion(): string {\n return SDK_VERSION;\n}\n\nfunction runtimeVersion(): string {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const proc = (globalThis as any).process;\n return proc?.version ? String(proc.version) : \"\";\n } catch {\n return \"\";\n }\n}\n\nfunction platformLabel(): string {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const proc = (globalThis as any).process;\n if (proc?.platform) return `${proc.platform}-${proc.arch ?? \"\"}`.slice(0, 128);\n return \"browser\";\n } catch {\n return \"\";\n }\n}\n\nfunction enqueue(event: DiagnosticEvent): void {\n // Oldest-first eviction: during an incident the newest diagnostics describe\n // what is happening now; a buffer of stale ones is worth less.\n pending.push(event);\n while (pending.length > MAX_PENDING) pending.shift();\n ensureTimer();\n}\n\n/**\n * Arm the flush timer on first use — never at import.\n *\n * Option B's lazy half, and it matters more here than in Python: an armed\n * `setInterval` keeps the Node event loop alive, so a healthy process that\n * armed one at import would refuse to exit. `unref()` where available means\n * even an armed timer never holds the process open.\n */\nfunction ensureTimer(): void {\n if (timer !== null) return;\n try {\n timer = setInterval(() => {\n void flushOnce();\n }, FLUSH_INTERVAL_MS);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (timer as any)?.unref?.();\n } catch {\n timer = null;\n }\n}\n\nfunction breakerBlocks(): boolean {\n return breakerOpenUntil > 0 && Date.now() < breakerOpenUntil;\n}\n\nfunction recordResult(ok: boolean): void {\n if (ok) {\n consecutiveFailures = 0;\n breakerOpenUntil = 0;\n return;\n }\n consecutiveFailures += 1;\n if (consecutiveFailures >= BREAKER_THRESHOLD) {\n // Open the breaker; when it lapses exactly one probe goes out (the counter\n // is not reset, so a failed probe re-opens it immediately).\n breakerOpenUntil = Date.now() + BREAKER_COOLDOWN_MS;\n }\n}\n\nexport async function flushOnce(): Promise<void> {\n try {\n const batch = pending.splice(0, MAX_BATCH_EVENTS);\n const drained = drainCounters();\n if (drained.length > 0) {\n batch.push({\n kind: \"counters\",\n fingerprint: \"morse.transport.delivery\",\n counters: drained,\n sdk_language: \"typescript\",\n sdk_version: sdkVersion(),\n });\n }\n // SDKDIAG-01/09: a healthy interval transmits nothing.\n if (batch.length === 0) return;\n if (breakerBlocks() || !transmissionAllowed()) return;\n\n const target = resolveTarget();\n if (target === null) return;\n\n let response: Response;\n try {\n response = await fetch(target.url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${target.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ events: batch }),\n });\n } catch {\n // Network fault. No retry — a retry loop here would amplify exactly the\n // situation we are reporting about (SDKDIAG-06).\n recordResult(false);\n return;\n }\n setLevel(response.headers.get(\"X-Morse-Diagnostics\"));\n recordResult(response.ok);\n } catch {\n // The flush loop must outlive any single batch.\n }\n}\n\n// MHQ-927: the live client's configuration, pushed in by `init()`.\n//\n// Python's `_resolve_target` reads `morse_ai._client` first and only falls\n// back to the environment. TS read the environment ONLY, so a consumer who\n// configured the SDK programmatically — `morse.init({ apiKey, endpoint })`,\n// the idiomatic and documented form — had no resolvable target and every\n// diagnostic was silently dropped. Traces still worked, because the transport\n// gets its config from `init()` directly.\n//\n// Pushed rather than pulled, mirroring `setDiagnosticsRedactionConfig`, to\n// keep diagnostics free of an import cycle back into `index.ts`.\nlet clientConfig: { apiKey?: string; endpoint?: string } | null = null;\n\nexport function setDiagnosticsClientConfig(\n config: { apiKey?: string; endpoint?: string } | null,\n): void {\n clientConfig = config;\n}\n\nfunction resolveTarget(): { apiKey: string; url: string } | null {\n try {\n const apiKey = clientConfig?.apiKey || getApiKey();\n if (!apiKey) return null; // No authenticated destination — local-log-only.\n const url = deriveDiagnosticsUrl(String(clientConfig?.endpoint || getEndpoint() || \"\"));\n if (!url) return null;\n return { apiKey: String(apiKey), url };\n } catch {\n return null;\n }\n}\n\nexport function deriveDiagnosticsUrl(tracesEndpoint: string): string | null {\n try {\n const parsed = new URL(tracesEndpoint);\n return `${parsed.protocol}//${parsed.host}${DIAGNOSTICS_PATH}`;\n } catch {\n return null;\n }\n}\n\n/**\n * Test-only reset hook.\n *\n * @internal\n */\nexport function _resetForTesting(): void {\n clientConfig = null;\n rateBuckets.clear();\n localLogBuckets.clear();\n counters.clear();\n pending = [];\n if (timer !== null) {\n clearInterval(timer);\n timer = null;\n }\n consecutiveFailures = 0;\n breakerOpenUntil = 0;\n reporting = false;\n level = LEVEL_ERROR;\n activeRedactionConfig = null;\n}\n\n/**\n * True when the flush timer is armed. Exported so tests can assert the\n * central Option B claim: a healthy process arms nothing.\n *\n * @internal\n */\nexport function _hasTimer(): boolean {\n return timer !== null;\n}\n","/**\n * Browser replacement for `otel-provider.ts` (MHQ-482 follow-up).\n *\n * Why this file exists\n * --------------------\n * `otel-provider.ts` is Node-only by construction — it statically imports\n * `@opentelemetry/sdk-trace-node`, `@opentelemetry/context-async-hooks`\n * (`async_hooks`), `@opentelemetry/instrumentation` (node `module`) and the\n * proto exporter's Node build. Because `index.ts` -> `tracing.ts` ->\n * `otel-provider.ts` is a static chain, ANY bundler targeting the browser\n * pulled those Node built-ins into the browser graph and failed to resolve\n * them. `tracing.ts`'s own docstring flagged this as a deferred decision\n * (\"a future browser-targeted build would need ... to keep the JSON path as\n * the browser default\"); this module is that decision, taken.\n *\n * The build swaps this module in for `otel-provider.ts` via the esbuild\n * plugin in `tsup.config.ts`, and `package.json`'s `\"browser\"` export\n * condition points browser bundlers at the resulting `dist/browser/*`. No\n * consumer configuration is involved — webpack, Turbopack, Vite, Rollup and\n * esbuild all honour the condition automatically.\n *\n * Behaviour, not a black hole\n * ---------------------------\n * Tracing still WORKS in the browser: `isOtelAvailable()` returns false, so\n * `tracing.ts::sendTrace` routes traces down the legacy JSON transport\n * (the same path `MORSE_LEGACY_TRANSPORT=1` selects in Node) instead of\n * dropping them. What is genuinely unavailable in a browser is the OTLP\n * span pipeline and DB-driver instrumentation; `noteBrowserRuntime()` says\n * so once, out loud, rather than leaving an integrator to wonder why their\n * spans look different from the Node docs.\n */\n\n/** Public surface mirrors `otel-provider.ts` exactly — see that module. */\nexport interface OtelEngineConfigureOptions {\n apiKey?: string | undefined;\n endpoint?: string | undefined;\n sampleRate?: number | undefined;\n maxFieldBytes?: number | undefined;\n redaction?: unknown;\n [key: string]: unknown;\n}\n\nexport interface TraceEntryLike {\n trace: Record<string, unknown>;\n spans: Record<string, unknown>[];\n}\n\nlet warned = false;\n\n/**\n * Emit the one-time \"you are on the browser build\" notice.\n *\n * Deliberately `console.info`, not `warn`: nothing is broken and nothing\n * needs fixing — a warning here would train integrators to ignore the\n * console. Fires only once per bundle, and only when the SDK is actually\n * configured (i.e. the app really did initialize Morse), so a page that\n * merely imports the SDK stays silent.\n */\nfunction noteBrowserRuntime(): void {\n if (warned) return;\n warned = true;\n try {\n console.info(\n \"[morse] Browser build active: OpenTelemetry span export and database \" +\n \"capture are Node-only, so traces are sent via Morse's JSON transport \" +\n \"instead. Everything else — run()/span()/track() and W3C traceparent \" +\n \"propagation — behaves identically. Server-side code (Next.js route \" +\n \"handlers, RSC, Node services) automatically gets the full OTel pipeline.\",\n );\n } catch {\n // A console-less runtime is not a reason to fail a customer's app.\n }\n}\n\n/**\n * Browser stand-in for `OtelEngine`. Every method is a safe no-op with the\n * same signature, so `index.ts` needs no `typeof window` branches.\n */\nexport class OtelEngine {\n // Params are declared (not dropped) so this class stays signature-compatible\n // with the real `OtelEngine` — the build swaps the modules, but anything\n // type-checking against this one must see the same shape. `void x` marks the\n // deliberate non-use for @typescript-eslint/no-unused-vars.\n configure(opts: OtelEngineConfigureOptions): void {\n void opts;\n noteBrowserRuntime();\n }\n\n shutdown(): void {}\n\n resetForTesting(): void {\n warned = false;\n }\n\n async flush(): Promise<void> {}\n\n resolveSampled(traceIdHex: string): boolean {\n void traceIdHex;\n // Sampling in the browser is decided by the JSON transport path, which\n // applies its own rate — claiming \"sampled\" here would double-apply it.\n return true;\n }\n\n registerInstrumentations(instrumentations: unknown[]): (() => void) | null {\n void instrumentations;\n // DB-driver instrumentation requires `require-in-the-middle`; there is\n // nothing to hook in a browser.\n return null;\n }\n}\n\nconst engine = new OtelEngine();\n\nexport function getEngine(): OtelEngine {\n return engine;\n}\n\n/**\n * False in the browser build — `tracing.ts::sendTrace` reads this to pick\n * the JSON transport instead of the (absent) OTLP pipeline.\n */\nexport function isOtelAvailable(): boolean {\n return false;\n}\n\n/**\n * Never called: `sendTrace` checks `isOtelAvailable()` first. Kept so the\n * module's shape matches `otel-provider.ts` (a shape mismatch would only\n * surface as a bundler error in a customer's build), and defensive — if it\n * ever IS reached, dropping the trace silently is the one outcome that must\n * not happen, so it reports rather than returning quietly.\n */\nexport function emitTraceEntry(entry: TraceEntryLike): void {\n void entry;\n noteBrowserRuntime();\n throw new Error(\"morse: OTLP export is unavailable in the browser build\");\n}\n\n/** No live OTel context to enter in a browser — run `fn` unchanged. */\nexport function withOtelSpanContext<T>(traceIdHex: string, spanIdHex: string, fn: () => T): T {\n void traceIdHex;\n void spanIdHex;\n return fn();\n}\n","/**\n * Span model — the wire format the SDK sends to Morse.\n *\n * Mirrors `apps/sdk/python/src/morse/spans.py` field-for-field. The\n * backend's `SpanType` choices are the source of truth.\n */\n\nexport const SpanType = {\n AGENT: \"agent\",\n LLM: \"llm\",\n TOOL: \"tool\",\n HTTP: \"http\",\n DB: \"db\",\n CUSTOM: \"custom\",\n MEMORY: \"memory\",\n // MHQ-482: matches Python's `SpanType.RETRIEVER` (apps/sdk/python/src/morse_ai/spans.py).\n // @beta — retriever span type is subject to change before SDK v1.0 (see\n // the plain-LangChain adapter's on_retriever_* callbacks in src/langchain/).\n RETRIEVER: \"retriever\",\n // MHQ-1025: matches Python's `SpanType.HANDOFF`. One span per routing\n // decision between two agents, with `from_agent` / `to_agent` metadata.\n HANDOFF: \"handoff\",\n} as const;\n\nexport type SpanType = (typeof SpanType)[keyof typeof SpanType];\n\nexport type SpanStatus = \"completed\" | \"failed\" | \"timed_out\";\n\n/**\n * Wire-format shape of one context segment carried on an LLM span.\n *\n * Mirrors the Python `morse.context.ContextSegmentDict` — keep both\n * sides in lockstep with the backend `ContextSegmentIn` Pydantic schema.\n *\n * - `tokens` is intentionally optional on the wire; the server tokenizes\n * when omitted to keep client-side cost and dependency surface small.\n * - `source` accepts either underscored DB enum values (`memory_vector`)\n * or the dotted public-API form (`memory.vector`); the server\n * `normalize_segment_source` helper translates dots → underscores.\n */\nexport interface ContextSegment {\n position: number;\n source: string;\n content_hash: string;\n content?: string;\n content_truncated?: boolean;\n tokens?: number;\n tokens_estimated?: boolean;\n cache_state?: \"cold\" | \"cache_write\" | \"cache_hit\";\n attrs?: Record<string, unknown>;\n producer_span_id?: string;\n}\n\nexport interface SpanData {\n trace_id: string;\n span_id: string;\n type: SpanType;\n name: string;\n parent_span_id?: string;\n started_at: string;\n ended_at?: string;\n duration_ms?: number;\n status: SpanStatus;\n // LLM-specific\n model?: string;\n input_tokens?: number;\n output_tokens?: number;\n cached_input_tokens?: number;\n cache_write_tokens?: number;\n total_tokens?: number;\n cost_usd?: number;\n // Payload\n input_data?: unknown;\n output_data?: unknown;\n error_message?: string;\n metadata?: Record<string, unknown>;\n /**\n * Pre-segmented context profile (Anthropic / LangGraph adapters populate this).\n * `undefined` → server runs its messages-array classifier.\n * `[]` → SDK explicitly says no segments (server skips classifier).\n * Populated → server skips classification and persists as-is.\n */\n context_segments?: ContextSegment[];\n}\n\nexport interface TraceFields {\n trace_id: string;\n /** Backend `TracePayloadIn.agent` — matches Python SDK + Pydantic schema. */\n agent: string;\n status: SpanStatus;\n started_at: string;\n ended_at?: string;\n duration_ms?: number;\n error_message?: string;\n success?: boolean;\n outcome?: string;\n}\n\nexport interface TraceEntry {\n trace: TraceFields;\n spans: SpanData[];\n}\n\n/** 32-char hex (128-bit). Compatible with W3C trace_id format. */\nexport function generateTraceId(): string {\n return randomHex(32);\n}\n\n/**\n * 32-char hex (UUID4-style, 128-bit). Matches the backend's UUID-typed\n * `span_id` column and the sibling Python SDK (`uuid.uuid4().hex`).\n *\n * When the SDK emits a W3C traceparent header (see `src/propagation.ts`),\n * the first 16 hex chars are sliced off to fit the W3C `span_id` slot —\n * that interop is handled at the header-formatting layer, not here.\n *\n * Was 16 hex chars historically (W3C span_id format) until Phase 13\n * Option A dogfood surfaced silent backend rejection: the dev ingest\n * `TracePayloadIn` schema requires UUID-shaped span_ids and was tossing\n * every TS-emitted span with `Invalid span_id format (expected UUID)`.\n */\nexport function generateSpanId(): string {\n return randomHex(32);\n}\n\nfunction randomHex(chars: number): string {\n const bytes = new Uint8Array(Math.ceil(chars / 2));\n // Use Web Crypto when available (Node 19+, all browsers).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cryptoObj = (globalThis as any).crypto as Crypto | undefined;\n if (cryptoObj?.getRandomValues) {\n cryptoObj.getRandomValues(bytes);\n } else {\n // Fallback: Math.random — non-cryptographic but acceptable for trace IDs.\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n let hex = \"\";\n for (const b of bytes) {\n hex += b.toString(16).padStart(2, \"0\");\n }\n return hex.slice(0, chars);\n}\n\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n\n/** Serialize a SpanData, dropping undefined fields, matching Python's to_dict(). */\nexport function spanToWire(span: SpanData): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(span)) {\n if (v !== undefined && v !== null) {\n out[k] = v;\n }\n }\n return out;\n}\n\nexport function buildTraceEntry(\n fields: TraceFields,\n spans: SpanData[],\n): { trace: TraceFields; spans: Record<string, unknown>[] } {\n return {\n trace: fields,\n spans: spans.map(spanToWire),\n };\n}\n","/**\n * SDK V2 tracing core — TraceState, run(), span() context-manager-likes.\n *\n * Mirrors `apps/sdk/python/src/morse/tracing.py`. Key differences:\n *\n * - Python uses `contextvars.ContextVar` for async/coroutine isolation.\n * In Node we use `node:async_hooks.AsyncLocalStorage` when available\n * (server-side, including Next.js API routes). On the browser there\n * is no equivalent; we fall back to a module-global slot. This is\n * acceptable because in the browser there is exactly one event loop\n * and one user — no parallel traces.\n *\n * - \"Context manager\" idioms in TS use callback-style: `run(name, fn)`\n * and `span(name, type, fn)` accept a function and invoke it with\n * the active state on the stack. We keep an explicit `start/end`\n * pair on the public surface for callers who can't use callbacks\n * (e.g., when the work spans an SSE stream).\n *\n * - MHQ-482: `run()`/`span()`/`runTraced()`'s emission path now goes\n * through `./otel-provider` (real OTel spans over OTLP, Node-only —\n * mirrors the Python SDK's MHQ-668 `otel_provider.py`). This is a\n * deliberate Node-only deviation from this module's own browser\n * fallback for `AsyncLocalStorage` above: `otel-provider.ts` statically\n * imports `@opentelemetry/sdk-trace-node`, which pulls in Node built-ins\n * (`node:crypto`, `node:http`/`https`) that don't exist in a browser\n * bundle. A future browser-targeted build would need either a\n * browser-flavored OTel exporter swapped in at this call site or to\n * keep `MORSE_LEGACY_TRANSPORT=1`'s JSON path as the browser default —\n * out of scope for this port (see the PR report's deviation notes).\n *\n * - MHQ-482 (db-capture follow-up): `runSync`/`runAsync`/`spanSync`/\n * `spanAsync` now ALSO wrap `fn()` in a live OTel context via\n * `otel-provider.ts::withOtelSpanContext` (Node only — a no-op\n * passthrough everywhere else, including the browser fallback path,\n * since that helper itself no-ops when the OTel engine isn't\n * configured). This is what lets community DB-driver instrumentation\n * (`./db-capture.ts`) — which reads OTel's *global*\n * `context.active()`, not this module's `TraceState` — see the right\n * trace id and nest under the right parent span id when a query runs\n * inside an active `morse.span()`/`morse.run()` block. It's a\n * deliberately separate mechanism from `emitTraceEntry`'s\n * synthetic-parent trick: that one runs once at trace-close time over\n * already-built `SpanData`; this one runs live, for spans this module\n * never sees (they're built entirely inside the instrumentation\n * package and exported directly to the same `NodeTracerProvider`).\n */\n\nimport { isLegacyTransport, isValidInternalSource } from \"./env\";\nimport { emitTraceEntry, isOtelAvailable, withOtelSpanContext } from \"./otel-provider\";\nimport { report, setRedactionConfig as setDiagnosticsRedactionConfig } from \"./diagnostics\";\nimport { buildRedactionConfig, type RedactionConfig, redactValue } from \"./redaction\";\nimport type { SpanData, SpanStatus, SpanType } from \"./spans\";\nimport { generateSpanId, generateTraceId, nowIso } from \"./spans\";\n\n/* ------------------------------------------------------------------------ */\n/* Internal state */\n/* ------------------------------------------------------------------------ */\n\nexport interface TraceState {\n traceId: string;\n agentName: string;\n spanStack: SpanData[];\n completedSpans: SpanData[];\n // Mutable outcome fields — set by `run()` callers via the returned handle.\n success?: boolean;\n outcome?: string;\n errorMessage?: string;\n // Multi-turn attribution (MHQ-748). threadId groups traces in the same\n // conversation; userId is the app-layer end-user identifier. Both\n // optional — mirrors Python's `_TraceState.thread_id`/`user_id`.\n threadId?: string;\n userId?: string;\n // Cost-attribution dimensions — set via `run({ userMetadata })` at\n // trace-creation time, or mutated mid-trace via `setContext()` (MHQ-751).\n // Keys/values are always strings at the SDK boundary — mirrors Python's\n // `_TraceState.user_metadata`.\n userMetadata?: Record<string, string>;\n // Per-trace override of the resource-level `morse_ai.source` tag. Wins\n // over the process-level `_source` when set — mirrors Python's\n // `_TraceState.source_override`.\n sourceOverride?: string;\n // MHQ-859: framework recorded by whichever adapter fired first inside\n // this trace (`_internal/active-framework.ts`). Lifted onto the trace\n // resource as `morse_ai.framework` — mirrors Python's\n // `_TraceState.framework`. Absence is the signal; never defaulted.\n framework?: string;\n}\n\ntype AlsLike<T> = {\n getStore(): T | undefined;\n run<R>(value: T, fn: () => R): R;\n};\n\nlet als: AlsLike<TraceState> | null = null;\nlet alsLoaded = false;\nlet browserState: TraceState | null = null;\n\nfunction tryLoadAls(): AlsLike<TraceState> | null {\n if (alsLoaded) return als;\n alsLoaded = true;\n // Skip in the browser.\n if (typeof process === \"undefined\" || !process.versions?.node) {\n als = null;\n return als;\n }\n // MHQ-924: two resolution paths, tried in order. `require` alone is NOT\n // enough — it does not exist in ESM, so every `.mjs` / `\"type\": \"module\"`\n // consumer silently fell through to the browser fallback below. That\n // fallback is a module-global, which survives synchronous code but is lost\n // across the first `await`, so EVERY child span was dropped with \"no active\n // trace\" while the root span still persisted. Node consumers were never\n // getting AsyncLocalStorage at all.\n //\n // Order matters: getBuiltinModule first, because it is the only one of the\n // two that works in both module systems.\n //\n // 1. `process.getBuiltinModule` — Node 22.3+, synchronous, and identical\n // in ESM and CJS. Not a bundler-visible specifier, so the browser\n // build still cannot try to resolve `node:async_hooks`.\n // 2. runtime-eval'd `require` — CJS, and older Node versions.\n //\n // A dynamic `import()` is not an option: this function is synchronous and\n // is called on the hot path by getActiveTraceState().\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const getBuiltin = (process as any)?.getBuiltinModule as ((m: string) => unknown) | undefined;\n if (typeof getBuiltin === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = getBuiltin(\"node:async_hooks\") as any;\n if (mod?.AsyncLocalStorage) {\n als = new mod.AsyncLocalStorage() as AlsLike<TraceState>;\n return als;\n }\n }\n } catch {\n // Fall through to the require path.\n }\n try {\n // Use a runtime-eval'd require so the browser bundler doesn't try\n // to resolve `node:async_hooks`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const dynamicRequire = Function(\"m\", \"return require(m)\") as any as (m: string) => unknown;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = dynamicRequire(\"node:async_hooks\") as any;\n if (mod?.AsyncLocalStorage) {\n als = new mod.AsyncLocalStorage() as AlsLike<TraceState>;\n return als;\n }\n } catch {\n // Fall through to browser fallback.\n }\n // Genuinely no ALS: browser, or a Node old enough to have neither path.\n // The module-global fallback below is correct there — a browser has no\n // concurrent async contexts to confuse it.\n als = null;\n return als;\n}\n\nexport function getActiveTraceState(): TraceState | null {\n const store = tryLoadAls();\n if (store) {\n return store.getStore() ?? null;\n }\n return browserState;\n}\n\nfunction setActiveTraceState(state: TraceState | null): () => void {\n // Returns a \"reset\" callback. Used only on the browser path. On Node,\n // `als.run()` handles the lifecycle.\n const previous = browserState;\n browserState = state;\n return () => {\n browserState = previous;\n };\n}\n\n/* ------------------------------------------------------------------------ */\n/* Transport injection */\n/* ------------------------------------------------------------------------ */\n\nexport interface TransportLike {\n track(event: { traces: unknown[] } | Record<string, unknown>): boolean;\n}\n\nlet transport: TransportLike | null = null;\n\nexport function setTransport(t: TransportLike | null): void {\n transport = t;\n}\n\nexport function getTransport(): TransportLike | null {\n return transport;\n}\n\n/* ------------------------------------------------------------------------ */\n/* Redaction config — module-level, replaceable on init() */\n/* ------------------------------------------------------------------------ */\n\n// Default-on with the canonical catalogue. Replaced when `init()` runs\n// with explicit redaction options. Customers calling SDK helpers before\n// `init()` still get the default redaction floor.\nlet redactionConfig: RedactionConfig = buildRedactionConfig();\n\nexport function setRedactionConfig(config: RedactionConfig): void {\n redactionConfig = config;\n // Keep the diagnostics reporter's view in sync so an exception MESSAGE gets\n // the same redaction as span content (SDKDIAG-02). Pushed rather than pulled\n // to keep diagnostics free of a cycle back into tracing.\n setDiagnosticsRedactionConfig(config);\n}\n\nexport function getRedactionConfig(): RedactionConfig {\n return redactionConfig;\n}\n\n/* ------------------------------------------------------------------------ */\n/* Resource-level \"source\" label (dogfood emitter discrimination) */\n/* ------------------------------------------------------------------------ */\n\n// Process-level source tag. Lifted into each outgoing trace's `resource`\n// dict so the backend can discriminate Morse's own dogfood emitters\n// from customer traces. Mirrors the Python SDK's module-level `_source`.\nlet _source: string | null = null;\n\nexport function setSource(value: string | null | undefined): void {\n _source = value && value.length > 0 ? value : null;\n}\n\nexport function getSource(): string | null {\n return _source;\n}\n\nlet lastTrace: { trace: unknown; spans: unknown[] } | null = null;\n\nexport function getLastTrace(): { trace: unknown; spans: unknown[] } | null {\n return lastTrace;\n}\n\n/* ------------------------------------------------------------------------ */\n/* Trace lifecycle helpers */\n/* ------------------------------------------------------------------------ */\n\nfunction nowMonotonic(): number {\n // performance.now() is available in Node >= 16 globally and in all browsers.\n if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n return performance.now();\n }\n return Date.now();\n}\n\nfunction elapsedMs(startMonotonic: number): number {\n return Math.max(0, Math.round(nowMonotonic() - startMonotonic));\n}\n\nfunction finalizeSpan(\n span: SpanData,\n startMono: number,\n status: SpanStatus = \"completed\",\n errorMessage?: string,\n): void {\n span.ended_at = nowIso();\n span.duration_ms = elapsedMs(startMono);\n span.status = status;\n if (errorMessage !== undefined) {\n span.error_message = errorMessage;\n }\n}\n\n/**\n * Field allowlist for span-level redaction. Identifiers, timestamps,\n * counts, and types pass through untouched; user-supplied strings and\n * JSON blobs route through `redactValue`.\n */\nconst SPAN_REDACTABLE_FIELDS: ReadonlySet<string> = new Set([\n \"name\",\n \"input_data\",\n \"output_data\",\n \"error_message\",\n \"metadata\",\n]);\n\nconst TRACE_REDACTABLE_FIELDS: ReadonlySet<string> = new Set([\"agent\", \"outcome\", \"error_message\"]);\n\nfunction redactSpanDict(\n raw: Record<string, unknown>,\n config: RedactionConfig,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n // MHQ-947: guarded PER FIELD. Span metadata is USER data, and reading or\n // redacting it runs arbitrary customer code — a getter, a `toString`. That\n // threw straight through `redactValue` -> `buildTraceDict` -> `endTrace` and\n // terminated the host process: instrumentation taking down the application\n // it observes, which is the one thing the non-invasive guarantee exists to\n // prevent. Confirmed reproducible on 0.5.0-rc.5.\n //\n // A bad field costs that field, not the trace. Losing one metadata key beats\n // losing the span, and losing the span beats crashing the customer.\n //\n // Note this no longer early-returns when redaction is disabled: the read\n // itself can throw, so the guard has to run either way.\n for (const k of Object.keys(raw)) {\n try {\n const v = raw[k];\n out[k] = config.enabled && SPAN_REDACTABLE_FIELDS.has(k) ? redactValue(v, config) : v;\n } catch (err) {\n report(err, { fingerprint: \"morse.tracing.span_field_unreadable\" });\n out[k] = \"<unserializable>\";\n }\n }\n return out;\n}\n\nfunction redactTraceDict(\n raw: Record<string, unknown>,\n config: RedactionConfig,\n): Record<string, unknown> {\n if (!config.enabled) return raw;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(raw)) {\n if (TRACE_REDACTABLE_FIELDS.has(k)) {\n out[k] = redactValue(v, config);\n } else {\n out[k] = v;\n }\n }\n return out;\n}\n\nfunction buildTraceDict(\n state: TraceState,\n rootSpan: SpanData,\n): {\n trace: Record<string, unknown>;\n spans: Record<string, unknown>[];\n} {\n const trace: Record<string, unknown> = {\n trace_id: state.traceId,\n // Wire-format field is `agent` (matches backend TracePayloadIn schema +\n // sibling Python SDK). Was `agent_name` historically — the mismatch\n // caused dev ingest to reject every TS-emitted trace with a 422\n // until Phase 13 Option A dogfood surfaced it.\n agent: state.agentName,\n status: rootSpan.status,\n started_at: rootSpan.started_at,\n };\n if (rootSpan.ended_at) trace.ended_at = rootSpan.ended_at;\n if (rootSpan.duration_ms !== undefined) trace.duration_ms = rootSpan.duration_ms;\n if (rootSpan.error_message) trace.error_message = rootSpan.error_message;\n if (state.success !== undefined) trace.success = state.success;\n if (state.outcome !== undefined) trace.outcome = state.outcome;\n // MHQ-748/MHQ-751: multi-turn + cost-attribution dimensions. Field names\n // (`thread_id`/`user_id`/`user_metadata`) match the backend's\n // `TracePayloadIn` schema exactly (apps/api/apps/traces/schemas.py) and\n // the sibling Python SDK's `_build_trace_dict` — do not camelCase these.\n if (state.threadId !== undefined) trace.thread_id = state.threadId;\n if (state.userId !== undefined) trace.user_id = state.userId;\n if (state.userMetadata && Object.keys(state.userMetadata).length > 0) {\n trace.user_metadata = state.userMetadata;\n }\n\n const allSpans = [rootSpan, ...state.completedSpans];\n const spans = allSpans.map((s) => {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(s)) {\n if (v !== undefined && v !== null) {\n out[k] = v;\n }\n }\n return out;\n });\n\n const config = redactionConfig;\n const out = {\n trace: redactTraceDict(trace, config),\n spans: spans.map((s) => redactSpanDict(s, config)),\n };\n // Per-trace `sourceOverride` wins over the process-level `_source` —\n // mirrors Python's `_build_trace_dict`'s `effective_source = state.source_override or _source`.\n const effectiveSource = state.sourceOverride || _source;\n // MHQ-859: `morse_ai.framework` rides the same resource envelope as\n // `morse_ai.source` — both are per-trace values a process-wide OTel\n // Resource cannot express, and `otel-provider.ts` already lifts both onto\n // the root span as `morse.source` / `morse.framework`. Python has stamped the\n // framework since AGE-240; TS never did, so every TS trace landed with\n // `framework` NULL.\n const resource: Record<string, unknown> = {};\n if (effectiveSource) {\n // Lift the source label onto the trace envelope so the backend can\n // route dogfood-emitter traces to the internal dashboards. Mirrors\n // Python's `resource[\"morse_ai.source\"]`.\n resource[\"morse_ai.source\"] = effectiveSource;\n }\n if (state.framework) {\n resource[\"morse_ai.framework\"] = state.framework;\n }\n if (Object.keys(resource).length > 0) {\n (out as Record<string, unknown>).resource = resource;\n }\n return out;\n}\n\n/**\n * `run()` / `span()` / `runTraced()`'s emission path: real OTel spans over\n * OTLP (MHQ-482, mirrors Python's `tracing.py::_finish_trace`, MHQ-668).\n * Always updates `lastTrace` (test/debug introspection — same bookkeeping\n * regardless of which pipeline actually ships the trace), then hands the\n * dict to `otel-provider.ts::emitTraceEntry()` — unless\n * `MORSE_LEGACY_TRANSPORT=1`, in which case it falls back to the old JSON\n * queue path instead (rollback escape hatch; never both, to avoid\n * double-ingesting the same trace).\n *\n * Exported (MHQ-746) so `index.ts::record()` can submit a synthetic\n * single-span trace through this same pipeline instead of the defunct\n * `runs`-shaped `state.transport.track()` path — mirrors the Python SDK's\n * `client.py::record()`, which builds a trace + span dict and calls this\n * module's `_send_trace()` directly rather than going through `track()`.\n */\nexport function sendTrace(entry: {\n trace: Record<string, unknown>;\n spans: Record<string, unknown>[];\n}): void {\n lastTrace = entry;\n\n // `!isOtelAvailable()` is the browser build (see `otel-provider.browser.ts`):\n // the OTLP pipeline is Node-only, so browser traces take the same JSON path\n // the legacy escape hatch uses rather than being dropped. Still never both.\n if (isLegacyTransport() || !isOtelAvailable()) {\n if (transport !== null) {\n try {\n transport.track({ traces: [entry] });\n } catch {\n // never propagate\n }\n }\n return;\n }\n\n try {\n emitTraceEntry(entry);\n } catch {\n // never propagate — mirrors the rest of the SDK's non-invasive guarantee\n }\n}\n\n/**\n * Run `fn` with the OTel-global active context set to a synthetic\n * `SpanContext` for `spanIdHex` under `traceId` (MHQ-482 db-capture\n * correlation — see the module docstring). No-op passthrough if the OTel\n * engine isn't configured (browser, uninitialized SDK, or\n * `otel-provider.ts` import failure) — never throws, mirrors the rest of\n * this module's non-invasive guarantee.\n */\nfunction withDbCaptureContext<T>(traceId: string, spanIdHex: string, fn: () => T): T {\n try {\n // OTel SpanId is 64-bit (16 hex chars); Morse's span_id is 128-bit\n // (32 hex chars) — same truncation convention `spans.ts::generateSpanId`\n // documents for W3C traceparent interop.\n return withOtelSpanContext(traceId, spanIdHex.slice(0, 16), fn);\n } catch {\n return fn();\n }\n}\n\n/* ------------------------------------------------------------------------ */\n/* Public-ish run() and span() — wrapped at the module surface */\n/* ------------------------------------------------------------------------ */\n\nexport interface RunOptions {\n agentName: string;\n /** W3C traceparent value to continue an upstream trace, when available. */\n incomingTraceparent?: string | null;\n /**\n * Application-layer conversation/thread identifier (MHQ-748). Groups all\n * traces from the same multi-turn session so the dashboard can show the\n * full conversation history for a thread. Mirrors Python's\n * `run(thread_id=...)`.\n */\n threadId?: string;\n /**\n * Application-layer end-user identifier (e.g. a user primary key or\n * email) (MHQ-748). Enables per-user filtering in the dashboard. Mirrors\n * Python's `run(user_id=...)`.\n */\n userId?: string;\n /**\n * Cost-attribution dimensions attached to this trace at creation time\n * (e.g. `customer_id`, `feature`, `env`, `team`) (MHQ-748). Values are\n * coerced to strings. Can also be set/merged mid-trace via\n * `setContext()` (MHQ-751). Mirrors Python's `run(user_metadata=...)`.\n */\n userMetadata?: Record<string, unknown>;\n /**\n * INTERNAL USE ONLY — per-trace override for the resource-level\n * `morse_ai.source` tag. Wins over the process-level source set at\n * `init({ source })`. Accepted values: `\"copilot\" | \"investigator\" |\n * \"refagent\" | \"ui-bot\"`; anything else is silently ignored and the\n * process-level source is used. Customer code should leave this unset.\n * Mirrors Python's `run(source=...)`.\n */\n source?: string;\n}\n\nexport interface RunHandle {\n setOutcome(success: boolean, outcome?: string): void;\n setError(message: string): void;\n /** Internal — set by `runSync`/`runAsync`. */\n _state: TraceState;\n}\n\nfunction buildRunHandle(state: TraceState): RunHandle {\n return {\n setOutcome(success, outcome) {\n state.success = success;\n if (outcome !== undefined) state.outcome = outcome;\n },\n setError(message) {\n state.errorMessage = message;\n state.success = false;\n },\n _state: state,\n };\n}\n\nfunction startTrace(opts: RunOptions): {\n state: TraceState;\n rootSpan: SpanData;\n startMono: number;\n} {\n let traceId: string | undefined;\n if (opts.incomingTraceparent) {\n // Lazy import to avoid a cycle.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { extractTraceparent } = require(\"../propagation\") as typeof import(\"../propagation\");\n const ctx = extractTraceparent(opts.incomingTraceparent);\n if (ctx) {\n traceId = ctx.traceId;\n }\n }\n if (!traceId) traceId = generateTraceId();\n\n const state: TraceState = {\n traceId,\n agentName: opts.agentName,\n spanStack: [],\n completedSpans: [],\n };\n if (opts.threadId !== undefined) state.threadId = opts.threadId;\n if (opts.userId !== undefined) state.userId = opts.userId;\n if (opts.userMetadata) {\n state.userMetadata = coerceDims(opts.userMetadata, \"morse.tracing.run.user_metadata\");\n }\n // Validate against the same whitelist as `init({ source })` — an invalid\n // value falls through to whatever the process has set (never throws).\n if (isValidInternalSource(opts.source)) {\n state.sourceOverride = opts.source;\n }\n const rootSpan: SpanData = {\n trace_id: traceId,\n span_id: generateSpanId(),\n type: \"agent\" as SpanType,\n name: opts.agentName,\n started_at: nowIso(),\n status: \"completed\",\n };\n state.spanStack.push(rootSpan);\n return { state, rootSpan, startMono: nowMonotonic() };\n}\n\nfunction endTrace(\n state: TraceState,\n rootSpan: SpanData,\n startMono: number,\n threwError: unknown,\n): void {\n state.spanStack.pop();\n if (threwError !== undefined) {\n const msg = state.errorMessage ?? errToString(threwError);\n finalizeSpan(rootSpan, startMono, \"failed\", msg);\n if (state.success === undefined) state.success = false;\n } else if (state.errorMessage !== undefined) {\n finalizeSpan(rootSpan, startMono, \"failed\", state.errorMessage);\n // setError() already set state.success = false.\n } else {\n finalizeSpan(rootSpan, startMono);\n if (state.success === undefined) state.success = true;\n }\n const dict = buildTraceDict(state, rootSpan);\n sendTrace(dict);\n}\n\nfunction errToString(e: unknown): string {\n if (e instanceof Error) return e.message;\n return String(e);\n}\n\n/* ------------------------------------------------------------------------ */\n/* Sync + async run() wrappers */\n/* ------------------------------------------------------------------------ */\n\n/** True for anything await-able, without assuming a real Promise. */\nfunction isThenable(v: unknown): v is PromiseLike<unknown> {\n return (\n v !== null &&\n (typeof v === \"object\" || typeof v === \"function\") &&\n typeof (v as { then?: unknown }).then === \"function\"\n );\n}\n\nexport function runSync<T>(opts: RunOptions, fn: (handle: RunHandle) => T): T | undefined {\n const { state, rootSpan, startMono } = startTrace(opts);\n const handle = buildRunHandle(state);\n const store = tryLoadAls();\n\n const runFn = (): T => withDbCaptureContext(state.traceId, rootSpan.span_id, () => fn(handle));\n\n // MHQ-924 (defect B): if `fn` is async, closing the trace here would send it\n // before the body has run, so `state.completedSpans` is still empty and\n // EVERY child span is lost. The root span still lands, so the trace looks\n // healthy — it is just silently truncated. `run()` accepts an async callback\n // (its signature cannot refuse one), so \"use runTraced() instead\" was a\n // documented footgun rather than a safeguard: three adapters and the pino\n // integration each landed exactly one span in live testing because of it.\n //\n // Settling first keeps the sync path byte-identical — a non-thenable result\n // still ends the trace inline — while making the async path correct.\n const settle = (result: T, onDone: () => void): T => {\n if (!isThenable(result)) {\n endTrace(state, rootSpan, startMono, undefined);\n onDone();\n return result;\n }\n return (result as PromiseLike<unknown>).then(\n (value) => {\n endTrace(state, rootSpan, startMono, undefined);\n onDone();\n return value;\n },\n (err) => {\n endTrace(state, rootSpan, startMono, err);\n onDone();\n throw err;\n },\n ) as unknown as T;\n };\n\n if (store) {\n try {\n return settle(store.run(state, runFn), () => {});\n } catch (err) {\n endTrace(state, rootSpan, startMono, err);\n throw err;\n }\n } else {\n // Browser fallback: the reset must not fire until an async body has\n // settled, or the module-global is cleared out from under it.\n const reset = setActiveTraceState(state);\n try {\n return settle(runFn(), reset);\n } catch (err) {\n endTrace(state, rootSpan, startMono, err);\n reset();\n throw err;\n }\n }\n}\n\nexport async function runAsync<T>(\n opts: RunOptions,\n fn: (handle: RunHandle) => Promise<T>,\n): Promise<T | undefined> {\n const { state, rootSpan, startMono } = startTrace(opts);\n const handle = buildRunHandle(state);\n const store = tryLoadAls();\n\n const runFn = (): Promise<T> =>\n withDbCaptureContext(state.traceId, rootSpan.span_id, () => fn(handle));\n\n if (store) {\n try {\n const result = await store.run(state, runFn);\n endTrace(state, rootSpan, startMono, undefined);\n return result;\n } catch (err) {\n endTrace(state, rootSpan, startMono, err);\n throw err;\n }\n } else {\n const reset = setActiveTraceState(state);\n try {\n const result = await runFn();\n endTrace(state, rootSpan, startMono, undefined);\n return result;\n } catch (err) {\n endTrace(state, rootSpan, startMono, err);\n throw err;\n } finally {\n reset();\n }\n }\n}\n\n/**\n * Attach cost-attribution dimensions to the active trace (MHQ-751).\n *\n * Call once per request (e.g. in Express/Next.js middleware) to propagate\n * `customer_id`, `feature`, `env`, `team`, etc. to all child spans\n * automatically. Mirrors Python's `morse_ai.set_context(**dims)`.\n *\n * morse.setContext({ customerId: request.customerId, feature: \"doc-qa\" });\n *\n * Values are coerced to strings via `String(v)` — mirrors Python's `str()`\n * coercion. Merges into any dimensions already set (e.g. via\n * `run({ userMetadata })`) rather than replacing them. No-op outside an\n * active trace — never throws.\n */\nexport function setContext(dims: Record<string, unknown>): void {\n const state = getActiveTraceState();\n if (state === null) return;\n if (state.userMetadata === undefined) state.userMetadata = {};\n Object.assign(state.userMetadata, coerceDims(dims, \"morse.tracing.set_context\"));\n}\n\n/**\n * Set `threadId` on the active trace when nothing has claimed it yet.\n *\n * MHQ-1029 (the TypeScript half of MHQ-1022): no adapter populated `threadId`,\n * so every auto-opened trace landed with `thread_id: null` and a five-turn\n * conversation showed up as five unrelated traces. Each framework keeps\n * conversation identity somewhere different — an openai-agents `session` /\n * run context, a LangGraph `configurable.thread_id`, the Agent SDK's session id\n * — so extraction stays per-adapter and this is the one place that writes it,\n * which is where precedence gets decided once.\n *\n * An explicit `run({ threadId })` from app code always wins; adapters only fill\n * the gap. Never throws: `String()` runs customer `toString`/`valueOf` code.\n */\nexport function adoptThreadId(value: unknown): void {\n const state = getActiveTraceState();\n if (state === null || state.threadId !== undefined || value === null || value === undefined) {\n return;\n }\n try {\n const s = String(value);\n if (s !== \"\") state.threadId = s;\n } catch (err) {\n report(err, { fingerprint: \"morse.tracing.adopt_thread_id\" });\n }\n}\n\n/**\n * `String()` every value, dropping any that throws. Never throws. (MHQ-947)\n *\n * Cost-attribution dimensions are USER values, and the SDK is the one choosing\n * to stringify them — so a bare `String(v)` runs arbitrary customer code\n * (`toString`, `valueOf`) on the telemetry path. An exception there propagated\n * into the caller: `setContext()` threw into host code, and\n * `run({ userMetadata })` threw at trace START, taking the whole callback with\n * it. Both confirmed reproducible on 0.5.0-rc.5.\n *\n * The trigger is not exotic — an ORM object whose `toString` lazily hits a\n * dead connection is a realistic, non-malicious source.\n *\n * Guarded PER KEY rather than per call: wrapping the entry point would discard\n * every dimension because one was bad, and losing a customer's `customerId`\n * because their `feature` object misbehaved is the worse answer. Mirrors the\n * Python SDK's `coerce_dims`.\n */\nexport function coerceDims(\n dims: Record<string, unknown>,\n fingerprint: string,\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const k of Object.keys(dims)) {\n try {\n out[k] = String(dims[k]);\n } catch (err) {\n report(err, { fingerprint });\n }\n }\n return out;\n}\n\n/* ------------------------------------------------------------------------ */\n/* span() child-span helpers */\n/* ------------------------------------------------------------------------ */\n\nexport interface SpanOptions {\n name: string;\n type?: SpanType;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SpanHandle {\n /** Mutate the underlying span data (e.g., set tokens / cost). */\n span: SpanData;\n end(error?: unknown): void;\n}\n\n// MHQ-806. Latches the \"no active trace\" warning to once per process — see\n// startSpan for why it warns at all, and why not on every call.\nlet spanOutsideTraceWarningEmitted = false;\n\n/** Test hook — clears the once-per-process latch. */\nexport function _resetSpanOutsideTraceWarning(): void {\n spanOutsideTraceWarningEmitted = false;\n}\n\n/** Start a child span under the active trace, returning a handle to close it. */\nexport function startSpan(opts: SpanOptions): SpanHandle | null {\n const state = getActiveTraceState();\n if (state === null) {\n // No active trace — returns null rather than throwing, because library\n // code may be instrumented but reached from an untraced path.\n //\n // The null is visible in the type here, unlike Python's context-manager\n // form, but callers routinely ignore it (`span({...}, () => { ... })`\n // never touches the handle), so the outcome is the same: no error, no\n // spans, nothing distinguishing it from working instrumentation.\n //\n // Warned once per process, matching the existing not-initialized warning\n // in index.ts — this sits inside request and agent loops, so per-call\n // logging would bury the signal. This is the single choke point for\n // startSpan / spanSync / spanAsync.\n if (!spanOutsideTraceWarningEmitted) {\n spanOutsideTraceWarningEmitted = true;\n console.warn(\n `morse: span(${JSON.stringify(opts.name)}) was called with no active trace, so nothing ` +\n `was recorded. Wrap the work in morse.run('<agent-name>', () => { ... }) — run() opens ` +\n `the trace that span() attaches to. This warning prints once per process.`,\n );\n }\n return null;\n }\n const parent = state.spanStack[state.spanStack.length - 1];\n const span: SpanData = {\n trace_id: state.traceId,\n span_id: generateSpanId(),\n type: opts.type ?? \"custom\",\n name: opts.name,\n parent_span_id: parent?.span_id,\n started_at: nowIso(),\n status: \"completed\",\n metadata: opts.metadata,\n };\n const startMono = nowMonotonic();\n state.spanStack.push(span);\n return {\n span,\n end(error?: unknown): void {\n // Pop only if still on top — defensive against out-of-order ends.\n if (state.spanStack[state.spanStack.length - 1] === span) {\n state.spanStack.pop();\n }\n if (error !== undefined) {\n finalizeSpan(span, startMono, \"failed\", errToString(error));\n } else {\n finalizeSpan(span, startMono);\n }\n state.completedSpans.push(span);\n },\n };\n}\n\n/** Sync callback wrapper for `startSpan` / `end`. No-op if no active trace. */\nexport function spanSync<T>(opts: SpanOptions, fn: (handle: SpanHandle | null) => T): T {\n const handle = startSpan(opts);\n try {\n const result = handle\n ? withDbCaptureContext(handle.span.trace_id, handle.span.span_id, () => fn(handle))\n : fn(handle);\n handle?.end();\n return result;\n } catch (err) {\n handle?.end(err);\n throw err;\n }\n}\n\n/** Async callback wrapper for `startSpan` / `end`. No-op if no active trace. */\nexport async function spanAsync<T>(\n opts: SpanOptions,\n fn: (handle: SpanHandle | null) => Promise<T>,\n): Promise<T> {\n const handle = startSpan(opts);\n try {\n const result = handle\n ? await withDbCaptureContext(handle.span.trace_id, handle.span.span_id, () => fn(handle))\n : await fn(handle);\n handle?.end();\n return result;\n } catch (err) {\n handle?.end(err);\n throw err;\n }\n}\n\n/* ------------------------------------------------------------------------ */\n/* Test helpers */\n/* ------------------------------------------------------------------------ */\n\nexport function _resetForTesting(): void {\n browserState = null;\n lastTrace = null;\n redactionConfig = buildRedactionConfig();\n // We do not reset `als` because re-loading it is expensive and the\n // store is process-scoped anyway.\n}\n","/**\n * W3C Trace Context propagation — inject and extract `traceparent` headers.\n *\n * W3C traceparent format: `{version}-{trace_id}-{span_id}-{flags}`\n * - version : \"00\" (fixed)\n * - trace_id : 32 lowercase hex chars (128-bit)\n * - span_id : 16 lowercase hex chars (64-bit)\n * - flags : \"01\" (sampled, always set for Morse)\n *\n * Example: `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01`\n *\n * References:\n * https://www.w3.org/TR/trace-context/\n */\n\nimport { getActiveTraceState } from \"./_internal/tracing\";\n\nexport const W3C_TRACEPARENT_HEADER = \"traceparent\";\nexport const W3C_VERSION = \"00\";\nexport const W3C_FLAGS_SAMPLED = \"01\";\n\nconst TRACE_ID_LEN = 32;\nconst SPAN_ID_LEN = 16;\n\n/**\n * Build a W3C traceparent value from explicit IDs.\n *\n * Useful when you have a trace_id / span_id from somewhere other than\n * the active context (e.g., re-emitting an upstream trace's IDs).\n */\nexport function formatTraceparent(traceId: string, spanId: string): string {\n // We trust the caller; the \"build then validate\" assumption is documented.\n const tid = traceId.slice(0, TRACE_ID_LEN).padStart(TRACE_ID_LEN, \"0\").toLowerCase();\n const sid = spanId.slice(0, SPAN_ID_LEN).padStart(SPAN_ID_LEN, \"0\").toLowerCase();\n return `${W3C_VERSION}-${tid}-${sid}-${W3C_FLAGS_SAMPLED}`;\n}\n\n/**\n * Inject the W3C `traceparent` header derived from the active trace\n * context into the supplied headers object. Mutates and returns the\n * object for convenience.\n *\n * No-op (returns headers unchanged) if no trace is active.\n *\n * Accepts both `Headers` (from fetch) and a plain dict.\n */\nexport function injectTraceparent<T extends HeadersLike>(headers: T): T {\n const state = getActiveTraceState();\n if (state === null) return headers;\n\n const traceId = state.traceId;\n const span =\n state.spanStack.length > 0\n ? state.spanStack[state.spanStack.length - 1]\n : state.completedSpans[state.completedSpans.length - 1];\n const rawSpanId = span?.span_id ?? traceId;\n const spanId = rawSpanId.slice(0, SPAN_ID_LEN);\n\n const value = formatTraceparent(traceId, spanId);\n setHeader(headers, W3C_TRACEPARENT_HEADER, value);\n return headers;\n}\n\nexport interface ExtractedContext {\n traceId: string;\n parentSpanId: string;\n}\n\n/**\n * Parse a W3C traceparent header and return `{ traceId, parentSpanId }`,\n * or `null` if the header is missing or malformed.\n *\n * Validation per W3C §3.2.3:\n * - exactly 4 dash-separated fields\n * - version === \"00\"\n * - trace_id is 32 lowercase hex chars (and not all-zero)\n * - span_id is 16 lowercase hex chars (and not all-zero)\n */\nexport function extractTraceparent(\n headers: HeadersLike | string | null | undefined,\n): ExtractedContext | null {\n if (headers === null || headers === undefined) return null;\n const raw = typeof headers === \"string\" ? headers : getHeader(headers, W3C_TRACEPARENT_HEADER);\n if (!raw) return null;\n const parts = raw.split(\"-\");\n if (parts.length !== 4) return null;\n const [version, traceId, spanId] = parts as [string, string, string, string];\n if (version !== W3C_VERSION) return null;\n if (traceId.length !== TRACE_ID_LEN) return null;\n if (spanId.length !== SPAN_ID_LEN) return null;\n if (!/^[0-9a-f]+$/.test(traceId)) return null;\n if (!/^[0-9a-f]+$/.test(spanId)) return null;\n if (/^0+$/.test(traceId)) return null;\n if (/^0+$/.test(spanId)) return null;\n return { traceId, parentSpanId: spanId };\n}\n\n/**\n * Convenience for Next.js API routes / generic HTTP servers: pull the\n * traceparent off an incoming Request (or a header bag).\n */\nexport function extractFromRequest(req: { headers: HeadersLike }): ExtractedContext | null {\n return extractTraceparent(req.headers);\n}\n\n/**\n * Convenience for outbound `fetch`: build a fresh `Headers` object with\n * the traceparent injected, layered on top of the caller's input.\n */\nexport function injectIntoRequestInit(init?: RequestInit): RequestInit {\n const merged = new Headers(init?.headers ?? {});\n injectTraceparent(merged);\n return { ...(init ?? {}), headers: merged };\n}\n\n/* ------------------------------------------------------------------------ */\n/* Header polymorphism helpers */\n/* ------------------------------------------------------------------------ */\n\nexport type HeadersLike =\n | Headers\n | Record<string, string | string[] | undefined>\n | { get(name: string): string | null }\n | { [key: string]: unknown };\n\nfunction getHeader(headers: HeadersLike, name: string): string | null {\n if (headers instanceof Headers) {\n return headers.get(name);\n }\n // Object that exposes get() — e.g., Node's IncomingMessage doesn't, but\n // Next.js's headers() does.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeGet = (headers as any).get;\n if (typeof maybeGet === \"function\") {\n const v = maybeGet.call(headers, name);\n if (typeof v === \"string\") return v;\n if (v === null || v === undefined) return null;\n }\n // Plain dict: case-insensitive lookup.\n const lower = name.toLowerCase();\n for (const [k, v] of Object.entries(headers as Record<string, unknown>)) {\n if (k.toLowerCase() === lower) {\n if (typeof v === \"string\") return v;\n if (Array.isArray(v) && v.length > 0 && typeof v[0] === \"string\") return v[0] as string;\n return null;\n }\n }\n return null;\n}\n\nfunction setHeader(headers: HeadersLike, name: string, value: string): void {\n if (headers instanceof Headers) {\n headers.set(name, value);\n return;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeSet = (headers as any).set;\n if (typeof maybeSet === \"function\") {\n maybeSet.call(headers, name, value);\n return;\n }\n (headers as Record<string, string>)[name] = value;\n}\n"]}
|