@agentwares/agentguard 0.1.7 → 0.1.9
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/CHANGELOG.md +75 -0
- package/README.md +223 -16
- package/dist/audit-2YCMHMCP.js +17 -0
- package/dist/audit-2YCMHMCP.js.map +1 -0
- package/dist/chunk-3O6KWT3E.js +345 -0
- package/dist/chunk-3O6KWT3E.js.map +1 -0
- package/dist/chunk-5WRI5ZAA.js +31 -0
- package/dist/chunk-5WRI5ZAA.js.map +1 -0
- package/dist/chunk-6S7LYVOC.js +1033 -0
- package/dist/chunk-6S7LYVOC.js.map +1 -0
- package/dist/chunk-6TUQD666.js +828 -0
- package/dist/chunk-6TUQD666.js.map +1 -0
- package/dist/chunk-BKXXTWIS.js +119 -0
- package/dist/chunk-BKXXTWIS.js.map +1 -0
- package/dist/chunk-D66U3PVB.js +529 -0
- package/dist/chunk-D66U3PVB.js.map +1 -0
- package/dist/chunk-HPYZ3JDX.js +206 -0
- package/dist/chunk-HPYZ3JDX.js.map +1 -0
- package/dist/chunk-KRKZGAJ3.js +769 -0
- package/dist/chunk-KRKZGAJ3.js.map +1 -0
- package/dist/chunk-SUXQTT3X.js +1268 -0
- package/dist/chunk-SUXQTT3X.js.map +1 -0
- package/dist/chunk-TW5KJREH.js +190 -0
- package/dist/chunk-TW5KJREH.js.map +1 -0
- package/dist/chunk-VQWQ5TOM.js +113 -0
- package/dist/chunk-VQWQ5TOM.js.map +1 -0
- package/dist/chunk-X4M7YWQA.js +270 -0
- package/dist/chunk-X4M7YWQA.js.map +1 -0
- package/dist/chunk-ZSLWPKXI.js +1144 -0
- package/dist/chunk-ZSLWPKXI.js.map +1 -0
- package/dist/cli.js +8 -4775
- package/dist/cli.js.map +1 -1
- package/dist/fixtures/crm-server.js +6 -1272
- package/dist/fixtures/crm-server.js.map +1 -1
- package/dist/fixtures/demo-agent.js +4 -115
- package/dist/fixtures/demo-agent.js.map +1 -1
- package/dist/index.d.ts +69 -10
- package/dist/index.js +245 -5138
- package/dist/index.js.map +1 -1
- package/dist/init-CWROGV5I.js +15 -0
- package/dist/init-CWROGV5I.js.map +1 -0
- package/dist/proxy-3Z5YEZ4R.js +154 -0
- package/dist/proxy-3Z5YEZ4R.js.map +1 -0
- package/dist/tools-3LLDG3XQ.js +15 -0
- package/dist/tools-3LLDG3XQ.js.map +1 -0
- package/llms.txt +4 -0
- package/package.json +9 -3
- package/server.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.pnpm/standardwebhooks@1.0.0/node_modules/standardwebhooks/src/timing_safe_equal.ts","../../../node_modules/.pnpm/@stablelib+base64@1.0.1/node_modules/@stablelib/base64/base64.ts","../../../node_modules/.pnpm/fast-sha256@1.3.0/node_modules/fast-sha256/sha256.js","../../../node_modules/.pnpm/standardwebhooks@1.0.0/node_modules/standardwebhooks/src/index.ts","../src/args.ts","../src/version.ts","../src/registration.ts","../../../node_modules/.pnpm/postal-mime@2.7.5/node_modules/postal-mime/src/decode-strings.js","../../../node_modules/.pnpm/postal-mime@2.7.5/node_modules/postal-mime/src/mime-node.js","../../../node_modules/.pnpm/postal-mime@2.7.5/node_modules/postal-mime/src/postal-mime.js","../../../node_modules/.pnpm/resend@6.25.0/node_modules/resend/dist/index.mjs","../../../packages/notify/src/html.ts","../../../packages/notify/src/templates/alert.ts","../../../packages/notify/src/templates/recovered.ts","../../../packages/notify/src/templates/digest.ts","../../../packages/notify/src/templates/drift.ts","../../../packages/notify/src/templates/receipt.ts","../../../packages/notify/src/channels.ts","../../../packages/notify/src/notify.ts","../src/notify.ts","../src/context.ts"],"sourcesContent":[null,"// Copyright (C) 2016 Dmitry Chestnykh\n// MIT License. See LICENSE file for details.\n\n/**\n * Package base64 implements Base64 encoding and decoding.\n */\n\n// Invalid character used in decoding to indicate\n// that the character to decode is out of range of\n// alphabet and cannot be decoded.\nconst INVALID_BYTE = 256;\n\n/**\n * Implements standard Base64 encoding.\n *\n * Operates in constant time.\n */\nexport class Coder {\n // TODO(dchest): methods to encode chunk-by-chunk.\n\n constructor(private _paddingCharacter = \"=\") { }\n\n encodedLength(length: number): number {\n if (!this._paddingCharacter) {\n return (length * 8 + 5) / 6 | 0;\n }\n return (length + 2) / 3 * 4 | 0;\n }\n\n encode(data: Uint8Array): string {\n let out = \"\";\n\n let i = 0;\n for (; i < data.length - 2; i += 3) {\n let c = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);\n out += this._encodeByte((c >>> 3 * 6) & 63);\n out += this._encodeByte((c >>> 2 * 6) & 63);\n out += this._encodeByte((c >>> 1 * 6) & 63);\n out += this._encodeByte((c >>> 0 * 6) & 63);\n }\n\n const left = data.length - i;\n if (left > 0) {\n let c = (data[i] << 16) | (left === 2 ? data[i + 1] << 8 : 0);\n out += this._encodeByte((c >>> 3 * 6) & 63);\n out += this._encodeByte((c >>> 2 * 6) & 63);\n if (left === 2) {\n out += this._encodeByte((c >>> 1 * 6) & 63);\n } else {\n out += this._paddingCharacter || \"\";\n }\n out += this._paddingCharacter || \"\";\n }\n\n return out;\n }\n\n maxDecodedLength(length: number): number {\n if (!this._paddingCharacter) {\n return (length * 6 + 7) / 8 | 0;\n }\n return length / 4 * 3 | 0;\n }\n\n decodedLength(s: string): number {\n return this.maxDecodedLength(s.length - this._getPaddingLength(s));\n }\n\n decode(s: string): Uint8Array {\n if (s.length === 0) {\n return new Uint8Array(0);\n }\n const paddingLength = this._getPaddingLength(s);\n const length = s.length - paddingLength;\n const out = new Uint8Array(this.maxDecodedLength(length));\n let op = 0;\n let i = 0;\n let haveBad = 0;\n let v0 = 0, v1 = 0, v2 = 0, v3 = 0;\n for (; i < length - 4; i += 4) {\n v0 = this._decodeChar(s.charCodeAt(i + 0));\n v1 = this._decodeChar(s.charCodeAt(i + 1));\n v2 = this._decodeChar(s.charCodeAt(i + 2));\n v3 = this._decodeChar(s.charCodeAt(i + 3));\n out[op++] = (v0 << 2) | (v1 >>> 4);\n out[op++] = (v1 << 4) | (v2 >>> 2);\n out[op++] = (v2 << 6) | v3;\n haveBad |= v0 & INVALID_BYTE;\n haveBad |= v1 & INVALID_BYTE;\n haveBad |= v2 & INVALID_BYTE;\n haveBad |= v3 & INVALID_BYTE;\n }\n if (i < length - 1) {\n v0 = this._decodeChar(s.charCodeAt(i));\n v1 = this._decodeChar(s.charCodeAt(i + 1));\n out[op++] = (v0 << 2) | (v1 >>> 4);\n haveBad |= v0 & INVALID_BYTE;\n haveBad |= v1 & INVALID_BYTE;\n }\n if (i < length - 2) {\n v2 = this._decodeChar(s.charCodeAt(i + 2));\n out[op++] = (v1 << 4) | (v2 >>> 2);\n haveBad |= v2 & INVALID_BYTE;\n }\n if (i < length - 3) {\n v3 = this._decodeChar(s.charCodeAt(i + 3));\n out[op++] = (v2 << 6) | v3;\n haveBad |= v3 & INVALID_BYTE;\n }\n if (haveBad !== 0) {\n throw new Error(\"Base64Coder: incorrect characters for decoding\");\n }\n return out;\n }\n\n // Standard encoding have the following encoded/decoded ranges,\n // which we need to convert between.\n //\n // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 + /\n // Index: 0 - 25 26 - 51 52 - 61 62 63\n // ASCII: 65 - 90 97 - 122 48 - 57 43 47\n //\n\n // Encode 6 bits in b into a new character.\n protected _encodeByte(b: number): string {\n // Encoding uses constant time operations as follows:\n //\n // 1. Define comparison of A with B using (A - B) >>> 8:\n // if A > B, then result is positive integer\n // if A <= B, then result is 0\n //\n // 2. Define selection of C or 0 using bitwise AND: X & C:\n // if X == 0, then result is 0\n // if X != 0, then result is C\n //\n // 3. Start with the smallest comparison (b >= 0), which is always\n // true, so set the result to the starting ASCII value (65).\n //\n // 4. Continue comparing b to higher ASCII values, and selecting\n // zero if comparison isn't true, otherwise selecting a value\n // to add to result, which:\n //\n // a) undoes the previous addition\n // b) provides new value to add\n //\n let result = b;\n // b >= 0\n result += 65;\n // b > 25\n result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);\n // b > 51\n result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);\n // b > 61\n result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 43);\n // b > 62\n result += ((62 - b) >>> 8) & ((62 - 43) - 63 + 47);\n\n return String.fromCharCode(result);\n }\n\n // Decode a character code into a byte.\n // Must return 256 if character is out of alphabet range.\n protected _decodeChar(c: number): number {\n // Decoding works similar to encoding: using the same comparison\n // function, but now it works on ranges: result is always incremented\n // by value, but this value becomes zero if the range is not\n // satisfied.\n //\n // Decoding starts with invalid value, 256, which is then\n // subtracted when the range is satisfied. If none of the ranges\n // apply, the function returns 256, which is then checked by\n // the caller to throw error.\n let result = INVALID_BYTE; // start with invalid character\n\n // c == 43 (c > 42 and c < 44)\n result += (((42 - c) & (c - 44)) >>> 8) & (-INVALID_BYTE + c - 43 + 62);\n // c == 47 (c > 46 and c < 48)\n result += (((46 - c) & (c - 48)) >>> 8) & (-INVALID_BYTE + c - 47 + 63);\n // c > 47 and c < 58\n result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);\n // c > 64 and c < 91\n result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);\n // c > 96 and c < 123\n result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);\n\n return result;\n }\n\n private _getPaddingLength(s: string): number {\n let paddingLength = 0;\n if (this._paddingCharacter) {\n for (let i = s.length - 1; i >= 0; i--) {\n if (s[i] !== this._paddingCharacter) {\n break;\n }\n paddingLength++;\n }\n if (s.length < 4 || paddingLength > 2) {\n throw new Error(\"Base64Coder: incorrect padding\");\n }\n }\n return paddingLength;\n }\n\n}\n\nconst stdCoder = new Coder();\n\nexport function encode(data: Uint8Array): string {\n return stdCoder.encode(data);\n}\n\nexport function decode(s: string): Uint8Array {\n return stdCoder.decode(s);\n}\n\n/**\n * Implements URL-safe Base64 encoding.\n * (Same as Base64, but '+' is replaced with '-', and '/' with '_').\n *\n * Operates in constant time.\n */\nexport class URLSafeCoder extends Coder {\n // URL-safe encoding have the following encoded/decoded ranges:\n //\n // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 - _\n // Index: 0 - 25 26 - 51 52 - 61 62 63\n // ASCII: 65 - 90 97 - 122 48 - 57 45 95\n //\n\n protected _encodeByte(b: number): string {\n let result = b;\n // b >= 0\n result += 65;\n // b > 25\n result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);\n // b > 51\n result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);\n // b > 61\n result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 45);\n // b > 62\n result += ((62 - b) >>> 8) & ((62 - 45) - 63 + 95);\n\n return String.fromCharCode(result);\n }\n\n protected _decodeChar(c: number): number {\n let result = INVALID_BYTE;\n\n // c == 45 (c > 44 and c < 46)\n result += (((44 - c) & (c - 46)) >>> 8) & (-INVALID_BYTE + c - 45 + 62);\n // c == 95 (c > 94 and c < 96)\n result += (((94 - c) & (c - 96)) >>> 8) & (-INVALID_BYTE + c - 95 + 63);\n // c > 47 and c < 58\n result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);\n // c > 64 and c < 91\n result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);\n // c > 96 and c < 123\n result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);\n\n return result;\n }\n}\n\nconst urlSafeCoder = new URLSafeCoder();\n\nexport function encodeURLSafe(data: Uint8Array): string {\n return urlSafeCoder.encode(data);\n}\n\nexport function decodeURLSafe(s: string): Uint8Array {\n return urlSafeCoder.decode(s);\n}\n\n\nexport const encodedLength = (length: number) =>\n stdCoder.encodedLength(length);\n\nexport const maxDecodedLength = (length: number) =>\n stdCoder.maxDecodedLength(length);\n\nexport const decodedLength = (s: string) =>\n stdCoder.decodedLength(s);\n","(function (root, factory) {\n // Hack to make all exports of this module sha256 function object properties.\n var exports = {};\n factory(exports);\n var sha256 = exports[\"default\"];\n for (var k in exports) {\n sha256[k] = exports[k];\n }\n \n if (typeof module === 'object' && typeof module.exports === 'object') {\n module.exports = sha256;\n } else if (typeof define === 'function' && define.amd) {\n define(function() { return sha256; }); \n } else {\n root.sha256 = sha256;\n }\n})(this, function(exports) {\n\"use strict\";\nexports.__esModule = true;\n// SHA-256 (+ HMAC and PBKDF2) for JavaScript.\n//\n// Written in 2014-2016 by Dmitry Chestnykh.\n// Public domain, no warranty.\n//\n// Functions (accept and return Uint8Arrays):\n//\n// sha256(message) -> hash\n// sha256.hmac(key, message) -> mac\n// sha256.pbkdf2(password, salt, rounds, dkLen) -> dk\n//\n// Classes:\n//\n// new sha256.Hash()\n// new sha256.HMAC(key)\n//\nexports.digestLength = 32;\nexports.blockSize = 64;\n// SHA-256 constants\nvar K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,\n 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,\n 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,\n 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,\n 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,\n 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,\n 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,\n 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,\n 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\nfunction hashBlocks(w, v, p, pos, len) {\n var a, b, c, d, e, f, g, h, u, i, j, t1, t2;\n while (len >= 64) {\n a = v[0];\n b = v[1];\n c = v[2];\n d = v[3];\n e = v[4];\n f = v[5];\n g = v[6];\n h = v[7];\n for (i = 0; i < 16; i++) {\n j = pos + i * 4;\n w[i] = (((p[j] & 0xff) << 24) | ((p[j + 1] & 0xff) << 16) |\n ((p[j + 2] & 0xff) << 8) | (p[j + 3] & 0xff));\n }\n for (i = 16; i < 64; i++) {\n u = w[i - 2];\n t1 = (u >>> 17 | u << (32 - 17)) ^ (u >>> 19 | u << (32 - 19)) ^ (u >>> 10);\n u = w[i - 15];\n t2 = (u >>> 7 | u << (32 - 7)) ^ (u >>> 18 | u << (32 - 18)) ^ (u >>> 3);\n w[i] = (t1 + w[i - 7] | 0) + (t2 + w[i - 16] | 0);\n }\n for (i = 0; i < 64; i++) {\n t1 = (((((e >>> 6 | e << (32 - 6)) ^ (e >>> 11 | e << (32 - 11)) ^\n (e >>> 25 | e << (32 - 25))) + ((e & f) ^ (~e & g))) | 0) +\n ((h + ((K[i] + w[i]) | 0)) | 0)) | 0;\n t2 = (((a >>> 2 | a << (32 - 2)) ^ (a >>> 13 | a << (32 - 13)) ^\n (a >>> 22 | a << (32 - 22))) + ((a & b) ^ (a & c) ^ (b & c))) | 0;\n h = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n v[0] += a;\n v[1] += b;\n v[2] += c;\n v[3] += d;\n v[4] += e;\n v[5] += f;\n v[6] += g;\n v[7] += h;\n pos += 64;\n len -= 64;\n }\n return pos;\n}\n// Hash implements SHA256 hash algorithm.\nvar Hash = /** @class */ (function () {\n function Hash() {\n this.digestLength = exports.digestLength;\n this.blockSize = exports.blockSize;\n // Note: Int32Array is used instead of Uint32Array for performance reasons.\n this.state = new Int32Array(8); // hash state\n this.temp = new Int32Array(64); // temporary state\n this.buffer = new Uint8Array(128); // buffer for data to hash\n this.bufferLength = 0; // number of bytes in buffer\n this.bytesHashed = 0; // number of total bytes hashed\n this.finished = false; // indicates whether the hash was finalized\n this.reset();\n }\n // Resets hash state making it possible\n // to re-use this instance to hash other data.\n Hash.prototype.reset = function () {\n this.state[0] = 0x6a09e667;\n this.state[1] = 0xbb67ae85;\n this.state[2] = 0x3c6ef372;\n this.state[3] = 0xa54ff53a;\n this.state[4] = 0x510e527f;\n this.state[5] = 0x9b05688c;\n this.state[6] = 0x1f83d9ab;\n this.state[7] = 0x5be0cd19;\n this.bufferLength = 0;\n this.bytesHashed = 0;\n this.finished = false;\n return this;\n };\n // Cleans internal buffers and re-initializes hash state.\n Hash.prototype.clean = function () {\n for (var i = 0; i < this.buffer.length; i++) {\n this.buffer[i] = 0;\n }\n for (var i = 0; i < this.temp.length; i++) {\n this.temp[i] = 0;\n }\n this.reset();\n };\n // Updates hash state with the given data.\n //\n // Optionally, length of the data can be specified to hash\n // fewer bytes than data.length.\n //\n // Throws error when trying to update already finalized hash:\n // instance must be reset to use it again.\n Hash.prototype.update = function (data, dataLength) {\n if (dataLength === void 0) { dataLength = data.length; }\n if (this.finished) {\n throw new Error(\"SHA256: can't update because hash was finished.\");\n }\n var dataPos = 0;\n this.bytesHashed += dataLength;\n if (this.bufferLength > 0) {\n while (this.bufferLength < 64 && dataLength > 0) {\n this.buffer[this.bufferLength++] = data[dataPos++];\n dataLength--;\n }\n if (this.bufferLength === 64) {\n hashBlocks(this.temp, this.state, this.buffer, 0, 64);\n this.bufferLength = 0;\n }\n }\n if (dataLength >= 64) {\n dataPos = hashBlocks(this.temp, this.state, data, dataPos, dataLength);\n dataLength %= 64;\n }\n while (dataLength > 0) {\n this.buffer[this.bufferLength++] = data[dataPos++];\n dataLength--;\n }\n return this;\n };\n // Finalizes hash state and puts hash into out.\n //\n // If hash was already finalized, puts the same value.\n Hash.prototype.finish = function (out) {\n if (!this.finished) {\n var bytesHashed = this.bytesHashed;\n var left = this.bufferLength;\n var bitLenHi = (bytesHashed / 0x20000000) | 0;\n var bitLenLo = bytesHashed << 3;\n var padLength = (bytesHashed % 64 < 56) ? 64 : 128;\n this.buffer[left] = 0x80;\n for (var i = left + 1; i < padLength - 8; i++) {\n this.buffer[i] = 0;\n }\n this.buffer[padLength - 8] = (bitLenHi >>> 24) & 0xff;\n this.buffer[padLength - 7] = (bitLenHi >>> 16) & 0xff;\n this.buffer[padLength - 6] = (bitLenHi >>> 8) & 0xff;\n this.buffer[padLength - 5] = (bitLenHi >>> 0) & 0xff;\n this.buffer[padLength - 4] = (bitLenLo >>> 24) & 0xff;\n this.buffer[padLength - 3] = (bitLenLo >>> 16) & 0xff;\n this.buffer[padLength - 2] = (bitLenLo >>> 8) & 0xff;\n this.buffer[padLength - 1] = (bitLenLo >>> 0) & 0xff;\n hashBlocks(this.temp, this.state, this.buffer, 0, padLength);\n this.finished = true;\n }\n for (var i = 0; i < 8; i++) {\n out[i * 4 + 0] = (this.state[i] >>> 24) & 0xff;\n out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff;\n out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff;\n out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff;\n }\n return this;\n };\n // Returns the final hash digest.\n Hash.prototype.digest = function () {\n var out = new Uint8Array(this.digestLength);\n this.finish(out);\n return out;\n };\n // Internal function for use in HMAC for optimization.\n Hash.prototype._saveState = function (out) {\n for (var i = 0; i < this.state.length; i++) {\n out[i] = this.state[i];\n }\n };\n // Internal function for use in HMAC for optimization.\n Hash.prototype._restoreState = function (from, bytesHashed) {\n for (var i = 0; i < this.state.length; i++) {\n this.state[i] = from[i];\n }\n this.bytesHashed = bytesHashed;\n this.finished = false;\n this.bufferLength = 0;\n };\n return Hash;\n}());\nexports.Hash = Hash;\n// HMAC implements HMAC-SHA256 message authentication algorithm.\nvar HMAC = /** @class */ (function () {\n function HMAC(key) {\n this.inner = new Hash();\n this.outer = new Hash();\n this.blockSize = this.inner.blockSize;\n this.digestLength = this.inner.digestLength;\n var pad = new Uint8Array(this.blockSize);\n if (key.length > this.blockSize) {\n (new Hash()).update(key).finish(pad).clean();\n }\n else {\n for (var i = 0; i < key.length; i++) {\n pad[i] = key[i];\n }\n }\n for (var i = 0; i < pad.length; i++) {\n pad[i] ^= 0x36;\n }\n this.inner.update(pad);\n for (var i = 0; i < pad.length; i++) {\n pad[i] ^= 0x36 ^ 0x5c;\n }\n this.outer.update(pad);\n this.istate = new Uint32Array(8);\n this.ostate = new Uint32Array(8);\n this.inner._saveState(this.istate);\n this.outer._saveState(this.ostate);\n for (var i = 0; i < pad.length; i++) {\n pad[i] = 0;\n }\n }\n // Returns HMAC state to the state initialized with key\n // to make it possible to run HMAC over the other data with the same\n // key without creating a new instance.\n HMAC.prototype.reset = function () {\n this.inner._restoreState(this.istate, this.inner.blockSize);\n this.outer._restoreState(this.ostate, this.outer.blockSize);\n return this;\n };\n // Cleans HMAC state.\n HMAC.prototype.clean = function () {\n for (var i = 0; i < this.istate.length; i++) {\n this.ostate[i] = this.istate[i] = 0;\n }\n this.inner.clean();\n this.outer.clean();\n };\n // Updates state with provided data.\n HMAC.prototype.update = function (data) {\n this.inner.update(data);\n return this;\n };\n // Finalizes HMAC and puts the result in out.\n HMAC.prototype.finish = function (out) {\n if (this.outer.finished) {\n this.outer.finish(out);\n }\n else {\n this.inner.finish(out);\n this.outer.update(out, this.digestLength).finish(out);\n }\n return this;\n };\n // Returns message authentication code.\n HMAC.prototype.digest = function () {\n var out = new Uint8Array(this.digestLength);\n this.finish(out);\n return out;\n };\n return HMAC;\n}());\nexports.HMAC = HMAC;\n// Returns SHA256 hash of data.\nfunction hash(data) {\n var h = (new Hash()).update(data);\n var digest = h.digest();\n h.clean();\n return digest;\n}\nexports.hash = hash;\n// Function hash is both available as module.hash and as default export.\nexports[\"default\"] = hash;\n// Returns HMAC-SHA256 of data under the key.\nfunction hmac(key, data) {\n var h = (new HMAC(key)).update(data);\n var digest = h.digest();\n h.clean();\n return digest;\n}\nexports.hmac = hmac;\n// Fills hkdf buffer like this:\n// T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)\nfunction fillBuffer(buffer, hmac, info, counter) {\n // Counter is a byte value: check if it overflowed.\n var num = counter[0];\n if (num === 0) {\n throw new Error(\"hkdf: cannot expand more\");\n }\n // Prepare HMAC instance for new data with old key.\n hmac.reset();\n // Hash in previous output if it was generated\n // (i.e. counter is greater than 1).\n if (num > 1) {\n hmac.update(buffer);\n }\n // Hash in info if it exists.\n if (info) {\n hmac.update(info);\n }\n // Hash in the counter.\n hmac.update(counter);\n // Output result to buffer and clean HMAC instance.\n hmac.finish(buffer);\n // Increment counter inside typed array, this works properly.\n counter[0]++;\n}\nvar hkdfSalt = new Uint8Array(exports.digestLength); // Filled with zeroes.\nfunction hkdf(key, salt, info, length) {\n if (salt === void 0) { salt = hkdfSalt; }\n if (length === void 0) { length = 32; }\n var counter = new Uint8Array([1]);\n // HKDF-Extract uses salt as HMAC key, and key as data.\n var okm = hmac(salt, key);\n // Initialize HMAC for expanding with extracted key.\n // Ensure no collisions with `hmac` function.\n var hmac_ = new HMAC(okm);\n // Allocate buffer.\n var buffer = new Uint8Array(hmac_.digestLength);\n var bufpos = buffer.length;\n var out = new Uint8Array(length);\n for (var i = 0; i < length; i++) {\n if (bufpos === buffer.length) {\n fillBuffer(buffer, hmac_, info, counter);\n bufpos = 0;\n }\n out[i] = buffer[bufpos++];\n }\n hmac_.clean();\n buffer.fill(0);\n counter.fill(0);\n return out;\n}\nexports.hkdf = hkdf;\n// Derives a key from password and salt using PBKDF2-HMAC-SHA256\n// with the given number of iterations.\n//\n// The number of bytes returned is equal to dkLen.\n//\n// (For better security, avoid dkLen greater than hash length - 32 bytes).\nfunction pbkdf2(password, salt, iterations, dkLen) {\n var prf = new HMAC(password);\n var len = prf.digestLength;\n var ctr = new Uint8Array(4);\n var t = new Uint8Array(len);\n var u = new Uint8Array(len);\n var dk = new Uint8Array(dkLen);\n for (var i = 0; i * len < dkLen; i++) {\n var c = i + 1;\n ctr[0] = (c >>> 24) & 0xff;\n ctr[1] = (c >>> 16) & 0xff;\n ctr[2] = (c >>> 8) & 0xff;\n ctr[3] = (c >>> 0) & 0xff;\n prf.reset();\n prf.update(salt);\n prf.update(ctr);\n prf.finish(u);\n for (var j = 0; j < len; j++) {\n t[j] = u[j];\n }\n for (var j = 2; j <= iterations; j++) {\n prf.reset();\n prf.update(u).finish(u);\n for (var k = 0; k < len; k++) {\n t[k] ^= u[k];\n }\n }\n for (var j = 0; j < len && i * len + j < dkLen; j++) {\n dk[i * len + j] = t[j];\n }\n }\n for (var i = 0; i < len; i++) {\n t[i] = u[i] = 0;\n }\n for (var i = 0; i < 4; i++) {\n ctr[i] = 0;\n }\n prf.clean();\n return dk;\n}\nexports.pbkdf2 = pbkdf2;\n});\n",null,"/** Tiny argv parser: `--flag value`, `--flag=value`, `--bool`, `--no-bool`, repeated flags → arrays. */\nexport interface ParsedArgs {\n command: string | undefined;\n positionals: string[];\n flags: Record<string, string | boolean | string[]>;\n}\n\nconst VALUE_FLAGS = new Set([\n \"config\",\n \"client\",\n \"mode\",\n \"port\",\n \"host\",\n \"agent\",\n \"run-id\",\n \"run\",\n \"base\",\n \"head\",\n \"paths\",\n \"format\",\n \"by\",\n \"note\",\n \"allow\",\n \"deny\",\n \"writes\",\n \"spend\",\n \"tool-calls\",\n \"deletes\",\n \"emails\",\n \"reason\",\n \"url\",\n \"timeout\",\n \"out\",\n \"upstream\",\n \"command\",\n \"fallback-config\",\n \"since\",\n \"repo\",\n \"cache-dir\",\n \"claude-dir\",\n \"codex-dir\",\n \"rules\",\n]);\n\nexport function parseArgs(argv: readonly string[]): ParsedArgs {\n const out: ParsedArgs = { command: undefined, positionals: [], flags: {} };\n const push = (key: string, value: string | boolean): void => {\n const existing = out.flags[key];\n if (existing === undefined) out.flags[key] = value;\n else if (Array.isArray(existing)) existing.push(String(value));\n else out.flags[key] = [String(existing), String(value)];\n };\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i]!;\n if (arg === \"--\") {\n out.positionals.push(...argv.slice(i + 1));\n break;\n }\n if (arg.startsWith(\"--\")) {\n const body = arg.slice(2);\n const eq = body.indexOf(\"=\");\n if (eq >= 0) {\n push(body.slice(0, eq), body.slice(eq + 1));\n continue;\n }\n if (body.startsWith(\"no-\")) {\n push(body.slice(3), false);\n continue;\n }\n const next = argv[i + 1];\n if (VALUE_FLAGS.has(body) && next !== undefined && !next.startsWith(\"--\")) {\n push(body, next);\n i += 1;\n } else push(body, true);\n continue;\n }\n if (arg.startsWith(\"-\") && arg.length === 2) {\n const short: Record<string, string> = {\n c: \"config\",\n y: \"yes\",\n h: \"help\",\n v: \"version\",\n j: \"json\",\n a: \"all\",\n };\n const key = short[arg[1]!] ?? arg[1]!;\n const next = argv[i + 1];\n if (VALUE_FLAGS.has(key) && next !== undefined && !next.startsWith(\"-\")) {\n push(key, next);\n i += 1;\n } else push(key, true);\n continue;\n }\n if (out.command === undefined) out.command = arg;\n else out.positionals.push(arg);\n }\n return out;\n}\n\nexport function flagString(args: ParsedArgs, name: string): string | undefined {\n const v = args.flags[name];\n if (Array.isArray(v)) return v[v.length - 1];\n return typeof v === \"string\" ? v : undefined;\n}\n\nexport function flagList(args: ParsedArgs, name: string): string[] {\n const v = args.flags[name];\n if (Array.isArray(v)) return v.flatMap((s) => s.split(\",\"));\n return typeof v === \"string\" ? v.split(\",\") : [];\n}\n\nexport function flagBool(args: ParsedArgs, name: string): boolean | undefined {\n const v = args.flags[name];\n if (typeof v === \"boolean\") return v;\n if (typeof v === \"string\") return v !== \"false\" && v !== \"0\";\n return undefined;\n}\n\nexport function flagNumber(args: ParsedArgs, name: string): number | undefined {\n const s = flagString(args, name);\n if (s === undefined) return undefined;\n const n = Number(s);\n return Number.isFinite(n) ? n : undefined;\n}\n","/**\n * The installed package version, read from package.json.\n *\n * It is reported to MCP clients in `serverInfo` and printed by `--version`. Keeping it in one\n * place matters: three hand-written copies had drifted to 0.1.0 while npm served 0.1.2, so a\n * client could not tell which build it was talking to.\n */\nimport { readFileSync } from \"node:fs\";\n\nlet cached: string | undefined;\n\nexport function version(): string {\n if (cached !== undefined) return cached;\n try {\n cached = (\n JSON.parse(readFileSync(new URL(\"../package.json\", import.meta.url), \"utf8\")) as {\n version: string;\n }\n ).version;\n } catch {\n cached = \"0.0.0\";\n }\n return cached;\n}\n","/**\n * Where a running HTTP proxy registers itself (`<state>/http.json`) so `kill`, `approve` and the\n * hook can find it. Kept apart from `proxy/http.ts` so reading it does not load the MCP SDK:\n * `agentguard hook pre-tool-use` runs before every guarded tool call and must start fast.\n */\nimport { join } from \"node:path\";\n\nexport interface HttpRegistration {\n url: string;\n baseUrl: string;\n token: string;\n pid: number;\n startedAt: string;\n}\n\nexport function registrationPath(stateDir: string): string {\n return join(stateDir, \"http.json\");\n}\n","export const textEncoder = new TextEncoder();\n\nconst base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n// Use a lookup table to find the index.\nconst base64Lookup = new Uint8Array(256);\nfor (let i = 0; i < base64Chars.length; i++) {\n base64Lookup[base64Chars.charCodeAt(i)] = i;\n}\n\nexport function decodeBase64(base64) {\n let bufferLength = Math.ceil(base64.length / 4) * 3;\n const len = base64.length;\n\n let p = 0;\n\n if (base64.length % 4 === 3) {\n bufferLength--;\n } else if (base64.length % 4 === 2) {\n bufferLength -= 2;\n } else if (base64[base64.length - 1] === '=') {\n bufferLength--;\n if (base64[base64.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n const arrayBuffer = new ArrayBuffer(bufferLength);\n const bytes = new Uint8Array(arrayBuffer);\n\n for (let i = 0; i < len; i += 4) {\n let encoded1 = base64Lookup[base64.charCodeAt(i)];\n let encoded2 = base64Lookup[base64.charCodeAt(i + 1)];\n let encoded3 = base64Lookup[base64.charCodeAt(i + 2)];\n let encoded4 = base64Lookup[base64.charCodeAt(i + 3)];\n\n bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n }\n\n return arrayBuffer;\n}\n\n// Charset aliases that the WHATWG Encoding Standard (and thus TextDecoder in\n// browsers and Workers) does not recognize, but that map cleanly to a supported\n// encoding. Node's ICU-backed TextDecoder resolves these natively; strict WHATWG\n// runtimes would otherwise throw and fall back to windows-1252, emitting mojibake.\n// eg. Hebrew bodies declared as the logical (iso-8859-8-i) or explicit (iso-8859-8-e)\n// variants decode to the same code points as iso-8859-8.\nconst charsetAliases = new Map([\n ['iso-8859-8-i', 'iso-8859-8'],\n ['iso-8859-8-e', 'iso-8859-8']\n]);\n\nexport function getDecoder(charset) {\n charset = (charset || 'utf8').trim().toLowerCase();\n charset = charsetAliases.get(charset) || charset;\n\n let decoder;\n\n try {\n decoder = new TextDecoder(charset);\n } catch (err) {\n decoder = new TextDecoder('windows-1252');\n }\n\n return decoder;\n}\n\n/**\n * Converts a Blob into an ArrayBuffer\n * @param {Blob} blob Blob to convert\n * @returns {ArrayBuffer} Converted value\n */\nexport async function blobToArrayBuffer(blob) {\n if ('arrayBuffer' in blob) {\n return await blob.arrayBuffer();\n }\n\n const fr = new FileReader();\n\n return new Promise((resolve, reject) => {\n fr.onload = function (e) {\n resolve(e.target.result);\n };\n\n fr.onerror = function (e) {\n reject(fr.error);\n };\n\n fr.readAsArrayBuffer(blob);\n });\n}\n\nexport function getHex(c) {\n if (\n (c >= 0x30 /* 0 */ && c <= 0x39) /* 9 */ ||\n (c >= 0x61 /* a */ && c <= 0x66) /* f */ ||\n (c >= 0x41 /* A */ && c <= 0x46) /* F */\n ) {\n return String.fromCharCode(c);\n }\n return false;\n}\n\n/**\n * Decode a complete mime word encoded string\n *\n * @param {String} str Mime word encoded string\n * @return {String} Decoded unicode string\n */\nexport function decodeWord(charset, encoding, str) {\n // RFC2231 added language tag to the encoding\n // see: https://tools.ietf.org/html/rfc2231#section-5\n // this implementation silently ignores this tag\n let splitPos = charset.indexOf('*');\n if (splitPos >= 0) {\n charset = charset.substr(0, splitPos);\n }\n\n encoding = encoding.toUpperCase();\n\n let byteStr;\n\n if (encoding === 'Q') {\n str = str\n // remove spaces between = and hex char, this might indicate invalidly applied line splitting\n .replace(/=\\s+([0-9a-fA-F])/g, '=$1')\n // convert all underscores to spaces\n .replace(/[_\\s]/g, ' ');\n\n let buf = textEncoder.encode(str);\n let encodedBytes = [];\n for (let i = 0, len = buf.length; i < len; i++) {\n let c = buf[i];\n if (i <= len - 2 && c === 0x3d /* = */) {\n let c1 = getHex(buf[i + 1]);\n let c2 = getHex(buf[i + 2]);\n if (c1 && c2) {\n let c = parseInt(c1 + c2, 16);\n encodedBytes.push(c);\n i += 2;\n continue;\n }\n }\n encodedBytes.push(c);\n }\n byteStr = new ArrayBuffer(encodedBytes.length);\n let dataView = new DataView(byteStr);\n for (let i = 0, len = encodedBytes.length; i < len; i++) {\n dataView.setUint8(i, encodedBytes[i]);\n }\n } else if (encoding === 'B') {\n byteStr = decodeBase64(str.replace(/[^a-zA-Z0-9\\+\\/=]+/g, ''));\n } else {\n // keep as is, convert ArrayBuffer to unicode string, assume utf8\n byteStr = textEncoder.encode(str);\n }\n\n return getDecoder(charset).decode(byteStr);\n}\n\nexport function decodeWords(str) {\n let joinString = true;\n let done = false;\n\n while (!done) {\n let result = (str || '')\n .toString()\n // find base64 words that can be joined\n .replace(\n /(=\\?([^?]+)\\?[Bb]\\?([^?]*)\\?=)\\s*(?==\\?([^?]+)\\?[Bb]\\?[^?]*\\?=)/g,\n (match, left, chLeft, encodedLeftStr, chRight) => {\n if (!joinString) {\n return match;\n }\n // only mark b64 chunks to be joined if charsets match and left side does not end with =\n if (chLeft === chRight && encodedLeftStr.length % 4 === 0 && !/=$/.test(encodedLeftStr)) {\n // set a joiner marker\n return left + '__\\x00JOIN\\x00__';\n }\n\n return match;\n }\n )\n // find QP words that can be joined\n .replace(\n /(=\\?([^?]+)\\?[Qq]\\?[^?]*\\?=)\\s*(?==\\?([^?]+)\\?[Qq]\\?[^?]*\\?=)/g,\n (match, left, chLeft, chRight) => {\n if (!joinString) {\n return match;\n }\n // only mark QP chunks to be joined if charsets match\n if (chLeft === chRight) {\n // set a joiner marker\n return left + '__\\x00JOIN\\x00__';\n }\n return match;\n }\n )\n // join base64 encoded words\n .replace(/(\\?=)?__\\x00JOIN\\x00__(=\\?([^?]+)\\?[QqBb]\\?)?/g, '')\n // remove spaces between mime encoded words\n .replace(/(=\\?[^?]+\\?[QqBb]\\?[^?]*\\?=)\\s+(?==\\?[^?]+\\?[QqBb]\\?[^?]*\\?=)/g, '$1')\n // decode words\n .replace(/=\\?([\\w_\\-*]+)\\?([QqBb])\\?([^?]*)\\?=/g, (m, charset, encoding, text) =>\n decodeWord(charset, encoding, text)\n );\n\n if (joinString && result.indexOf('\\ufffd') >= 0) {\n // text contains \\ufffd (EF BF BD), so unicode conversion failed, retry without joining strings\n joinString = false;\n } else {\n return result;\n }\n }\n}\n\nexport function decodeURIComponentWithCharset(encodedStr, charset) {\n charset = charset || 'utf-8';\n\n let encodedBytes = [];\n for (let i = 0; i < encodedStr.length; i++) {\n let c = encodedStr.charAt(i);\n if (c === '%' && /^[a-f0-9]{2}/i.test(encodedStr.substr(i + 1, 2))) {\n // encoded sequence\n let byte = encodedStr.substr(i + 1, 2);\n i += 2;\n encodedBytes.push(parseInt(byte, 16));\n } else if (c.charCodeAt(0) > 126) {\n c = textEncoder.encode(c);\n for (let j = 0; j < c.length; j++) {\n encodedBytes.push(c[j]);\n }\n } else {\n // \"normal\" char\n encodedBytes.push(c.charCodeAt(0));\n }\n }\n\n const byteStr = new ArrayBuffer(encodedBytes.length);\n const dataView = new DataView(byteStr);\n for (let i = 0, len = encodedBytes.length; i < len; i++) {\n dataView.setUint8(i, encodedBytes[i]);\n }\n\n return getDecoder(charset).decode(byteStr);\n}\n\nexport function decodeParameterValueContinuations(header) {\n // handle parameter value continuations\n // https://tools.ietf.org/html/rfc2231#section-3\n\n // preprocess values\n let paramKeys = new Map();\n\n Object.keys(header.params).forEach(key => {\n let match = key.match(/\\*((\\d+)\\*?)?$/);\n if (!match) {\n // nothing to do here, does not seem like a continuation param\n return;\n }\n\n let actualKey = key.substr(0, match.index).toLowerCase();\n let nr = Number(match[2]) || 0;\n\n let paramVal;\n if (!paramKeys.has(actualKey)) {\n paramVal = {\n charset: false,\n values: []\n };\n paramKeys.set(actualKey, paramVal);\n } else {\n paramVal = paramKeys.get(actualKey);\n }\n\n let value = header.params[key];\n if (nr === 0 && match[0].charAt(match[0].length - 1) === '*' && (match = value.match(/^([^']*)'[^']*'(.*)$/))) {\n paramVal.charset = match[1] || 'utf-8';\n value = match[2];\n }\n\n paramVal.values.push({ nr, value });\n\n // remove the old reference\n delete header.params[key];\n });\n\n paramKeys.forEach((paramVal, key) => {\n header.params[key] = decodeURIComponentWithCharset(\n paramVal.values\n .sort((a, b) => a.nr - b.nr)\n .map(a => a.value)\n .join(''),\n paramVal.charset\n );\n });\n}\n","import { getDecoder, decodeParameterValueContinuations, textEncoder } from './decode-strings.js';\nimport PassThroughDecoder from './pass-through-decoder.js';\nimport Base64Decoder from './base64-decoder.js';\nimport QPDecoder from './qp-decoder.js';\n\nconst defaultDecoder = getDecoder();\n\nexport default class MimeNode {\n constructor(options) {\n this.options = options || {};\n\n this.postalMime = this.options.postalMime;\n\n this.root = !!this.options.parentNode;\n this.childNodes = [];\n\n if (this.options.parentNode) {\n this.parentNode = this.options.parentNode;\n\n this.depth = this.parentNode.depth + 1;\n if (this.depth > this.options.maxNestingDepth) {\n throw new Error(`Maximum MIME nesting depth of ${this.options.maxNestingDepth} levels exceeded`);\n }\n\n this.options.parentNode.childNodes.push(this);\n } else {\n this.depth = 0;\n }\n\n this.state = 'header';\n\n this.headerLines = [];\n this.headerSize = 0;\n\n // RFC 2046 Section 5.1.5: multipart/digest defaults to message/rfc822\n const parentMultipartType = this.options.parentMultipartType || null;\n const defaultContentType = parentMultipartType === 'digest' ? 'message/rfc822' : 'text/plain';\n\n this.contentType = {\n value: defaultContentType,\n default: true\n };\n\n this.contentTransferEncoding = {\n value: '8bit'\n };\n\n this.contentDisposition = {\n value: ''\n };\n\n this.headers = [];\n\n this.contentDecoder = false;\n }\n\n setupContentDecoder(transferEncoding) {\n if (/base64/i.test(transferEncoding)) {\n this.contentDecoder = new Base64Decoder();\n } else if (/quoted-printable/i.test(transferEncoding)) {\n this.contentDecoder = new QPDecoder({ decoder: getDecoder(this.contentType.parsed.params.charset) });\n } else {\n this.contentDecoder = new PassThroughDecoder();\n }\n }\n\n async finalize() {\n if (this.state === 'finished') {\n return;\n }\n\n if (this.state === 'header') {\n this.processHeaders();\n }\n\n // remove self from boundary listing\n let boundaries = this.postalMime.boundaries;\n for (let i = boundaries.length - 1; i >= 0; i--) {\n let boundary = boundaries[i];\n if (boundary.node === this) {\n boundaries.splice(i, 1);\n break;\n }\n }\n\n await this.finalizeChildNodes();\n\n this.content = this.contentDecoder ? await this.contentDecoder.finalize() : null;\n\n this.state = 'finished';\n }\n\n async finalizeChildNodes() {\n for (let childNode of this.childNodes) {\n await childNode.finalize();\n }\n }\n\n // Strip RFC 822 comments (parenthesized text) from structured header values\n stripComments(str) {\n let result = '';\n let depth = 0;\n let escaped = false;\n let inQuote = false;\n\n for (let i = 0; i < str.length; i++) {\n const chr = str.charAt(i);\n\n if (escaped) {\n if (depth === 0) {\n result += chr;\n }\n escaped = false;\n continue;\n }\n\n if (chr === '\\\\') {\n escaped = true;\n if (depth === 0) {\n result += chr;\n }\n continue;\n }\n\n if (chr === '\"' && depth === 0) {\n inQuote = !inQuote;\n result += chr;\n continue;\n }\n\n if (!inQuote) {\n if (chr === '(') {\n depth++;\n continue;\n }\n if (chr === ')' && depth > 0) {\n depth--;\n continue;\n }\n }\n\n if (depth === 0) {\n result += chr;\n }\n }\n\n return result;\n }\n\n parseStructuredHeader(str) {\n // Strip RFC 822 comments before parsing\n str = this.stripComments(str);\n\n let response = {\n value: false,\n params: {}\n };\n\n let key = false;\n let value = '';\n let stage = 'value';\n\n let quote = false;\n let escaped = false;\n let chr;\n\n for (let i = 0, len = str.length; i < len; i++) {\n chr = str.charAt(i);\n switch (stage) {\n case 'key':\n if (chr === '=') {\n key = value.trim().toLowerCase();\n stage = 'value';\n value = '';\n break;\n }\n value += chr;\n break;\n case 'value':\n if (escaped) {\n value += chr;\n } else if (chr === '\\\\') {\n escaped = true;\n continue;\n } else if (quote && chr === quote) {\n quote = false;\n } else if (!quote && chr === '\"') {\n quote = chr;\n } else if (!quote && chr === ';') {\n if (key === false) {\n response.value = value.trim();\n } else {\n response.params[key] = value.trim();\n }\n stage = 'key';\n value = '';\n } else {\n value += chr;\n }\n escaped = false;\n break;\n }\n }\n\n // finalize remainder\n value = value.trim();\n if (stage === 'value') {\n if (key === false) {\n // default value\n response.value = value;\n } else {\n // subkey value\n response.params[key] = value;\n }\n } else if (value) {\n // treat as key without value, see emptykey:\n // Header-Key: somevalue; key=value; emptykey\n response.params[value.toLowerCase()] = '';\n }\n\n if (response.value) {\n response.value = response.value.toLowerCase();\n }\n\n // convert Parameter Value Continuations into single strings\n decodeParameterValueContinuations(response);\n\n return response;\n }\n\n decodeFlowedText(str, delSp) {\n return (\n str\n .split(/\\r?\\n/)\n // remove soft linebreaks\n // soft linebreaks are added after space symbols\n .reduce((previousValue, currentValue) => {\n if (previousValue.endsWith(' ') && previousValue !== '-- ' && !previousValue.endsWith('\\n-- ')) {\n if (delSp) {\n // delsp adds space to text to be able to fold it\n // these spaces can be removed once the text is unfolded\n return previousValue.slice(0, -1) + currentValue;\n } else {\n return previousValue + currentValue;\n }\n } else {\n return previousValue + '\\n' + currentValue;\n }\n })\n // remove whitespace stuffing\n // http://tools.ietf.org/html/rfc3676#section-4.4\n .replace(/^ /gm, '')\n );\n }\n\n getTextContent() {\n if (!this.content) {\n return '';\n }\n\n let str = getDecoder(this.contentType.parsed.params.charset).decode(this.content);\n\n if (/^flowed$/i.test(this.contentType.parsed.params.format)) {\n str = this.decodeFlowedText(str, /^yes$/i.test(this.contentType.parsed.params.delsp));\n }\n\n return str;\n }\n\n processHeaders() {\n // First pass: merge folded headers (backward iteration)\n for (let i = this.headerLines.length - 1; i >= 0; i--) {\n let line = this.headerLines[i];\n if (i && /^\\s/.test(line)) {\n this.headerLines[i - 1] += '\\n' + line;\n this.headerLines.splice(i, 1);\n }\n }\n\n // Initialize rawHeaderLines to store unmodified lines\n this.rawHeaderLines = [];\n\n // Second pass: process headers (MUST be backward to maintain this.headers order)\n // The existing code iterates backward and postal-mime.js calls .reverse()\n // We must preserve this behavior to avoid breaking changes\n for (let i = this.headerLines.length - 1; i >= 0; i--) {\n let rawLine = this.headerLines[i];\n\n // Extract key from raw line for rawHeaderLines\n let sep = rawLine.indexOf(':');\n let rawKey = sep < 0 ? rawLine.trim() : rawLine.substr(0, sep).trim();\n\n // Store raw line with lowercase key\n this.rawHeaderLines.push({\n key: rawKey.toLowerCase(),\n line: rawLine\n });\n\n // Normalize for this.headers (existing behavior - order preserved)\n let normalizedLine = rawLine.replace(/\\s+/g, ' ');\n sep = normalizedLine.indexOf(':');\n let key = sep < 0 ? normalizedLine.trim() : normalizedLine.substr(0, sep).trim();\n let value = sep < 0 ? '' : normalizedLine.substr(sep + 1).trim();\n this.headers.push({ key: key.toLowerCase(), originalKey: key, value });\n\n switch (key.toLowerCase()) {\n case 'content-type':\n if (this.contentType.default) {\n this.contentType = { value, parsed: {} };\n }\n break;\n case 'content-transfer-encoding':\n this.contentTransferEncoding = { value, parsed: {} };\n break;\n case 'content-disposition':\n this.contentDisposition = { value, parsed: {} };\n break;\n case 'content-id':\n this.contentId = value;\n break;\n case 'content-description':\n this.contentDescription = value;\n break;\n }\n }\n\n this.contentType.parsed = this.parseStructuredHeader(this.contentType.value);\n this.contentType.multipart = /^multipart\\//i.test(this.contentType.parsed.value)\n ? this.contentType.parsed.value.substr(this.contentType.parsed.value.indexOf('/') + 1)\n : false;\n\n if (this.contentType.multipart && this.contentType.parsed.params.boundary) {\n // add self to boundary terminator listing\n this.postalMime.boundaries.push({\n value: textEncoder.encode(this.contentType.parsed.params.boundary),\n node: this\n });\n }\n\n this.contentDisposition.parsed = this.parseStructuredHeader(this.contentDisposition.value);\n\n this.contentTransferEncoding.encoding = this.contentTransferEncoding.value\n .toLowerCase()\n .split(/[^\\w-]/)\n .shift();\n\n this.setupContentDecoder(this.contentTransferEncoding.encoding);\n }\n\n feed(line) {\n switch (this.state) {\n case 'header':\n if (!line.length) {\n this.state = 'body';\n return this.processHeaders();\n }\n\n this.headerSize += line.length;\n\n if (this.headerSize > this.options.maxHeadersSize) {\n let error = new Error(`Maximum header size of ${this.options.maxHeadersSize} bytes exceeded`);\n throw error;\n }\n\n this.headerLines.push(defaultDecoder.decode(line));\n break;\n case 'body': {\n // add line to body\n this.contentDecoder.update(line);\n }\n }\n }\n}\n","import MimeNode from './mime-node.js';\nimport { textToHtml, htmlToText, formatTextHeader, formatHtmlHeader } from './text-format.js';\nimport addressParser from './address-parser.js';\nimport { decodeWords, textEncoder, blobToArrayBuffer } from './decode-strings.js';\nimport { base64ArrayBuffer } from './base64-encoder.js';\n\nexport { addressParser, decodeWords };\n\nconst MAX_NESTING_DEPTH = 256;\nconst MAX_HEADERS_SIZE = 2 * 1024 * 1024;\n\nfunction toCamelCase(key) {\n return key.replace(/-(.)/g, (o, c) => c.toUpperCase());\n}\n\nexport default class PostalMime {\n static parse(buf, options) {\n const parser = new PostalMime(options);\n return parser.parse(buf);\n }\n\n constructor(options) {\n this.options = options || {};\n this.mimeOptions = {\n maxNestingDepth: this.options.maxNestingDepth || MAX_NESTING_DEPTH,\n maxHeadersSize: this.options.maxHeadersSize || MAX_HEADERS_SIZE\n };\n\n this.root = this.currentNode = new MimeNode({\n postalMime: this,\n ...this.mimeOptions\n });\n this.boundaries = [];\n\n this.textContent = {};\n this.attachments = [];\n\n this.attachmentEncoding =\n (this.options.attachmentEncoding || '')\n .toString()\n .replace(/[-_\\s]/g, '')\n .trim()\n .toLowerCase() || 'arraybuffer';\n\n this.started = false;\n }\n\n async finalize() {\n // close all pending nodes\n await this.root.finalize();\n }\n\n async processLine(line, isFinal) {\n let boundaries = this.boundaries;\n\n // check if this is a mime boundary\n if (boundaries.length && line.length > 2 && line[0] === 0x2d && line[1] === 0x2d) {\n // could be a boundary marker\n for (let i = boundaries.length - 1; i >= 0; i--) {\n let boundary = boundaries[i];\n\n // Line must be at least long enough for \"--\" + boundary\n if (line.length < boundary.value.length + 2) {\n continue;\n }\n\n // Check if boundary value matches\n let boundaryMatches = true;\n for (let j = 0; j < boundary.value.length; j++) {\n if (line[j + 2] !== boundary.value[j]) {\n boundaryMatches = false;\n break;\n }\n }\n if (!boundaryMatches) {\n continue;\n }\n\n // Check for terminator (-- after boundary) and determine where boundary ends\n let boundaryEnd = boundary.value.length + 2;\n let isTerminator = false;\n\n if (\n line.length >= boundary.value.length + 4 &&\n line[boundary.value.length + 2] === 0x2d &&\n line[boundary.value.length + 3] === 0x2d\n ) {\n isTerminator = true;\n boundaryEnd = boundary.value.length + 4;\n }\n\n // RFC 2046: boundary line may have trailing whitespace (space/tab) before CRLF\n let hasValidTrailing = true;\n for (let j = boundaryEnd; j < line.length; j++) {\n if (line[j] !== 0x20 && line[j] !== 0x09) {\n hasValidTrailing = false;\n break;\n }\n }\n if (!hasValidTrailing) {\n continue;\n }\n\n if (isTerminator) {\n await boundary.node.finalize();\n\n this.currentNode = boundary.node.parentNode || this.root;\n } else {\n // finalize any open child nodes (should be just one though)\n await boundary.node.finalizeChildNodes();\n\n this.currentNode = new MimeNode({\n postalMime: this,\n parentNode: boundary.node,\n parentMultipartType: boundary.node.contentType.multipart,\n ...this.mimeOptions\n });\n }\n\n if (isFinal) {\n return this.finalize();\n }\n\n return;\n }\n }\n\n this.currentNode.feed(line);\n\n if (isFinal) {\n return this.finalize();\n }\n }\n\n readLine() {\n let startPos = this.readPos;\n let endPos = this.readPos;\n\n while (this.readPos < this.av.length) {\n const c = this.av[this.readPos++];\n\n if (c !== 0x0d && c !== 0x0a) {\n endPos = this.readPos;\n }\n\n if (c === 0x0a) {\n return {\n bytes: new Uint8Array(this.buf, startPos, endPos - startPos),\n done: this.readPos >= this.av.length\n };\n }\n }\n\n return {\n bytes: new Uint8Array(this.buf, startPos, endPos - startPos),\n done: this.readPos >= this.av.length\n };\n }\n\n async processNodeTree() {\n // get text nodes\n\n let textContent = {};\n\n let textTypes = new Set();\n let textMap = (this.textMap = new Map());\n\n let forceRfc822Attachments = this.forceRfc822Attachments();\n\n let walk = async (node, alternative, related) => {\n alternative = alternative || false;\n related = related || false;\n\n if (!node.contentType.multipart) {\n // is it inline message/rfc822\n if (this.isInlineMessageRfc822(node) && !forceRfc822Attachments) {\n const subParser = new PostalMime();\n node.subMessage = await subParser.parse(node.content);\n\n if (!textMap.has(node)) {\n textMap.set(node, {});\n }\n\n let textEntry = textMap.get(node);\n\n // default to text if there is no content\n if (node.subMessage.text || !node.subMessage.html) {\n textEntry.plain = textEntry.plain || [];\n textEntry.plain.push({ type: 'subMessage', value: node.subMessage });\n textTypes.add('plain');\n }\n\n if (node.subMessage.html) {\n textEntry.html = textEntry.html || [];\n textEntry.html.push({ type: 'subMessage', value: node.subMessage });\n textTypes.add('html');\n }\n\n if (subParser.textMap) {\n subParser.textMap.forEach((subTextEntry, subTextNode) => {\n textMap.set(subTextNode, subTextEntry);\n });\n }\n\n for (let attachment of node.subMessage.attachments || []) {\n this.attachments.push(attachment);\n }\n }\n\n // is it text?\n else if (this.isInlineTextNode(node)) {\n let textType = node.contentType.parsed.value.substr(node.contentType.parsed.value.indexOf('/') + 1);\n\n let selectorNode = alternative || node;\n if (!textMap.has(selectorNode)) {\n textMap.set(selectorNode, {});\n }\n\n let textEntry = textMap.get(selectorNode);\n textEntry[textType] = textEntry[textType] || [];\n textEntry[textType].push({ type: 'text', value: node.getTextContent() });\n textTypes.add(textType);\n }\n\n // is it an attachment\n else if (node.content) {\n const filename =\n node.contentDisposition?.parsed?.params?.filename ||\n node.contentType.parsed.params.name ||\n null;\n const attachment = {\n filename: filename ? decodeWords(filename) : null,\n mimeType: node.contentType.parsed.value,\n disposition: node.contentDisposition?.parsed?.value || null\n };\n\n if (related && node.contentId) {\n attachment.related = true;\n }\n\n if (node.contentDescription) {\n attachment.description = node.contentDescription;\n }\n\n if (node.contentId) {\n attachment.contentId = node.contentId;\n }\n\n switch (node.contentType.parsed.value) {\n // Special handling for calendar events\n case 'text/calendar':\n case 'application/ics': {\n if (node.contentType.parsed.params.method) {\n attachment.method = node.contentType.parsed.params.method\n .toString()\n .toUpperCase()\n .trim();\n }\n\n // Enforce into unicode\n const decodedText = node.getTextContent().replace(/\\r?\\n/g, '\\n').replace(/\\n*$/, '\\n');\n attachment.content = textEncoder.encode(decodedText);\n break;\n }\n\n // Regular attachments\n default:\n attachment.content = node.content;\n }\n\n this.attachments.push(attachment);\n }\n } else if (node.contentType.multipart === 'alternative') {\n alternative = node;\n } else if (node.contentType.multipart === 'related') {\n related = node;\n }\n\n for (let childNode of node.childNodes) {\n await walk(childNode, alternative, related);\n }\n };\n\n await walk(this.root, false, false);\n\n textMap.forEach(mapEntry => {\n textTypes.forEach(textType => {\n if (!textContent[textType]) {\n textContent[textType] = [];\n }\n\n if (mapEntry[textType]) {\n mapEntry[textType].forEach(textEntry => {\n switch (textEntry.type) {\n case 'text':\n textContent[textType].push(textEntry.value);\n break;\n\n case 'subMessage':\n {\n switch (textType) {\n case 'html':\n textContent[textType].push(formatHtmlHeader(textEntry.value));\n break;\n case 'plain':\n textContent[textType].push(formatTextHeader(textEntry.value));\n break;\n }\n }\n break;\n }\n });\n } else {\n let alternativeType;\n switch (textType) {\n case 'html':\n alternativeType = 'plain';\n break;\n case 'plain':\n alternativeType = 'html';\n break;\n }\n\n (mapEntry[alternativeType] || []).forEach(textEntry => {\n switch (textEntry.type) {\n case 'text':\n switch (textType) {\n case 'html':\n textContent[textType].push(textToHtml(textEntry.value));\n break;\n case 'plain':\n textContent[textType].push(htmlToText(textEntry.value));\n break;\n }\n break;\n\n case 'subMessage':\n {\n switch (textType) {\n case 'html':\n textContent[textType].push(formatHtmlHeader(textEntry.value));\n break;\n case 'plain':\n textContent[textType].push(formatTextHeader(textEntry.value));\n break;\n }\n }\n break;\n }\n });\n }\n });\n });\n\n Object.keys(textContent).forEach(textType => {\n textContent[textType] = textContent[textType].join('\\n');\n });\n\n this.textContent = textContent;\n }\n\n isInlineTextNode(node) {\n if (node.contentDisposition?.parsed?.value === 'attachment') {\n // no matter the type, this is an attachment\n return false;\n }\n\n switch (node.contentType.parsed?.value) {\n case 'text/html':\n case 'text/plain':\n return true;\n\n case 'text/calendar':\n case 'text/csv':\n default:\n return false;\n }\n }\n\n isInlineMessageRfc822(node) {\n if (node.contentType.parsed?.value !== 'message/rfc822') {\n return false;\n }\n let disposition =\n node.contentDisposition?.parsed?.value || (this.options.rfc822Attachments ? 'attachment' : 'inline');\n return disposition === 'inline';\n }\n\n // Check if this is a specially crafted report email where message/rfc822 content should not be inlined\n forceRfc822Attachments() {\n if (this.options.forceRfc822Attachments) {\n return true;\n }\n\n let forceRfc822Attachments = false;\n let walk = node => {\n if (!node.contentType.multipart) {\n if (\n node.contentType.parsed &&\n ['message/delivery-status', 'message/feedback-report'].includes(node.contentType.parsed.value)\n ) {\n forceRfc822Attachments = true;\n }\n }\n\n for (let childNode of node.childNodes) {\n walk(childNode);\n }\n };\n walk(this.root);\n return forceRfc822Attachments;\n }\n\n async resolveStream(stream) {\n let chunkLen = 0;\n let chunks = [];\n const reader = stream.getReader();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n chunks.push(value);\n chunkLen += value.length;\n }\n\n const result = new Uint8Array(chunkLen);\n let chunkPointer = 0;\n for (let chunk of chunks) {\n result.set(chunk, chunkPointer);\n chunkPointer += chunk.length;\n }\n\n return result;\n }\n\n async parse(buf) {\n if (this.started) {\n throw new Error('Can not reuse parser, create a new PostalMime object');\n }\n this.started = true;\n\n // Check if the input is a readable stream and resolve it into an ArrayBuffer\n if (buf && typeof buf.getReader === 'function') {\n buf = await this.resolveStream(buf);\n }\n\n // Should it throw for an empty value instead of defaulting to an empty ArrayBuffer?\n buf = buf || new ArrayBuffer(0);\n\n // Cast string input to Uint8Array\n if (typeof buf === 'string') {\n buf = textEncoder.encode(buf);\n }\n\n // Cast Blob to ArrayBuffer\n if (buf instanceof Blob || Object.prototype.toString.call(buf) === '[object Blob]') {\n buf = await blobToArrayBuffer(buf);\n }\n\n // Cast Node.js Buffer object or Uint8Array into ArrayBuffer\n if (buf.buffer instanceof ArrayBuffer) {\n buf = new Uint8Array(buf).buffer;\n }\n\n this.buf = buf;\n\n this.av = new Uint8Array(buf);\n this.readPos = 0;\n\n while (this.readPos < this.av.length) {\n const line = this.readLine();\n\n await this.processLine(line.bytes, line.done);\n }\n\n await this.processNodeTree();\n\n const message = {\n headers: this.root.headers\n .map(entry => ({ key: entry.key, originalKey: entry.originalKey, value: entry.value }))\n .reverse()\n };\n\n for (const key of ['from', 'sender']) {\n const addressHeader = this.root.headers.find(line => line.key === key);\n if (addressHeader && addressHeader.value) {\n const addresses = addressParser(addressHeader.value);\n if (addresses && addresses.length) {\n message[key] = addresses[0];\n }\n }\n }\n\n for (const key of ['delivered-to', 'return-path']) {\n const addressHeader = this.root.headers.find(line => line.key === key);\n if (addressHeader && addressHeader.value) {\n const addresses = addressParser(addressHeader.value);\n if (addresses && addresses.length && addresses[0].address) {\n const camelKey = toCamelCase(key);\n message[camelKey] = addresses[0].address;\n }\n }\n }\n\n for (const key of ['to', 'cc', 'bcc', 'reply-to']) {\n const addressHeaders = this.root.headers.filter(line => line.key === key);\n let addresses = [];\n\n addressHeaders\n .filter(entry => entry && entry.value)\n .map(entry => addressParser(entry.value))\n .forEach(parsed => (addresses = addresses.concat(parsed || [])));\n\n if (addresses && addresses.length) {\n const camelKey = toCamelCase(key);\n message[camelKey] = addresses;\n }\n }\n\n for (const key of ['subject', 'message-id', 'in-reply-to', 'references']) {\n const header = this.root.headers.find(line => line.key === key);\n if (header && header.value) {\n const camelKey = toCamelCase(key);\n message[camelKey] = decodeWords(header.value);\n }\n }\n\n let dateHeader = this.root.headers.find(line => line.key === 'date');\n if (dateHeader) {\n let date = new Date(dateHeader.value);\n if (date.toString() === 'Invalid Date') {\n date = dateHeader.value;\n } else {\n // enforce ISO format if seems to be a valid date\n date = date.toISOString();\n }\n message.date = date;\n }\n\n if (this.textContent?.html) {\n message.html = this.textContent.html;\n }\n\n if (this.textContent?.plain) {\n message.text = this.textContent.plain;\n }\n\n message.attachments = this.attachments;\n\n // Expose raw header lines (reversed to match headers array order)\n message.headerLines = (this.root.rawHeaderLines || []).slice().reverse();\n\n switch (this.attachmentEncoding) {\n case 'arraybuffer':\n break;\n\n case 'base64':\n for (let attachment of message.attachments || []) {\n if (attachment?.content) {\n attachment.content = base64ArrayBuffer(attachment.content);\n attachment.encoding = 'base64';\n }\n }\n break;\n\n case 'utf8':\n let attachmentDecoder = new TextDecoder('utf8');\n for (let attachment of message.attachments || []) {\n if (attachment?.content) {\n attachment.content = attachmentDecoder.decode(attachment.content);\n attachment.encoding = 'utf8';\n }\n }\n break;\n\n default:\n throw new Error('Unknown attachment encoding');\n }\n\n return message;\n }\n}\n","import PostalMime from \"postal-mime\";\nimport { Webhook } from \"standardwebhooks\";\n//#region package.json\nvar version = \"6.25.0\";\n//#endregion\n//#region src/common/utils/build-pagination-query.ts\nfunction buildPaginationUrl(base, options) {\n\tconst queryString = buildPaginationQuery(options);\n\treturn queryString ? `${base}?${queryString}` : base;\n}\n/**\n* Builds a query string from pagination options\n* @param options - Pagination options containing limit and either after or before (but not both)\n* @returns Query string (without leading '?') or empty string if no options\n*/\nfunction buildPaginationQuery(options) {\n\tconst searchParams = new URLSearchParams();\n\tif (options.limit !== void 0) searchParams.set(\"limit\", options.limit.toString());\n\tif (\"after\" in options && options.after !== void 0) searchParams.set(\"after\", options.after);\n\tif (\"before\" in options && options.before !== void 0) searchParams.set(\"before\", options.before);\n\treturn searchParams.toString();\n}\n//#endregion\n//#region src/api-keys/api-keys.ts\nvar ApiKeys = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync create(payload, options = {}) {\n\t\treturn await this.resend.post(\"/api-keys\", payload, options);\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/api-keys\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync update(id, payload) {\n\t\treturn await this.resend.patch(`/api-keys/${id}`, payload);\n\t}\n\tasync remove(id) {\n\t\treturn await this.resend.delete(`/api-keys/${id}`);\n\t}\n};\n//#endregion\n//#region src/automation-runs/automation-runs.ts\nvar AutomationRuns = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync get(options) {\n\t\treturn await this.resend.get(`/automations/${options.automationId}/runs/${options.runId}`);\n\t}\n\tasync list(options) {\n\t\tconst queryString = buildPaginationQuery(options);\n\t\tconst searchParams = new URLSearchParams(queryString);\n\t\tif (options.status) {\n\t\t\tconst statusValue = Array.isArray(options.status) ? options.status.join(\",\") : options.status;\n\t\t\tsearchParams.set(\"status\", statusValue);\n\t\t}\n\t\tconst qs = searchParams.toString();\n\t\tconst url = qs ? `/automations/${options.automationId}/runs?${qs}` : `/automations/${options.automationId}/runs`;\n\t\treturn await this.resend.get(url);\n\t}\n};\n//#endregion\n//#region src/common/utils/parse-automation-to-api-options.ts\nfunction parseStepConfig(step) {\n\tswitch (step.type) {\n\t\tcase \"trigger\": return {\n\t\t\tkey: step.key,\n\t\t\ttype: step.type,\n\t\t\tconfig: { event_name: step.config.eventName }\n\t\t};\n\t\tcase \"delay\": return {\n\t\t\tkey: step.key,\n\t\t\ttype: step.type,\n\t\t\tconfig: step.config\n\t\t};\n\t\tcase \"send_email\": return {\n\t\t\tkey: step.key,\n\t\t\ttype: step.type,\n\t\t\tconfig: {\n\t\t\t\ttemplate: step.config.template,\n\t\t\t\tsubject: step.config.subject,\n\t\t\t\tfrom: step.config.from,\n\t\t\t\treply_to: step.config.replyTo\n\t\t\t}\n\t\t};\n\t\tcase \"wait_for_event\": return {\n\t\t\tkey: step.key,\n\t\t\ttype: step.type,\n\t\t\tconfig: {\n\t\t\t\tevent_name: step.config.eventName,\n\t\t\t\ttimeout: step.config.timeout,\n\t\t\t\tfilter_rule: step.config.filterRule\n\t\t\t}\n\t\t};\n\t\tcase \"condition\": return {\n\t\t\tkey: step.key,\n\t\t\ttype: step.type,\n\t\t\tconfig: step.config\n\t\t};\n\t\tcase \"contact_update\": return {\n\t\t\tkey: step.key,\n\t\t\ttype: step.type,\n\t\t\tconfig: {\n\t\t\t\tfirst_name: step.config.firstName,\n\t\t\t\tlast_name: step.config.lastName,\n\t\t\t\tunsubscribed: step.config.unsubscribed,\n\t\t\t\tproperties: step.config.properties\n\t\t\t}\n\t\t};\n\t\tcase \"contact_delete\": return {\n\t\t\tkey: step.key,\n\t\t\ttype: step.type,\n\t\t\tconfig: step.config\n\t\t};\n\t\tcase \"add_to_segment\": return {\n\t\t\tkey: step.key,\n\t\t\ttype: step.type,\n\t\t\tconfig: { segment_id: step.config.segmentId }\n\t\t};\n\t}\n}\nfunction parseConnection(connection) {\n\treturn {\n\t\tfrom: connection.from,\n\t\tto: connection.to,\n\t\ttype: connection.type\n\t};\n}\nfunction parseAutomationToApiOptions(automation) {\n\treturn {\n\t\tname: automation.name,\n\t\tstatus: automation.status,\n\t\tsteps: automation.steps.map(parseStepConfig),\n\t\tconnections: automation.connections.map(parseConnection)\n\t};\n}\nfunction parseEventToApiOptions(event) {\n\treturn {\n\t\tevent: event.event,\n\t\tcontact_id: event.contactId,\n\t\temail: event.email,\n\t\tpayload: event.payload\n\t};\n}\n//#endregion\n//#region src/automations/automations.ts\nvar Automations = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t\tthis.runs = new AutomationRuns(this.resend);\n\t}\n\tasync create(payload) {\n\t\treturn await this.resend.post(\"/automations\", parseAutomationToApiOptions(payload));\n\t}\n\tasync list(options = {}) {\n\t\tconst params = [buildPaginationQuery(options)];\n\t\tif (options.status) params.push(`status=${encodeURIComponent(options.status)}`);\n\t\tconst qs = params.filter(Boolean).join(\"&\");\n\t\tconst url = qs ? `/automations?${qs}` : \"/automations\";\n\t\treturn await this.resend.get(url);\n\t}\n\tasync get(id) {\n\t\treturn await this.resend.get(`/automations/${id}`);\n\t}\n\tasync remove(id) {\n\t\treturn await this.resend.delete(`/automations/${id}`);\n\t}\n\tasync update(id, payload) {\n\t\tconst apiPayload = {};\n\t\tif (payload.name !== void 0) apiPayload.name = payload.name;\n\t\tif (payload.status !== void 0) apiPayload.status = payload.status;\n\t\tif (payload.steps !== void 0) apiPayload.steps = payload.steps.map(parseStepConfig);\n\t\tif (payload.connections !== void 0) apiPayload.connections = payload.connections.map(parseConnection);\n\t\treturn await this.resend.patch(`/automations/${id}`, apiPayload);\n\t}\n\tasync duplicate(id) {\n\t\treturn await this.resend.post(`/automations/${id}/duplicate`);\n\t}\n\tasync stop(id) {\n\t\treturn await this.resend.post(`/automations/${id}/stop`);\n\t}\n};\n//#endregion\n//#region src/common/utils/parse-email-to-api-options.ts\nfunction parseAttachments(attachments) {\n\treturn attachments?.map((attachment) => ({\n\t\tcontent: attachment.content,\n\t\tfilename: attachment.filename,\n\t\tpath: attachment.path,\n\t\tcontent_type: attachment.contentType,\n\t\tcontent_id: attachment.contentId\n\t}));\n}\nfunction parseEmailToApiOptions(email) {\n\treturn {\n\t\tattachments: parseAttachments(email.attachments),\n\t\tbcc: email.bcc,\n\t\tcc: email.cc,\n\t\tfrom: email.from,\n\t\theaders: email.headers,\n\t\thtml: email.html,\n\t\treply_to: email.replyTo,\n\t\tscheduled_at: email.scheduledAt,\n\t\tsubject: email.subject,\n\t\ttags: email.tags,\n\t\ttext: email.text,\n\t\tto: email.to,\n\t\ttemplate: email.template ? {\n\t\t\tid: email.template.id,\n\t\t\tvariables: email.template.variables\n\t\t} : void 0,\n\t\ttopic_id: email.topicId\n\t};\n}\n//#endregion\n//#region src/render.ts\nasync function render(node) {\n\tlet render;\n\ttry {\n\t\t({render} = await import(\"@react-email/render\"));\n\t} catch {\n\t\tthrow new Error(\"Failed to render React component. Make sure to install `@react-email/render` or `@react-email/components`.\");\n\t}\n\treturn render(node);\n}\n//#endregion\n//#region src/batch/batch.ts\nvar Batch$1 = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync send(payload, options) {\n\t\treturn this.create(payload, options);\n\t}\n\tasync create(payload, options) {\n\t\tconst emails = [];\n\t\tfor (const email of payload) {\n\t\t\tif (email.react) {\n\t\t\t\temail.html = await render(email.react);\n\t\t\t\temail.react = void 0;\n\t\t\t}\n\t\t\temails.push(parseEmailToApiOptions(email));\n\t\t}\n\t\treturn await this.resend.post(\"/emails/batch\", emails, {\n\t\t\t...options,\n\t\t\theaders: {\n\t\t\t\t\"x-batch-validation\": options?.batchValidation ?? \"strict\",\n\t\t\t\t...options?.headers\n\t\t\t}\n\t\t});\n\t}\n};\n//#endregion\n//#region src/broadcasts/broadcasts.ts\nvar Broadcasts = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync create(payload, options = {}) {\n\t\tconst html = payload.react ? await render(payload.react) : payload.html;\n\t\treturn await this.resend.post(\"/broadcasts\", {\n\t\t\tname: payload.name,\n\t\t\tsegment_id: payload.segmentId,\n\t\t\taudience_id: payload.audienceId,\n\t\t\tpreview_text: payload.previewText,\n\t\t\tfrom: payload.from,\n\t\t\thtml,\n\t\t\treply_to: payload.replyTo,\n\t\t\tsubject: payload.subject,\n\t\t\ttext: payload.text,\n\t\t\ttopic_id: payload.topicId,\n\t\t\tsend: payload.send,\n\t\t\tscheduled_at: payload.scheduledAt\n\t\t}, options);\n\t}\n\tasync send(id, payload) {\n\t\treturn await this.resend.post(`/broadcasts/${id}/send`, { scheduled_at: payload?.scheduledAt });\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/broadcasts\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync get(id) {\n\t\treturn await this.resend.get(`/broadcasts/${id}`);\n\t}\n\tasync recipients(id, options) {\n\t\tconst url = `/broadcasts/${id}/recipients?${buildRecipientsQuery(options)}`;\n\t\treturn await this.resend.get(url);\n\t}\n\tasync clickedLinks(id, options = {}) {\n\t\tconst url = buildPaginationUrl(`/broadcasts/${id}/clicked-links`, options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync remove(id) {\n\t\treturn await this.resend.delete(`/broadcasts/${id}`);\n\t}\n\tasync cancel(id) {\n\t\treturn await this.resend.post(`/broadcasts/${id}/cancel`);\n\t}\n\tasync update(id, payload) {\n\t\tconst html = payload.react ? await render(payload.react) : payload.html;\n\t\treturn await this.resend.patch(`/broadcasts/${id}`, {\n\t\t\tname: payload.name,\n\t\t\tsegment_id: payload.segmentId,\n\t\t\taudience_id: payload.audienceId,\n\t\t\tfrom: payload.from,\n\t\t\thtml,\n\t\t\ttext: payload.text,\n\t\t\tsubject: payload.subject,\n\t\t\treply_to: payload.replyTo,\n\t\t\tpreview_text: payload.previewText,\n\t\t\ttopic_id: payload.topicId\n\t\t});\n\t}\n};\nfunction buildRecipientsQuery(options) {\n\tconst { type, email, bounceType, ...pagination } = options;\n\tconst searchParams = new URLSearchParams(buildPaginationQuery(pagination));\n\tsearchParams.set(\"type\", type);\n\tif (email !== void 0) searchParams.set(\"email\", email);\n\tif (bounceType !== void 0) searchParams.set(\"bounce_type\", bounceType);\n\treturn searchParams.toString();\n}\n//#endregion\n//#region src/common/utils/parse-contact-properties-to-api-options.ts\nfunction parseContactPropertyFromApi(contactProperty) {\n\treturn {\n\t\tid: contactProperty.id,\n\t\tkey: contactProperty.key,\n\t\tcreatedAt: contactProperty.created_at,\n\t\ttype: contactProperty.type,\n\t\tfallbackValue: contactProperty.fallback_value\n\t};\n}\nfunction parseContactPropertyToApiOptions(contactProperty) {\n\tif (\"key\" in contactProperty) return {\n\t\tkey: contactProperty.key,\n\t\ttype: contactProperty.type,\n\t\tfallback_value: contactProperty.fallbackValue\n\t};\n\treturn { fallback_value: contactProperty.fallbackValue };\n}\n//#endregion\n//#region src/contact-properties/contact-properties.ts\nvar ContactProperties = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync create(options) {\n\t\tconst apiOptions = parseContactPropertyToApiOptions(options);\n\t\treturn await this.resend.post(\"/contact-properties\", apiOptions);\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/contact-properties\", options);\n\t\tconst response = await this.resend.get(url);\n\t\tif (response.data) return {\n\t\t\tdata: {\n\t\t\t\t...response.data,\n\t\t\t\tdata: response.data.data.map((apiContactProperty) => parseContactPropertyFromApi(apiContactProperty))\n\t\t\t},\n\t\t\theaders: response.headers,\n\t\t\terror: null\n\t\t};\n\t\treturn response;\n\t}\n\tasync get(id) {\n\t\tif (!id) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tconst response = await this.resend.get(`/contact-properties/${id}`);\n\t\tif (response.data) return {\n\t\t\tdata: {\n\t\t\t\tobject: \"contact_property\",\n\t\t\t\t...parseContactPropertyFromApi(response.data)\n\t\t\t},\n\t\t\theaders: response.headers,\n\t\t\terror: null\n\t\t};\n\t\treturn response;\n\t}\n\tasync update(payload) {\n\t\tif (!payload.id) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tconst apiOptions = parseContactPropertyToApiOptions(payload);\n\t\treturn await this.resend.patch(`/contact-properties/${payload.id}`, apiOptions);\n\t}\n\tasync remove(id) {\n\t\tif (!id) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\treturn await this.resend.delete(`/contact-properties/${id}`);\n\t}\n};\n//#endregion\n//#region src/contacts/imports/contact-imports.ts\nvar ContactImports = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync create(payload, options = {}) {\n\t\tconst formData = this.buildCreateFormData(payload);\n\t\treturn this.resend.post(\"/contacts/imports\", formData, options);\n\t}\n\tasync list(options = {}) {\n\t\tconst searchParams = new URLSearchParams(buildPaginationQuery(options));\n\t\tif (options.status !== void 0) searchParams.set(\"status\", options.status);\n\t\tconst queryString = searchParams.toString();\n\t\tconst url = queryString ? `/contacts/imports?${queryString}` : \"/contacts/imports\";\n\t\treturn this.resend.get(url);\n\t}\n\tasync get(id) {\n\t\treturn this.resend.get(`/contacts/imports/${id}`);\n\t}\n\tbuildCreateFormData(payload) {\n\t\tconst formData = new FormData();\n\t\tformData.append(\"file\", payload.file);\n\t\tthis.appendField(formData, \"column_map\", this.buildColumnMap(payload.columnMap ?? null));\n\t\tthis.appendField(formData, \"on_conflict\", payload.onConflict ?? null);\n\t\tthis.appendField(formData, \"segments\", payload.segments ?? null);\n\t\tthis.appendField(formData, \"topics\", payload.topics ?? null);\n\t\treturn formData;\n\t}\n\tbuildColumnMap(columnMap) {\n\t\tif (columnMap === null) return null;\n\t\treturn {\n\t\t\temail: columnMap.email,\n\t\t\tfirst_name: columnMap.firstName,\n\t\t\tlast_name: columnMap.lastName,\n\t\t\tunsubscribed: columnMap.unsubscribed,\n\t\t\tproperties: columnMap.properties\n\t\t};\n\t}\n\tappendField(formData, name, value) {\n\t\tif (value === null) return;\n\t\tformData.append(name, typeof value === \"string\" ? value : JSON.stringify(value));\n\t}\n};\n//#endregion\n//#region src/contacts/segments/contact-segments.ts\nvar ContactSegments = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync list(options) {\n\t\tif (!options.contactId && !options.email) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` or `email` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tconst url = buildPaginationUrl(`/contacts/${options.email ? options.email : options.contactId}/segments`, options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync add(options) {\n\t\tif (!options.contactId && !options.email) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` or `email` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tconst identifier = options.email ? options.email : options.contactId;\n\t\treturn this.resend.post(`/contacts/${identifier}/segments/${options.segmentId}`);\n\t}\n\tasync remove(options) {\n\t\tif (!options.contactId && !options.email) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` or `email` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tconst identifier = options.email ? options.email : options.contactId;\n\t\treturn this.resend.delete(`/contacts/${identifier}/segments/${options.segmentId}`);\n\t}\n};\n//#endregion\n//#region src/contacts/topics/contact-topics.ts\nvar ContactTopics = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync update(payload) {\n\t\tif (!payload.id && !payload.email) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` or `email` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tconst identifier = payload.email ? payload.email : payload.id;\n\t\treturn this.resend.patch(`/contacts/${identifier}/topics`, payload.topics);\n\t}\n\tasync list(options) {\n\t\tif (!options.id && !options.email) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` or `email` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tconst url = buildPaginationUrl(`/contacts/${options.email ? options.email : options.id}/topics`, options);\n\t\treturn this.resend.get(url);\n\t}\n};\n//#endregion\n//#region src/contacts/contacts.ts\nvar Contacts = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t\tthis.imports = new ContactImports(this.resend);\n\t\tthis.topics = new ContactTopics(this.resend);\n\t\tthis.segments = new ContactSegments(this.resend);\n\t}\n\tasync create(payload, options = {}) {\n\t\tif (\"audienceId\" in payload) {\n\t\t\tif (\"segments\" in payload || \"topics\" in payload) return {\n\t\t\t\tdata: null,\n\t\t\t\theaders: null,\n\t\t\t\terror: {\n\t\t\t\t\tmessage: \"`audienceId` is deprecated, and cannot be used together with `segments` or `topics`. Use `segments` instead to add one or more segments to the new contact.\",\n\t\t\t\t\tstatusCode: null,\n\t\t\t\t\tname: \"invalid_parameter\"\n\t\t\t\t}\n\t\t\t};\n\t\t\treturn await this.resend.post(`/audiences/${payload.audienceId}/contacts`, {\n\t\t\t\tunsubscribed: payload.unsubscribed,\n\t\t\t\temail: payload.email,\n\t\t\t\tfirst_name: payload.firstName,\n\t\t\t\tlast_name: payload.lastName,\n\t\t\t\tproperties: payload.properties\n\t\t\t}, options);\n\t\t}\n\t\treturn await this.resend.post(\"/contacts\", {\n\t\t\tunsubscribed: payload.unsubscribed,\n\t\t\temail: payload.email,\n\t\t\tfirst_name: payload.firstName,\n\t\t\tlast_name: payload.lastName,\n\t\t\tproperties: payload.properties,\n\t\t\tsegments: payload.segments,\n\t\t\ttopics: payload.topics\n\t\t}, options);\n\t}\n\tasync list(options = {}) {\n\t\tconst segmentId = options.segmentId ?? options.audienceId;\n\t\tif (!segmentId) {\n\t\t\tconst url = buildPaginationUrl(\"/contacts\", options);\n\t\t\treturn await this.resend.get(url);\n\t\t}\n\t\tconst url = buildPaginationUrl(`/segments/${segmentId}/contacts`, options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync get(options) {\n\t\tif (typeof options === \"string\") return this.resend.get(`/contacts/${options}`);\n\t\tif (!options.id && !options.email) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` or `email` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tif (!options.audienceId) return this.resend.get(`/contacts/${options?.email ? options?.email : options?.id}`);\n\t\treturn this.resend.get(`/audiences/${options.audienceId}/contacts/${options?.email ? options?.email : options?.id}`);\n\t}\n\tasync update(options) {\n\t\tif (!options.id && !options.email) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` or `email` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tif (!options.audienceId) return await this.resend.patch(`/contacts/${options?.email ? options?.email : options?.id}`, {\n\t\t\tunsubscribed: options.unsubscribed,\n\t\t\tfirst_name: options.firstName,\n\t\t\tlast_name: options.lastName,\n\t\t\tproperties: options.properties\n\t\t});\n\t\treturn await this.resend.patch(`/audiences/${options.audienceId}/contacts/${options?.email ? options?.email : options?.id}`, {\n\t\t\tunsubscribed: options.unsubscribed,\n\t\t\tfirst_name: options.firstName,\n\t\t\tlast_name: options.lastName,\n\t\t\tproperties: options.properties\n\t\t});\n\t}\n\tasync remove(payload) {\n\t\tif (typeof payload === \"string\") return this.resend.delete(`/contacts/${payload}`);\n\t\tif (!payload.id && !payload.email) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` or `email` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\tif (!payload.audienceId) return this.resend.delete(`/contacts/${payload?.email ? payload?.email : payload?.id}`);\n\t\treturn this.resend.delete(`/audiences/${payload.audienceId}/contacts/${payload?.email ? payload?.email : payload?.id}`);\n\t}\n};\n//#endregion\n//#region src/common/utils/parse-domain-to-api-options.ts\nfunction parseDomainToApiOptions(domain) {\n\treturn {\n\t\tname: domain.name,\n\t\tregion: domain.region,\n\t\tcustom_return_path: domain.customReturnPath,\n\t\tcapabilities: domain.capabilities,\n\t\topen_tracking: domain.openTracking,\n\t\tclick_tracking: domain.clickTracking,\n\t\ttls: domain.tls,\n\t\ttracking_subdomain: domain.trackingSubdomain\n\t};\n}\n//#endregion\n//#region src/domains/claims/domain-claims.ts\nvar DomainClaims = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync create(payload, options = {}) {\n\t\treturn await this.resend.post(\"/domains/claim\", {\n\t\t\tname: payload.name,\n\t\t\tregion: payload.region,\n\t\t\tcustom_return_path: payload.customReturnPath,\n\t\t\topen_tracking: payload.openTracking,\n\t\t\tclick_tracking: payload.clickTracking,\n\t\t\ttracking_subdomain: payload.trackingSubdomain\n\t\t}, options);\n\t}\n\tasync get(domainId) {\n\t\treturn await this.resend.get(`/domains/${domainId}/claim`);\n\t}\n\tasync verify(domainId) {\n\t\treturn await this.resend.post(`/domains/${domainId}/claim/verify`);\n\t}\n};\n//#endregion\n//#region src/domains/domains.ts\nvar Domains = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t\tthis.claims = new DomainClaims(this.resend);\n\t}\n\tasync create(payload, options = {}) {\n\t\treturn await this.resend.post(\"/domains\", parseDomainToApiOptions(payload), options);\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/domains\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync get(id) {\n\t\treturn await this.resend.get(`/domains/${id}`);\n\t}\n\tasync update(payload) {\n\t\treturn await this.resend.patch(`/domains/${payload.id}`, {\n\t\t\tclick_tracking: payload.clickTracking,\n\t\t\topen_tracking: payload.openTracking,\n\t\t\ttls: payload.tls,\n\t\t\tcapabilities: payload.capabilities,\n\t\t\ttracking_subdomain: payload.trackingSubdomain\n\t\t});\n\t}\n\tasync remove(id) {\n\t\treturn await this.resend.delete(`/domains/${id}`);\n\t}\n\tasync verify(id) {\n\t\treturn await this.resend.post(`/domains/${id}/verify`);\n\t}\n};\n//#endregion\n//#region src/emails/attachments/attachments.ts\nvar Attachments$1 = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync get(options) {\n\t\tconst { emailId, id } = options;\n\t\treturn await this.resend.get(`/emails/${emailId}/attachments/${id}`);\n\t}\n\tasync list(options) {\n\t\tconst { emailId } = options;\n\t\tconst url = buildPaginationUrl(`/emails/${emailId}/attachments`, options);\n\t\treturn await this.resend.get(url);\n\t}\n};\n//#endregion\n//#region src/emails/receiving/attachments/attachments.ts\nvar Attachments = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync get(options) {\n\t\tconst { emailId, id } = options;\n\t\treturn await this.resend.get(`/emails/receiving/${emailId}/attachments/${id}`);\n\t}\n\tasync list(options) {\n\t\tconst { emailId } = options;\n\t\tconst url = buildPaginationUrl(`/emails/receiving/${emailId}/attachments`, options);\n\t\treturn await this.resend.get(url);\n\t}\n};\n//#endregion\n//#region src/emails/receiving/receiving.ts\nvar Receiving = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t\tthis.attachments = new Attachments(resend);\n\t}\n\tasync get(id, options = {}) {\n\t\tconst searchParams = new URLSearchParams();\n\t\tif (options.html_format !== void 0) searchParams.set(\"html_format\", options.html_format);\n\t\tconst queryString = searchParams.toString();\n\t\tconst path = queryString ? `/emails/receiving/${id}?${queryString}` : `/emails/receiving/${id}`;\n\t\treturn await this.resend.get(path);\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/emails/receiving\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync forward(options, requestOptions = {}) {\n\t\tconst { emailId, to, from } = options;\n\t\tconst passthrough = options.passthrough !== false;\n\t\tconst emailResponse = await this.get(emailId);\n\t\tif (emailResponse.error) return {\n\t\t\tdata: null,\n\t\t\terror: emailResponse.error,\n\t\t\theaders: emailResponse.headers\n\t\t};\n\t\tconst email = emailResponse.data;\n\t\tconst originalSubject = email.subject || \"(no subject)\";\n\t\tif (passthrough) return this.forwardPassthrough(email, {\n\t\t\tto,\n\t\t\tfrom,\n\t\t\tsubject: originalSubject\n\t\t}, requestOptions);\n\t\tconst forwardSubject = originalSubject.startsWith(\"Fwd:\") ? originalSubject : `Fwd: ${originalSubject}`;\n\t\treturn this.forwardWrapped(email, {\n\t\t\tto,\n\t\t\tfrom,\n\t\t\tsubject: forwardSubject,\n\t\t\ttext: \"text\" in options ? options.text : void 0,\n\t\t\thtml: \"html\" in options ? options.html : void 0\n\t\t}, requestOptions);\n\t}\n\tasync forwardPassthrough(email, options, requestOptions) {\n\t\tconst { to, from, subject } = options;\n\t\tif (!email.raw?.download_url) return {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\tname: \"validation_error\",\n\t\t\t\tmessage: \"Raw email content is not available for this email\",\n\t\t\t\tstatusCode: 400\n\t\t\t},\n\t\t\theaders: null\n\t\t};\n\t\tconst rawResponse = await fetch(email.raw.download_url);\n\t\tif (!rawResponse.ok) return {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\tname: \"application_error\",\n\t\t\t\tmessage: \"Failed to download raw email content\",\n\t\t\t\tstatusCode: rawResponse.status\n\t\t\t},\n\t\t\theaders: null\n\t\t};\n\t\tconst rawEmailContent = await rawResponse.text();\n\t\tconst parsed = await PostalMime.parse(rawEmailContent, { attachmentEncoding: \"base64\" });\n\t\tconst attachments = parsed.attachments.map((attachment) => {\n\t\t\tconst contentId = attachment.contentId ? attachment.contentId.replace(/^<|>$/g, \"\") : void 0;\n\t\t\treturn {\n\t\t\t\tfilename: attachment.filename,\n\t\t\t\tcontent: attachment.content.toString(),\n\t\t\t\tcontent_type: attachment.mimeType,\n\t\t\t\tcontent_id: contentId || void 0\n\t\t\t};\n\t\t});\n\t\treturn await this.resend.post(\"/emails\", {\n\t\t\tfrom,\n\t\t\tto,\n\t\t\tsubject,\n\t\t\ttext: parsed.text || void 0,\n\t\t\thtml: parsed.html || void 0,\n\t\t\tattachments: attachments.length > 0 ? attachments : void 0\n\t\t}, requestOptions);\n\t}\n\tasync forwardWrapped(email, options, requestOptions) {\n\t\tconst { to, from, subject, text, html } = options;\n\t\tif (!email.raw?.download_url) return {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\tname: \"validation_error\",\n\t\t\t\tmessage: \"Raw email content is not available for this email\",\n\t\t\t\tstatusCode: 400\n\t\t\t},\n\t\t\theaders: null\n\t\t};\n\t\tconst rawResponse = await fetch(email.raw.download_url);\n\t\tif (!rawResponse.ok) return {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\tname: \"application_error\",\n\t\t\t\tmessage: \"Failed to download raw email content\",\n\t\t\t\tstatusCode: rawResponse.status\n\t\t\t},\n\t\t\theaders: null\n\t\t};\n\t\tconst rawEmailContent = await rawResponse.text();\n\t\treturn await this.resend.post(\"/emails\", {\n\t\t\tfrom,\n\t\t\tto,\n\t\t\tsubject,\n\t\t\ttext,\n\t\t\thtml,\n\t\t\tattachments: [{\n\t\t\t\tfilename: \"forwarded_message.eml\",\n\t\t\t\tcontent: Buffer.from(rawEmailContent).toString(\"base64\"),\n\t\t\t\tcontent_type: \"message/rfc822\"\n\t\t\t}]\n\t\t}, requestOptions);\n\t}\n};\n//#endregion\n//#region src/emails/emails.ts\nvar Emails = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t\tthis.attachments = new Attachments$1(resend);\n\t\tthis.receiving = new Receiving(resend);\n\t}\n\tasync send(payload, options = {}) {\n\t\treturn this.create(payload, options);\n\t}\n\tasync create(payload, options = {}) {\n\t\tconst body = { ...payload };\n\t\tif (payload.react) body.html = await render(payload.react);\n\t\treturn await this.resend.post(\"/emails\", parseEmailToApiOptions(body), options);\n\t}\n\tasync get(id) {\n\t\treturn await this.resend.get(`/emails/${id}`);\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/emails\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync update(payload) {\n\t\treturn await this.resend.patch(`/emails/${payload.id}`, { scheduled_at: payload.scheduledAt });\n\t}\n\tasync cancel(id) {\n\t\treturn await this.resend.post(`/emails/${id}/cancel`);\n\t}\n\tasync share(id, payload) {\n\t\treturn await this.resend.post(`/emails/${id}/share`, { expires_in: payload?.expiresIn });\n\t}\n\tasync metrics(options = {}) {\n\t\tconst queryString = buildMetricsQuery(options);\n\t\tconst url = queryString ? `/emails/metrics?${queryString}` : \"/emails/metrics\";\n\t\treturn await this.resend.get(url);\n\t}\n};\nfunction buildMetricsQuery(options) {\n\tconst params = {\n\t\tstart_date: options.startDate,\n\t\tend_date: options.endDate,\n\t\ttimezone: options.timezone,\n\t\tgranularity: options.granularity,\n\t\tmetrics: options.metrics?.join(\",\"),\n\t\tdimensions: options.dimensions?.join(\",\"),\n\t\tdomain_id: options.domainId?.join(\",\"),\n\t\temail_id: options.emailId?.join(\",\"),\n\t\tbroadcast_id: options.broadcastId?.join(\",\")\n\t};\n\tconst searchParams = new URLSearchParams();\n\tfor (const [key, value] of Object.entries(params)) if (value !== void 0 && value !== \"\") searchParams.set(key, value);\n\treturn searchParams.toString();\n}\n//#endregion\n//#region src/events/events.ts\nvar Events$1 = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync send(payload) {\n\t\treturn await this.resend.post(\"/events/send\", parseEventToApiOptions(payload));\n\t}\n\tasync create(payload) {\n\t\treturn await this.resend.post(\"/events\", payload);\n\t}\n\tasync get(identifier) {\n\t\treturn await this.resend.get(`/events/${encodeURIComponent(identifier)}`);\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/events\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync update(identifier, payload) {\n\t\treturn await this.resend.patch(`/events/${encodeURIComponent(identifier)}`, payload);\n\t}\n\tasync remove(identifier) {\n\t\treturn await this.resend.delete(`/events/${encodeURIComponent(identifier)}`);\n\t}\n};\n//#endregion\n//#region src/logs/logs.ts\nvar Logs = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/logs\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync get(id) {\n\t\treturn await this.resend.get(`/logs/${id}`);\n\t}\n};\n//#endregion\n//#region src/oauth-grants/oauth-grants.ts\nvar OAuthGrants = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/oauth/grants\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync revoke(id) {\n\t\treturn await this.resend.delete(`/oauth/grants/${id}`);\n\t}\n};\n//#endregion\n//#region src/segments/segments.ts\nvar Segments = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync create(payload, options = {}) {\n\t\treturn await this.resend.post(\"/segments\", payload, options);\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/segments\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync get(id) {\n\t\treturn await this.resend.get(`/segments/${id}`);\n\t}\n\tasync update(id, payload) {\n\t\treturn await this.resend.patch(`/segments/${id}`, payload);\n\t}\n\tasync remove(id) {\n\t\treturn await this.resend.delete(`/segments/${id}`);\n\t}\n};\n//#endregion\n//#region src/suppressions/batch/batch.ts\nvar Batch = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync add(options) {\n\t\treturn this.resend.post(\"/suppressions/batch/add\", options);\n\t}\n\tasync remove(options) {\n\t\treturn this.resend.post(\"/suppressions/batch/remove\", options);\n\t}\n};\n//#endregion\n//#region src/suppressions/suppressions.ts\nconst missingIdentifierError = () => ({\n\tdata: null,\n\theaders: null,\n\terror: {\n\t\tmessage: \"Missing `id` field.\",\n\t\tstatusCode: null,\n\t\tname: \"missing_required_field\"\n\t}\n});\nvar Suppressions = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t\tthis.batch = new Batch(resend);\n\t}\n\tasync add(options) {\n\t\treturn this.resend.post(\"/suppressions\", options);\n\t}\n\tasync list(options = {}) {\n\t\tconst queryString = buildSuppressionsQuery(options);\n\t\tconst url = queryString ? `/suppressions?${queryString}` : \"/suppressions\";\n\t\treturn this.resend.get(url);\n\t}\n\tasync get(idOrEmail) {\n\t\tif (!idOrEmail) return missingIdentifierError();\n\t\treturn this.resend.get(`/suppressions/${encodeURIComponent(idOrEmail)}`);\n\t}\n\tasync remove(idOrEmail) {\n\t\tif (!idOrEmail) return missingIdentifierError();\n\t\treturn this.resend.delete(`/suppressions/${encodeURIComponent(idOrEmail)}`);\n\t}\n};\nfunction buildSuppressionsQuery(options) {\n\tconst { origin, ...pagination } = options;\n\tconst searchParams = new URLSearchParams(buildPaginationQuery(pagination));\n\tif (origin) searchParams.set(\"origin\", origin);\n\treturn searchParams.toString();\n}\n//#endregion\n//#region src/common/utils/get-pagination-query-properties.ts\nfunction getPaginationQueryProperties(options = {}) {\n\tconst query = new URLSearchParams();\n\tif (options.before) query.set(\"before\", options.before);\n\tif (options.after) query.set(\"after\", options.after);\n\tif (options.limit) query.set(\"limit\", options.limit.toString());\n\treturn query.size > 0 ? `?${query.toString()}` : \"\";\n}\n//#endregion\n//#region src/common/utils/parse-template-to-api-options.ts\nfunction parseVariables(variables) {\n\treturn variables?.map((variable) => ({\n\t\tkey: variable.key,\n\t\ttype: variable.type,\n\t\tfallback_value: variable.fallbackValue\n\t}));\n}\nfunction parseTemplateToApiOptions(template) {\n\treturn {\n\t\tname: \"name\" in template ? template.name : void 0,\n\t\tsubject: template.subject,\n\t\thtml: template.html,\n\t\ttext: template.text,\n\t\talias: template.alias,\n\t\tfrom: template.from,\n\t\treply_to: template.replyTo,\n\t\tvariables: parseVariables(template.variables)\n\t};\n}\n//#endregion\n//#region src/templates/chainable-template-result.ts\nvar ChainableTemplateResult = class {\n\tconstructor(promise, publishFn) {\n\t\tthis.promise = promise;\n\t\tthis.publishFn = publishFn;\n\t}\n\tthen(onfulfilled, onrejected) {\n\t\treturn this.promise.then(onfulfilled, onrejected);\n\t}\n\tasync publish() {\n\t\tconst { data, error } = await this.promise;\n\t\tif (error) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror\n\t\t};\n\t\treturn this.publishFn(data.id);\n\t}\n};\n//#endregion\n//#region src/templates/templates.ts\nvar Templates = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tcreate(payload) {\n\t\treturn new ChainableTemplateResult(this.performCreate(payload), this.publish.bind(this));\n\t}\n\tasync performCreate(payload) {\n\t\tconst body = { ...payload };\n\t\tif (payload.react) body.html = await render(payload.react);\n\t\treturn this.resend.post(\"/templates\", parseTemplateToApiOptions(body));\n\t}\n\tasync remove(identifier) {\n\t\treturn await this.resend.delete(`/templates/${identifier}`);\n\t}\n\tasync get(identifier) {\n\t\treturn await this.resend.get(`/templates/${identifier}`);\n\t}\n\tasync list(options = {}) {\n\t\treturn this.resend.get(`/templates${getPaginationQueryProperties(options)}`);\n\t}\n\tduplicate(identifier) {\n\t\treturn new ChainableTemplateResult(this.resend.post(`/templates/${identifier}/duplicate`), this.publish.bind(this));\n\t}\n\tasync publish(identifier) {\n\t\treturn await this.resend.post(`/templates/${identifier}/publish`);\n\t}\n\tasync update(identifier, payload) {\n\t\treturn await this.resend.patch(`/templates/${identifier}`, parseTemplateToApiOptions(payload));\n\t}\n};\n//#endregion\n//#region src/topics/topics.ts\nvar Topics = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync create(payload) {\n\t\tconst { defaultSubscription, ...body } = payload;\n\t\treturn await this.resend.post(\"/topics\", {\n\t\t\t...body,\n\t\t\tdefault_subscription: defaultSubscription\n\t\t});\n\t}\n\tasync list() {\n\t\treturn await this.resend.get(\"/topics\");\n\t}\n\tasync get(id) {\n\t\tif (!id) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\treturn await this.resend.get(`/topics/${id}`);\n\t}\n\tasync update(payload) {\n\t\tif (!payload.id) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\treturn await this.resend.patch(`/topics/${payload.id}`, payload);\n\t}\n\tasync remove(id) {\n\t\tif (!id) return {\n\t\t\tdata: null,\n\t\t\theaders: null,\n\t\t\terror: {\n\t\t\t\tmessage: \"Missing `id` field.\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tname: \"missing_required_field\"\n\t\t\t}\n\t\t};\n\t\treturn await this.resend.delete(`/topics/${id}`);\n\t}\n};\n//#endregion\n//#region src/webhooks/events/attempts/attempts.ts\nvar Attempts = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t}\n\tasync list(options) {\n\t\tconst { webhookId, eventId } = options;\n\t\tconst url = buildPaginationUrl(`/webhooks/${webhookId}/events/${eventId}/attempts`, options);\n\t\treturn await this.resend.get(url);\n\t}\n};\n//#endregion\n//#region src/webhooks/events/events.ts\nvar Events = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t\tthis.attempts = new Attempts(resend);\n\t}\n\tasync list(options) {\n\t\tconst { webhookId } = options;\n\t\tconst url = buildPaginationUrl(`/webhooks/${webhookId}/events`, options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync get(options) {\n\t\tconst { webhookId, eventId } = options;\n\t\treturn await this.resend.get(`/webhooks/${webhookId}/events/${eventId}`);\n\t}\n};\n//#endregion\n//#region src/webhooks/webhooks.ts\nvar Webhooks = class {\n\tconstructor(resend) {\n\t\tthis.resend = resend;\n\t\tthis.events = new Events(resend);\n\t}\n\tasync create(payload, options = {}) {\n\t\treturn await this.resend.post(\"/webhooks\", payload, options);\n\t}\n\tasync get(id) {\n\t\treturn await this.resend.get(`/webhooks/${id}`);\n\t}\n\tasync list(options = {}) {\n\t\tconst url = buildPaginationUrl(\"/webhooks\", options);\n\t\treturn await this.resend.get(url);\n\t}\n\tasync update(id, payload) {\n\t\treturn await this.resend.patch(`/webhooks/${id}`, payload);\n\t}\n\tasync remove(id) {\n\t\treturn await this.resend.delete(`/webhooks/${id}`);\n\t}\n\tverify(payload) {\n\t\treturn new Webhook(payload.webhookSecret).verify(payload.payload, {\n\t\t\t\"webhook-id\": payload.headers.id,\n\t\t\t\"webhook-timestamp\": payload.headers.timestamp,\n\t\t\t\"webhook-signature\": payload.headers.signature\n\t\t});\n\t}\n};\n//#endregion\n//#region src/resend.ts\nconst defaultBaseUrl = \"https://api.resend.com\";\nconst defaultUserAgent = `resend-node:${version}`;\nfunction getDefaultBaseUrl() {\n\treturn typeof process !== \"undefined\" && process.env ? process.env.RESEND_BASE_URL || defaultBaseUrl : defaultBaseUrl;\n}\nfunction getDefaultUserAgent() {\n\treturn typeof process !== \"undefined\" && process.env ? process.env.RESEND_USER_AGENT || defaultUserAgent : defaultUserAgent;\n}\nvar Resend = class {\n\tconstructor(key, options) {\n\t\tthis.key = key;\n\t\tthis.segments = new Segments(this);\n\t\tthis.apiKeys = new ApiKeys(this);\n\t\tthis.audiences = this.segments;\n\t\tthis.automations = new Automations(this);\n\t\tthis.batch = new Batch$1(this);\n\t\tthis.broadcasts = new Broadcasts(this);\n\t\tthis.contactProperties = new ContactProperties(this);\n\t\tthis.contacts = new Contacts(this);\n\t\tthis.domains = new Domains(this);\n\t\tthis.emails = new Emails(this);\n\t\tthis.events = new Events$1(this);\n\t\tthis.logs = new Logs(this);\n\t\tthis.oauthGrants = new OAuthGrants(this);\n\t\tthis.suppressions = new Suppressions(this);\n\t\tthis.templates = new Templates(this);\n\t\tthis.topics = new Topics(this);\n\t\tthis.webhooks = new Webhooks(this);\n\t\tif (!key) {\n\t\t\tif (typeof process !== \"undefined\" && process.env) this.key = process.env.RESEND_API_KEY;\n\t\t\tif (!this.key) throw new Error(\"Missing API key. Pass it to the constructor `new Resend(\\\"re_123\\\")`\");\n\t\t}\n\t\tthis.baseUrl = options?.baseUrl ?? getDefaultBaseUrl();\n\t\tthis.userAgent = options?.userAgent ?? getDefaultUserAgent();\n\t\tthis.headers = new Headers({\n\t\t\tAuthorization: `Bearer ${this.key}`,\n\t\t\t\"User-Agent\": this.userAgent,\n\t\t\t\"Content-Type\": \"application/json\"\n\t\t});\n\t}\n\tlogError(error, path, status) {\n\t\tif (typeof process !== \"undefined\" && process.env && process.env.NODE_ENV !== \"production\") console.error(\"[Resend API Error]:\", {\n\t\t\t...status !== void 0 && { status },\n\t\t\terror,\n\t\t\tpath\n\t\t});\n\t}\n\tasync fetchRequest(path, options = {}) {\n\t\ttry {\n\t\t\tconst response = await fetch(`${this.baseUrl}${path}`, options);\n\t\t\tif (!response.ok) try {\n\t\t\t\tconst rawError = await response.text();\n\t\t\t\tconst parsedError = JSON.parse(rawError);\n\t\t\t\tthis.logError(parsedError, path, response.status);\n\t\t\t\treturn {\n\t\t\t\t\tdata: null,\n\t\t\t\t\terror: parsedError,\n\t\t\t\t\theaders: Object.fromEntries(response.headers.entries())\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof SyntaxError) {\n\t\t\t\t\tconst error = {\n\t\t\t\t\t\tname: \"application_error\",\n\t\t\t\t\t\tstatusCode: response.status,\n\t\t\t\t\t\tmessage: \"Internal server error. We are unable to process your request right now, please try again later.\"\n\t\t\t\t\t};\n\t\t\t\t\tthis.logError(error, path, response.status);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdata: null,\n\t\t\t\t\t\terror,\n\t\t\t\t\t\theaders: Object.fromEntries(response.headers.entries())\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst error = {\n\t\t\t\t\tmessage: response.statusText,\n\t\t\t\t\tstatusCode: response.status,\n\t\t\t\t\tname: \"application_error\"\n\t\t\t\t};\n\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\tconst errorWithMessage = {\n\t\t\t\t\t\t...error,\n\t\t\t\t\t\tmessage: err.message\n\t\t\t\t\t};\n\t\t\t\t\tthis.logError(errorWithMessage, path, response.status);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdata: null,\n\t\t\t\t\t\terror: errorWithMessage,\n\t\t\t\t\t\theaders: Object.fromEntries(response.headers.entries())\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthis.logError(error, path, response.status);\n\t\t\t\treturn {\n\t\t\t\t\tdata: null,\n\t\t\t\t\terror,\n\t\t\t\t\theaders: Object.fromEntries(response.headers.entries())\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: await response.json(),\n\t\t\t\terror: null,\n\t\t\t\theaders: Object.fromEntries(response.headers.entries())\n\t\t\t};\n\t\t} catch {\n\t\t\tconst error = {\n\t\t\t\tname: \"application_error\",\n\t\t\t\tstatusCode: null,\n\t\t\t\tmessage: \"Unable to fetch data. The request could not be resolved.\"\n\t\t\t};\n\t\t\tthis.logError(error, path);\n\t\t\treturn {\n\t\t\t\tdata: null,\n\t\t\t\terror,\n\t\t\t\theaders: null\n\t\t\t};\n\t\t}\n\t}\n\tasync post(path, entity, options = {}) {\n\t\tconst headers = new Headers(this.headers);\n\t\tconst isFormData = typeof FormData !== \"undefined\" && entity instanceof FormData;\n\t\tif (isFormData) headers.delete(\"Content-Type\");\n\t\tif (options.headers) for (const [key, value] of new Headers(options.headers).entries()) headers.set(key, value);\n\t\tif (options.idempotencyKey) headers.set(\"Idempotency-Key\", options.idempotencyKey);\n\t\tconst requestOptions = {\n\t\t\tmethod: \"POST\",\n\t\t\tbody: isFormData ? entity : JSON.stringify(entity),\n\t\t\t...options,\n\t\t\theaders\n\t\t};\n\t\treturn this.fetchRequest(path, requestOptions);\n\t}\n\tasync get(path, options = {}) {\n\t\tconst headers = new Headers(this.headers);\n\t\tif (options.headers) for (const [key, value] of new Headers(options.headers).entries()) headers.set(key, value);\n\t\tconst requestOptions = {\n\t\t\tmethod: \"GET\",\n\t\t\t...options,\n\t\t\theaders\n\t\t};\n\t\treturn this.fetchRequest(path, requestOptions);\n\t}\n\tasync put(path, entity, options = {}) {\n\t\tconst headers = new Headers(this.headers);\n\t\tif (options.headers) for (const [key, value] of new Headers(options.headers).entries()) headers.set(key, value);\n\t\tconst requestOptions = {\n\t\t\tmethod: \"PUT\",\n\t\t\tbody: JSON.stringify(entity),\n\t\t\t...options,\n\t\t\theaders\n\t\t};\n\t\treturn this.fetchRequest(path, requestOptions);\n\t}\n\tasync patch(path, entity, options = {}) {\n\t\tconst headers = new Headers(this.headers);\n\t\tif (options.headers) for (const [key, value] of new Headers(options.headers).entries()) headers.set(key, value);\n\t\tconst requestOptions = {\n\t\t\tmethod: \"PATCH\",\n\t\t\tbody: JSON.stringify(entity),\n\t\t\t...options,\n\t\t\theaders\n\t\t};\n\t\treturn this.fetchRequest(path, requestOptions);\n\t}\n\tasync delete(path, query, options = {}) {\n\t\tconst headers = new Headers(this.headers);\n\t\tif (options.headers) for (const [key, value] of new Headers(options.headers).entries()) headers.set(key, value);\n\t\tconst requestOptions = {\n\t\t\tmethod: \"DELETE\",\n\t\t\tbody: query === void 0 ? void 0 : JSON.stringify(query),\n\t\t\t...options,\n\t\t\theaders\n\t\t};\n\t\treturn this.fetchRequest(path, requestOptions);\n\t}\n};\n//#endregion\nexport { Resend };\n","/**\n * Tiny HTML email toolkit. No images, no external CSS, no tracking: inline styles only,\n * max-width 600px, system fonts, readable in light and dark mode. Everything that reaches\n * `layout()` as `bodyHtml` must already be escaped with `escapeHtml()`.\n */\n\nconst ESCAPES: Record<string, string> = {\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n '\"': \""\",\n \"'\": \"'\",\n};\n\n/** Escape a value for safe interpolation into HTML text or attribute context. */\nexport function escapeHtml(value: string | number | boolean | null | undefined): string {\n if (value === null || value === undefined) return \"\";\n return String(value).replace(/[&<>\"']/g, (ch) => ESCAPES[ch] ?? ch);\n}\n\n/** Escape a URL for use in an href. Non http(s)/mailto schemes render as \"#\". */\nexport function safeUrl(url: string): string {\n const trimmed = url.trim();\n if (!/^(https?:|mailto:)/i.test(trimmed)) return \"#\";\n return escapeHtml(trimmed);\n}\n\n// ---------------------------------------------------------------------------\n// Palette + typography. Inline everywhere; a small <style> block adds dark-mode overrides\n// for clients that honour it (Apple Mail, iOS Mail, Outlook for Mac, most webmails).\n// ---------------------------------------------------------------------------\n\nexport const palette = {\n bg: \"#f4f5f7\",\n card: \"#ffffff\",\n text: \"#111827\",\n muted: \"#6b7280\",\n border: \"#e5e7eb\",\n link: \"#2563eb\",\n codeBg: \"#f3f4f6\",\n red: \"#b91c1c\",\n redBg: \"#fef2f2\",\n green: \"#15803d\",\n greenBg: \"#f0fdf4\",\n amber: \"#b45309\",\n amberBg: \"#fffbeb\",\n gray: \"#374151\",\n grayBg: \"#f3f4f6\",\n} as const;\n\nexport const fontStack =\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\";\nexport const monoStack =\n \"ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace\";\n\nconst baseText = `font-family:${fontStack};font-size:15px;line-height:1.55;color:${palette.text};`;\n\n// ---------------------------------------------------------------------------\n// Building blocks. Every helper escapes its *text* arguments; `*Html` arguments are trusted.\n// ---------------------------------------------------------------------------\n\nexport function h1(text: string): string {\n return `<h1 style=\"${baseText}font-size:22px;line-height:1.3;font-weight:700;margin:0 0 12px 0;\">${escapeHtml(text)}</h1>`;\n}\n\nexport function h2(text: string): string {\n return `<h2 style=\"${baseText}font-size:16px;line-height:1.3;font-weight:700;margin:24px 0 8px 0;\">${escapeHtml(text)}</h2>`;\n}\n\nexport function p(text: string): string {\n return pHtml(escapeHtml(text));\n}\n\nexport function pHtml(innerHtml: string): string {\n return `<p style=\"${baseText}margin:0 0 12px 0;\">${innerHtml}</p>`;\n}\n\nexport function muted(text: string): string {\n return `<p style=\"${baseText}font-size:13px;color:${palette.muted};margin:0 0 12px 0;\">${escapeHtml(text)}</p>`;\n}\n\nexport function link(href: string, text: string): string {\n return `<a href=\"${safeUrl(href)}\" style=\"color:${palette.link};text-decoration:underline;\">${escapeHtml(text)}</a>`;\n}\n\nexport function button(href: string, label: string): string {\n return (\n `<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin:16px 0;\"><tr><td style=\"border-radius:6px;background:${palette.text};\">` +\n `<a href=\"${safeUrl(href)}\" style=\"display:inline-block;padding:10px 18px;font-family:${fontStack};font-size:14px;font-weight:600;color:#ffffff;text-decoration:none;border-radius:6px;\">${escapeHtml(label)}</a>` +\n `</td></tr></table>`\n );\n}\n\n/** Preformatted block (transcripts, diffs). Preserves whitespace, wraps long lines. */\nexport function pre(text: string, opts: { maxChars?: number } = {}): string {\n const max = opts.maxChars ?? 4000;\n const body =\n text.length > max ? `${text.slice(0, max)}\\n... (${text.length - max} more chars)` : text;\n return `<pre style=\"font-family:${monoStack};font-size:13px;line-height:1.45;color:${palette.text};background:${palette.codeBg};border:1px solid ${palette.border};border-radius:6px;padding:12px;margin:0 0 12px 0;white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere;\">${escapeHtml(body)}</pre>`;\n}\n\nexport function code(text: string): string {\n return `<code style=\"font-family:${monoStack};font-size:13px;background:${palette.codeBg};border-radius:4px;padding:1px 5px;\">${escapeHtml(text)}</code>`;\n}\n\nexport type Tone = \"red\" | \"green\" | \"amber\" | \"gray\";\n\nfunction toneColors(tone: Tone): { fg: string; bg: string } {\n switch (tone) {\n case \"red\":\n return { fg: palette.red, bg: palette.redBg };\n case \"green\":\n return { fg: palette.green, bg: palette.greenBg };\n case \"amber\":\n return { fg: palette.amber, bg: palette.amberBg };\n case \"gray\":\n return { fg: palette.gray, bg: palette.grayBg };\n }\n}\n\n/** Small inline status pill. */\nexport function pill(text: string, tone: Tone): string {\n const c = toneColors(tone);\n return `<span style=\"display:inline-block;font-family:${fontStack};font-size:12px;font-weight:600;letter-spacing:0.02em;color:${c.fg};background:${c.bg};border:1px solid ${c.fg};border-radius:999px;padding:1px 8px;white-space:nowrap;\">${escapeHtml(text)}</span>`;\n}\n\n/** Callout box (error details, decisions needed). `innerHtml` is trusted. */\nexport function callout(innerHtml: string, tone: Tone): string {\n const c = toneColors(tone);\n return `<div style=\"${baseText}background:${c.bg};border-left:4px solid ${c.fg};border-radius:4px;padding:12px 14px;margin:0 0 16px 0;\">${innerHtml}</div>`;\n}\n\nexport function ul(items: string[]): string {\n const lis = items\n .map((it) => `<li style=\"${baseText}margin:0 0 6px 0;\">${escapeHtml(it)}</li>`)\n .join(\"\");\n return `<ul style=\"margin:0 0 12px 0;padding-left:20px;\">${lis}</ul>`;\n}\n\nexport interface TableColumn {\n header: string;\n /** Right-align numeric columns. */\n align?: \"left\" | \"right\";\n}\n\n/** Compact table. Cell values are HTML (already escaped by the caller). */\nexport function table(columns: TableColumn[], rowsHtml: string[][]): string {\n const th = columns\n .map(\n (c) =>\n `<th align=\"${c.align ?? \"left\"}\" style=\"${baseText}font-size:12px;text-transform:uppercase;letter-spacing:0.04em;color:${palette.muted};font-weight:600;padding:6px 8px;border-bottom:1px solid ${palette.border};\">${escapeHtml(c.header)}</th>`,\n )\n .join(\"\");\n const trs = rowsHtml\n .map(\n (cells) =>\n `<tr>${cells\n .map(\n (cell, i) =>\n `<td align=\"${columns[i]?.align ?? \"left\"}\" valign=\"top\" style=\"${baseText}font-size:14px;padding:8px;border-bottom:1px solid ${palette.border};\">${cell}</td>`,\n )\n .join(\"\")}</tr>`,\n )\n .join(\"\");\n return `<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\" style=\"border-collapse:collapse;margin:0 0 16px 0;\"><thead><tr>${th}</tr></thead><tbody>${trs}</tbody></table>`;\n}\n\nexport function hr(): string {\n return `<hr style=\"border:0;border-top:1px solid ${palette.border};margin:20px 0;\">`;\n}\n\n// ---------------------------------------------------------------------------\n// Layout\n// ---------------------------------------------------------------------------\n\nexport interface LayoutOptions {\n /** Used for <title>; shown by some clients as the tab/window name. */\n title: string;\n /** Inbox preview text. Hidden in the rendered body. */\n preheader?: string;\n /** Trusted, already-escaped body HTML. */\n bodyHtml: string;\n /** Trusted footer HTML (sender line, settings links). */\n footerHtml?: string;\n}\n\n/**\n * Complete HTML email document: single 600px column, inline styles, no images,\n * `color-scheme: light dark` plus a dark-mode override block so text stays readable.\n */\nexport function layout({ title, preheader, bodyHtml, footerHtml }: LayoutOptions): string {\n const preheaderHtml = preheader\n ? `<div data-preheader=\"1\" style=\"display:none;max-height:0;overflow:hidden;font-size:1px;line-height:1px;color:${palette.bg};opacity:0;\">${escapeHtml(preheader)}${\"͏‌ \".repeat(30)}</div>`\n : \"\";\n const footer = footerHtml\n ? `<tr><td class=\"aw-footer\" style=\"${baseText}font-size:12px;line-height:1.5;color:${palette.muted};padding:16px 8px 0 8px;\">${footerHtml}</td></tr>`\n : \"\";\n return (\n `<!DOCTYPE html>` +\n `<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">` +\n `<head>` +\n `<meta charset=\"utf-8\">` +\n `<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">` +\n `<meta name=\"color-scheme\" content=\"light dark\">` +\n `<meta name=\"supported-color-schemes\" content=\"light dark\">` +\n `<title>${escapeHtml(title)}</title>` +\n `<style>` +\n `:root{color-scheme:light dark;supported-color-schemes:light dark;}` +\n `body{margin:0;padding:0;-webkit-text-size-adjust:100%;}` +\n `@media (prefers-color-scheme: dark){` +\n `body,.aw-bg{background:#0b0f19 !important;}` +\n `.aw-card{background:#111827 !important;border-color:#1f2937 !important;}` +\n `.aw-card,.aw-card h1,.aw-card h2,.aw-card p,.aw-card td,.aw-card li{color:#e5e7eb !important;}` +\n `.aw-card pre,.aw-card code{background:#0b0f19 !important;color:#e5e7eb !important;border-color:#1f2937 !important;}` +\n `.aw-card a{color:#93c5fd !important;}` +\n `.aw-card th{color:#9ca3af !important;border-color:#1f2937 !important;}` +\n `.aw-card td{border-color:#1f2937 !important;}` +\n `.aw-footer,.aw-footer p{color:#9ca3af !important;}` +\n `}` +\n `</style>` +\n `</head>` +\n `<body class=\"aw-bg\" style=\"margin:0;padding:0;background:${palette.bg};\">` +\n preheaderHtml +\n `<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\" class=\"aw-bg\" style=\"background:${palette.bg};\">` +\n `<tr><td align=\"center\" style=\"padding:24px 12px;\">` +\n `<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\" style=\"max-width:600px;width:100%;\">` +\n `<tr><td class=\"aw-card\" style=\"background:${palette.card};border:1px solid ${palette.border};border-radius:8px;padding:28px 28px 20px 28px;${baseText}\">` +\n bodyHtml +\n `</td></tr>` +\n footer +\n `</table>` +\n `</td></tr></table>` +\n `</body></html>`\n );\n}\n\n// ---------------------------------------------------------------------------\n// HTML -> plain text\n// ---------------------------------------------------------------------------\n\nconst NAMED_ENTITIES: Record<string, string> = {\n amp: \"&\",\n lt: \"<\",\n gt: \">\",\n quot: '\"',\n apos: \"'\",\n nbsp: \" \",\n zwnj: \"\",\n zwj: \"\",\n hellip: \"...\",\n mdash: \"—\",\n ndash: \"–\",\n middot: \"·\",\n copy: \"©\",\n};\n\nexport function decodeEntities(s: string): string {\n return s.replace(/&(#x[0-9a-f]+|#\\d+|[a-z]+);/gi, (m, ent: string) => {\n if (ent[0] === \"#\") {\n const cp =\n ent[1]?.toLowerCase() === \"x\" ? parseInt(ent.slice(2), 16) : parseInt(ent.slice(1), 10);\n if (!Number.isFinite(cp)) return m;\n if (cp === 847) return \"\"; // combining grapheme joiner used as preheader padding\n try {\n return String.fromCodePoint(cp);\n } catch {\n return m;\n }\n }\n const named = NAMED_ENTITIES[ent.toLowerCase()];\n return named === undefined ? m : named;\n });\n}\n\nconst PRE_TOKEN = \"@@AWPRE\";\n\n/**\n * Plain-text rendering of an HTML email: tags stripped, block structure kept as newlines,\n * links kept as `text (url)`, list items bulleted, <pre> whitespace preserved.\n */\nexport function toText(html: string): string {\n let s = html;\n // Drop non-content regions.\n s = s.replace(/<head[\\s\\S]*?<\\/head>/gi, \"\");\n s = s.replace(/<(style|script)[\\s\\S]*?<\\/\\1>/gi, \"\");\n s = s.replace(/<!--[\\s\\S]*?-->/g, \"\");\n s = s.replace(/<[a-z]+[^>]*\\bdata-preheader\\b[^>]*>[\\s\\S]*?<\\/[a-z]+>/gi, \"\");\n\n // Pull <pre> blocks out so whitespace collapsing doesn't touch them.\n const pres: string[] = [];\n s = s.replace(/<pre\\b[^>]*>([\\s\\S]*?)<\\/pre>/gi, (_m, inner: string) => {\n const txt = decodeEntities(inner.replace(/<[^>]+>/g, \"\")).replace(/\\s+$/g, \"\");\n pres.push(txt);\n return `\\n${PRE_TOKEN}${pres.length - 1}@@\\n`;\n });\n\n // Links -> \"text (url)\".\n s = s.replace(\n /<a\\b[^>]*href=\"([^\"]*)\"[^>]*>([\\s\\S]*?)<\\/a>/gi,\n (_m, href: string, inner: string) => {\n const text = decodeEntities(inner.replace(/<[^>]+>/g, \"\"))\n .replace(/\\s+/g, \" \")\n .trim();\n const url = decodeEntities(href).trim();\n if (!url || url === \"#\") return text;\n if (!text || text === url) return url;\n return `${text} (${url})`;\n },\n );\n\n // Structure.\n s = s.replace(/<br\\s*\\/?>/gi, \"\\n\");\n s = s.replace(/<hr\\b[^>]*>/gi, \"\\n---\\n\");\n s = s.replace(/<li\\b[^>]*>/gi, \"\\n- \");\n s = s.replace(/<\\/(td|th)>/gi, \"\\t\");\n s = s.replace(/<\\/(p|div|h[1-6]|tr|table|ul|ol|blockquote|section)>/gi, \"\\n\");\n s = s.replace(/<(h[1-6]|p|div|table|ul|ol|blockquote|section)\\b[^>]*>/gi, \"\\n\");\n s = s.replace(/<[^>]+>/g, \"\");\n s = decodeEntities(s);\n\n // Whitespace: collapse runs of spaces, trim lines, cap blank lines at one.\n s = s\n .split(\"\\n\")\n .map((line) =>\n line\n .replace(/[ \\u00a0]+/g, \" \")\n .replace(/ ?\\t ?/g, \"\\t\")\n .trim(),\n )\n .join(\"\\n\")\n .replace(/\\t+$/gm, \"\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n\n // Restore <pre> blocks.\n s = s.replace(new RegExp(`${PRE_TOKEN}(\\\\d+)@@`, \"g\"), (_m, i: string) => pres[Number(i)] ?? \"\");\n return s;\n}\n\n// ---------------------------------------------------------------------------\n// Formatting helpers shared by templates\n// ---------------------------------------------------------------------------\n\nexport function formatDate(value: string | Date): string {\n const d = typeof value === \"string\" ? new Date(value) : value;\n if (Number.isNaN(d.getTime())) return typeof value === \"string\" ? value : \"\";\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())} UTC`;\n}\n\nexport function formatUsd(amount: number): string {\n const sign = amount < 0 ? \"-\" : \"\";\n const abs = Math.abs(amount);\n const fixed = abs > 0 && abs < 0.01 ? abs.toFixed(4) : abs.toFixed(2);\n const [int = \"0\", frac] = fixed.split(\".\");\n const grouped = int.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n return `${sign}$${grouped}${frac ? `.${frac}` : \"\"}`;\n}\n\nexport function plural(n: number, singular: string, pluralWord = `${singular}s`): string {\n return `${n} ${n === 1 ? singular : pluralWord}`;\n}\n","import {\n button,\n callout,\n code,\n escapeHtml,\n formatDate,\n h1,\n h2,\n layout,\n link,\n muted,\n p,\n pHtml,\n pill,\n plural,\n pre,\n toText,\n} from \"../html.js\";\nimport type { RenderedEmail } from \"./types.js\";\n\nexport interface AlertError {\n code: string;\n cause?: string;\n fix?: string;\n}\n\nexport interface AlertDiff {\n /** Response/transcript from the last passing run. */\n before: string;\n /** Response/transcript from the failing run. */\n after: string;\n}\n\nexport interface AlertTemplateInput {\n productName: string;\n targetName: string;\n checkName: string;\n statusUrl: string;\n openedAt: string | Date;\n error: AlertError;\n /** Excerpt of the failing transcript (rendered verbatim in a <pre>). */\n transcriptExcerpt?: string;\n /** Either a unified diff string or a before/after pair vs the last pass. */\n diff?: AlertDiff | string;\n consecutiveFailures: number;\n /**\n * Link that silences this check for 24h. Defaults to `${statusUrl}?silence=24h`\n * until the product wires a real route.\n */\n silenceUrl?: string;\n}\n\n/** Monitor failed: leads with what failed, then transcript, then diff vs last pass. */\nexport function alertTemplate(input: AlertTemplateInput): RenderedEmail {\n const { productName, targetName, checkName, statusUrl, error } = input;\n const silenceUrl =\n input.silenceUrl ?? `${statusUrl}${statusUrl.includes(\"?\") ? \"&\" : \"?\"}silence=24h`;\n const failures = plural(input.consecutiveFailures, \"consecutive failure\");\n const since = formatDate(input.openedAt);\n\n const subject = `[${productName}] FAILING: ${targetName} · ${checkName}`;\n\n const errorLines = [\n `<div style=\"margin:0 0 6px 0;\">${pill(\"FAILING\", \"red\")} ${code(error.code)}</div>`,\n error.cause ? pHtml(`<strong>Cause:</strong> ${escapeHtml(error.cause)}`) : \"\",\n error.fix ? pHtml(`<strong>Fix:</strong> ${escapeHtml(error.fix)}`) : \"\",\n ].join(\"\");\n\n let diffHtml = \"\";\n if (typeof input.diff === \"string\" && input.diff.trim()) {\n diffHtml = h2(\"Diff vs last pass\") + pre(input.diff);\n } else if (input.diff && typeof input.diff === \"object\") {\n diffHtml =\n h2(\"Diff vs last pass\") +\n muted(\"Last pass\") +\n pre(input.diff.before, { maxChars: 2000 }) +\n muted(\"Now\") +\n pre(input.diff.after, { maxChars: 2000 });\n }\n\n const bodyHtml =\n h1(`${checkName} is failing on ${targetName}`) +\n p(`${failures} since ${since}.`) +\n callout(errorLines, \"red\") +\n (input.transcriptExcerpt ? h2(\"Failing transcript\") + pre(input.transcriptExcerpt) : \"\") +\n diffHtml +\n button(statusUrl, \"Open status page\") +\n pHtml(`${link(statusUrl, \"Status page\")} · ${link(silenceUrl, \"Silence this check for 24h\")}`);\n\n const html = layout({\n title: subject,\n preheader: `${error.code}${error.cause ? `: ${error.cause}` : \"\"} (${failures})`,\n bodyHtml,\n footerHtml: `${escapeHtml(productName)} opened this incident automatically. It closes on the first passing run.`,\n });\n\n return { subject, html, text: toText(html) };\n}\n","import { button, escapeHtml, h1, layout, link, p, pHtml, pill, plural, toText } from \"../html.js\";\nimport type { RenderedEmail } from \"./types.js\";\n\nexport interface RecoveredTemplateInput {\n productName: string;\n targetName: string;\n checkName: string;\n statusUrl: string;\n downtimeMinutes: number;\n}\n\n/** Incident closed: first passing run after a failure. */\nexport function recoveredTemplate(input: RecoveredTemplateInput): RenderedEmail {\n const { productName, targetName, checkName, statusUrl } = input;\n const minutes = Math.max(0, Math.round(input.downtimeMinutes));\n const downtime =\n minutes >= 120 ? plural(Math.round(minutes / 60), \"hour\") : plural(minutes, \"minute\");\n const subject = `[${productName}] RECOVERED: ${targetName} · ${checkName}`;\n\n const bodyHtml =\n h1(`${checkName} is passing again on ${targetName}`) +\n pHtml(`${pill(\"RECOVERED\", \"green\")} back after ${escapeHtml(downtime)} of failures.`) +\n p(\"The incident is closed. The status page keeps the timeline and the failing transcripts.\") +\n button(statusUrl, \"Open status page\") +\n pHtml(link(statusUrl, statusUrl));\n\n const html = layout({\n title: subject,\n preheader: `Back after ${downtime}.`,\n bodyHtml,\n footerHtml: `${escapeHtml(productName)} closed this incident automatically.`,\n });\n\n return { subject, html, text: toText(html) };\n}\n","import {\n button,\n callout,\n escapeHtml,\n formatUsd,\n h1,\n h2,\n layout,\n link,\n muted,\n p,\n pHtml,\n toText,\n ul,\n} from \"../html.js\";\nimport type { RenderedEmail } from \"./types.js\";\n\nexport interface DigestSection {\n title: string;\n items: string[];\n}\n\nexport interface DigestTemplateInput {\n productName: string;\n /** Report date, e.g. \"2026-09-01\" (rendered verbatim). */\n date: string;\n sections: DigestSection[];\n /** Judge/LLM spend for the night, shown to the account owner. */\n costUsd?: number;\n /** Anything that needs a human choice; rendered first when present. */\n decisionsNeeded?: string[];\n reportUrl: string;\n}\n\n/** Nightly report: decisions needed first, then each section as a bulleted list. */\nexport function digestTemplate(input: DigestTemplateInput): RenderedEmail {\n const { productName, date, reportUrl } = input;\n const decisions = (input.decisionsNeeded ?? []).filter((d) => d.trim().length > 0);\n const sections = input.sections.filter((s) => s.items.length > 0);\n const subject = decisions.length\n ? `[${productName}] Nightly report ${date}: ${decisions.length} decision${decisions.length === 1 ? \"\" : \"s\"} needed`\n : `[${productName}] Nightly report ${date}`;\n\n const decisionsHtml = decisions.length\n ? callout(`<strong>Decisions needed</strong>${ul(decisions)}`, \"amber\")\n : \"\";\n\n const sectionsHtml = sections.length\n ? sections.map((s) => h2(s.title) + ul(s.items)).join(\"\")\n : p(\"Nothing changed overnight. All checks passed.\");\n\n const costHtml =\n input.costUsd !== undefined ? muted(`Overnight judge spend: ${formatUsd(input.costUsd)}.`) : \"\";\n\n const bodyHtml =\n h1(`Nightly report for ${date}`) +\n decisionsHtml +\n sectionsHtml +\n costHtml +\n button(reportUrl, \"Open full report\") +\n pHtml(link(reportUrl, reportUrl));\n\n const preheader = decisions.length\n ? `${decisions.length} decision${decisions.length === 1 ? \"\" : \"s\"} needed. ${decisions[0] ?? \"\"}`\n : (sections[0]?.items[0] ?? \"All checks passed overnight.\");\n\n const html = layout({\n title: subject,\n preheader,\n bodyHtml,\n footerHtml: `Sent by ${escapeHtml(productName)} after the nightly suite finished.`,\n });\n\n return { subject, html, text: toText(html) };\n}\n","import {\n button,\n callout,\n escapeHtml,\n formatDate,\n h1,\n h2,\n hr,\n layout,\n link,\n muted,\n p,\n pHtml,\n pill,\n plural,\n table,\n toText,\n} from \"../html.js\";\nimport type { RenderedEmail } from \"./types.js\";\n\nexport type DriftVerdict = \"regressed\" | \"improved\" | \"unchanged\";\n\nexport interface DriftChange {\n check: string;\n before: string;\n after: string;\n verdict: DriftVerdict;\n}\n\nexport interface DriftTemplateInput {\n productName: string;\n provider: string;\n model: string;\n releasedAt: string | Date;\n targetName: string;\n /** One or two sentences: what the re-run found. */\n summary: string;\n changes: DriftChange[];\n runUrl: string;\n /** Public, forwardable results page. */\n shareUrl: string;\n}\n\nconst VERDICT_ORDER: Record<DriftVerdict, number> = { regressed: 0, improved: 1, unchanged: 2 };\n\nfunction verdictPill(v: DriftVerdict): string {\n switch (v) {\n case \"regressed\":\n return pill(\"REGRESSED\", \"red\");\n case \"improved\":\n return pill(\"IMPROVED\", \"green\");\n case \"unchanged\":\n return pill(\"UNCHANGED\", \"gray\");\n }\n}\n\n/** Sort a copy: regressed first, then improved, then unchanged; stable within a verdict. */\nexport function sortDriftChanges(changes: readonly DriftChange[]): DriftChange[] {\n return changes\n .map((c, i) => ({ c, i }))\n .sort((a, b) => VERDICT_ORDER[a.c.verdict] - VERDICT_ORDER[b.c.verdict] || a.i - b.i)\n .map(({ c }) => c);\n}\n\n/**\n * \"Model X shipped. Here's what changed in your agent.\" The forwardable one: compact table,\n * regressions on top, a share link, and no account-specific noise.\n */\nexport function driftTemplate(input: DriftTemplateInput): RenderedEmail {\n const { productName, provider, model, targetName, runUrl, shareUrl } = input;\n const sorted = sortDriftChanges(input.changes);\n const counts = { regressed: 0, improved: 0, unchanged: 0 };\n for (const c of sorted) counts[c.verdict] += 1;\n\n const headline = `${model} shipped. Here's what changed in ${targetName}.`;\n const subject = counts.regressed\n ? `[${productName}] ${model} shipped: ${plural(counts.regressed, \"regression\")} in ${targetName}`\n : `[${productName}] ${model} shipped: no regressions in ${targetName}`;\n\n const countsLine =\n `${pill(`${counts.regressed} regressed`, counts.regressed ? \"red\" : \"gray\")} ` +\n `${pill(`${counts.improved} improved`, counts.improved ? \"green\" : \"gray\")} ` +\n `${pill(`${counts.unchanged} unchanged`, \"gray\")}`;\n\n const tableHtml = sorted.length\n ? table(\n [{ header: \"Check\" }, { header: \"Before\" }, { header: \"After\" }, { header: \"Verdict\" }],\n sorted.map((c) => [\n `<strong>${escapeHtml(c.check)}</strong>`,\n escapeHtml(c.before),\n escapeHtml(c.after),\n verdictPill(c.verdict),\n ]),\n )\n : p(\"No checks were re-run for this release.\");\n\n const bodyHtml =\n h1(headline) +\n muted(\n `${provider} released ${model} on ${formatDate(input.releasedAt)}. We re-ran the suite for ${targetName} against it.`,\n ) +\n p(input.summary) +\n pHtml(countsLine) +\n h2(\"What changed\") +\n tableHtml +\n button(runUrl, \"See the full run\") +\n hr() +\n callout(\n `<strong>Forward this.</strong> Know a team running on ${escapeHtml(model)}? This report is public and safe to share: ${link(shareUrl, shareUrl)}`,\n \"gray\",\n ) +\n muted(`Re-run automatically by ${productName} when a provider ships a new model or alias.`);\n\n const html = layout({\n title: subject,\n preheader: counts.regressed\n ? `${plural(counts.regressed, \"regression\")}, ${counts.improved} improved, ${counts.unchanged} unchanged.`\n : `No regressions. ${counts.improved} improved, ${counts.unchanged} unchanged.`,\n bodyHtml,\n footerHtml: `${escapeHtml(productName)} model-drift re-run. Public results: ${link(shareUrl, \"share link\")}.`,\n });\n\n return { subject, html, text: toText(html) };\n}\n","import {\n button,\n escapeHtml,\n formatUsd,\n h1,\n layout,\n link,\n muted,\n p,\n pHtml,\n table,\n toText,\n} from \"../html.js\";\nimport type { RenderedEmail } from \"./types.js\";\n\nexport interface ReceiptLine {\n description: string;\n amountUsd: number;\n}\n\nexport interface ReceiptTemplateInput {\n productName: string;\n lines: ReceiptLine[];\n totalUsd: number;\n /** Stripe Customer Portal (or equivalent) URL for invoices and plan changes. */\n portalUrl: string;\n /** Optional invoice/receipt identifier shown in the subject and body. */\n reference?: string;\n}\n\n/** Payment receipt: line items, total, link to the billing portal. */\nexport function receiptTemplate(input: ReceiptTemplateInput): RenderedEmail {\n const { productName, portalUrl } = input;\n const total = formatUsd(input.totalUsd);\n const subject = `[${productName}] Receipt${input.reference ? ` ${input.reference}` : \"\"}: ${total}`;\n\n const rows = input.lines.map((l) => [\n escapeHtml(l.description),\n escapeHtml(formatUsd(l.amountUsd)),\n ]);\n rows.push([`<strong>Total</strong>`, `<strong>${escapeHtml(total)}</strong>`]);\n\n const bodyHtml =\n h1(`Thanks. Here is your receipt.`) +\n (input.reference ? muted(`Reference ${input.reference}`) : \"\") +\n table([{ header: \"Item\" }, { header: \"Amount\", align: \"right\" }], rows) +\n p(\"Invoices, plan changes and cancellation are self-serve in the billing portal.\") +\n button(portalUrl, \"Manage billing\") +\n pHtml(link(portalUrl, portalUrl));\n\n const html = layout({\n title: subject,\n preheader: `${total} paid to ${productName}.`,\n bodyHtml,\n footerHtml: `Sent by ${escapeHtml(productName)}. Reply to this email if something looks wrong.`,\n });\n\n return { subject, html, text: toText(html) };\n}\n","/**\n * Delivery channels: Resend email, Slack/Discord incoming webhooks, generic signed webhook.\n * Web-standard only (`fetch`, `crypto.subtle`) so the same code runs on Vercel Functions and\n * Cloudflare Workers. Nothing here throws on remote failure; every call resolves a SendResult.\n */\nimport { Resend } from \"resend\";\n\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\nexport interface SendResult {\n ok: boolean;\n /** Provider-side id (Resend email id, Discord message id) when available. */\n id?: string;\n /** HTTP status of the provider response when one was received. */\n status?: number;\n /** Short, log-safe error description. Never contains secrets. */\n error?: string;\n}\n\nconst USER_AGENT = \"agentwares-notify/0.1\";\nconst RESEND_API = \"https://api.resend.com/emails\";\n\nfunction errorMessage(e: unknown): string {\n if (e instanceof Error) return e.message;\n return typeof e === \"string\" ? e : \"unknown error\";\n}\n\nasync function readBody(res: Response): Promise<string> {\n try {\n return (await res.text()).slice(0, 500);\n } catch {\n return \"\";\n }\n}\n\nfunction parseJson(text: string): Record<string, unknown> | undefined {\n try {\n const v: unknown = JSON.parse(text);\n return v && typeof v === \"object\" ? (v as Record<string, unknown>) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction defaultFetch(): FetchLike | undefined {\n return typeof fetch === \"function\" ? (input, init) => fetch(input, init) : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Email (Resend)\n// ---------------------------------------------------------------------------\n\nexport interface ResendEmailPayload {\n from: string;\n to: string | string[];\n subject: string;\n html: string;\n text?: string;\n replyTo?: string | string[];\n headers?: Record<string, string>;\n}\n\nexport interface ResendSendResponse {\n data: { id: string } | null;\n error: { message: string; name?: string; statusCode?: number | null } | null;\n}\n\n/** The slice of the Resend SDK we use; `new Resend(key)` satisfies it, so do test fakes. */\nexport interface ResendLike {\n emails: {\n send(payload: ResendEmailPayload): Promise<ResendSendResponse>;\n };\n}\n\nexport interface SendEmailOptions extends ResendEmailPayload {\n /** Resend API key. Ignored when `resend` is given. */\n apiKey?: string;\n /** Injected client (tests, or a shared instance). */\n resend?: ResendLike;\n /**\n * Injected fetch. When given (and no `resend` client), the email is posted to the Resend\n * REST API through this fetch instead of the SDK, which only uses the global fetch.\n */\n fetch?: FetchLike;\n}\n\n/** Minimal Resend client over an injected fetch. Same endpoint and shapes the SDK uses. */\nexport function resendOverFetch(apiKey: string, fetchImpl: FetchLike): ResendLike {\n return {\n emails: {\n async send(payload) {\n const res = await fetchImpl(RESEND_API, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": USER_AGENT,\n },\n body: JSON.stringify({\n from: payload.from,\n to: payload.to,\n subject: payload.subject,\n html: payload.html,\n text: payload.text,\n reply_to: payload.replyTo,\n headers: payload.headers,\n }),\n });\n const body = parseJson(await readBody(res));\n if (!res.ok) {\n return {\n data: null,\n error: {\n message: typeof body?.message === \"string\" ? body.message : res.statusText,\n name: typeof body?.name === \"string\" ? body.name : \"application_error\",\n statusCode: res.status,\n },\n };\n }\n return { data: { id: typeof body?.id === \"string\" ? body.id : \"\" }, error: null };\n },\n },\n };\n}\n\nfunction resolveResend(opts: SendEmailOptions): ResendLike | undefined {\n if (opts.resend) return opts.resend;\n if (!opts.apiKey) return undefined;\n if (opts.fetch) return resendOverFetch(opts.apiKey, opts.fetch);\n return new Resend(opts.apiKey);\n}\n\n/**\n * Domains that can never receive mail: the special-use names of RFC 2606 / RFC 6761 / RFC 6762\n * (`.test`, `.example`, `.invalid`, `.localhost`, `.local`) and the `example.*` second-level\n * names. Our demo, soak and dogfood users carry `@agentwares.local`; sending to them bounced\n * every night (46 of 50 Resend sends, 28 Sep–6 Oct 2026), and a bounce rate like that can get\n * the sending domain paused, which would silence every customer alert with it.\n */\nconst UNDELIVERABLE =\n /@(?:[^@\\s]+\\.)?(?:test|example|invalid|localhost|local)$|@example\\.(?:com|net|org)$/i;\n\n/** True when an address can never be delivered to and must not be sent to. */\nexport function isUndeliverableAddress(address: string): boolean {\n return UNDELIVERABLE.test(address.trim().replace(/^.*<([^>]+)>\\s*$/, \"$1\"));\n}\n\n/** Send one transactional email through Resend. Never throws. */\nexport async function sendEmail(opts: SendEmailOptions): Promise<SendResult> {\n const client = resolveResend(opts);\n if (!client) return { ok: false, error: \"RESEND_API_KEY not configured\" };\n const all = Array.isArray(opts.to) ? opts.to : [opts.to];\n if (all.length === 0 || all.some((t) => !t.trim())) return { ok: false, error: \"no recipient\" };\n const to = all.filter((t) => !isUndeliverableAddress(t));\n if (to.length === 0) return { ok: false, error: \"suppressed: reserved test domain, not sent\" };\n try {\n const payload: ResendEmailPayload = {\n from: opts.from,\n to,\n subject: opts.subject,\n html: opts.html,\n };\n if (opts.text !== undefined) payload.text = opts.text;\n if (opts.replyTo !== undefined) payload.replyTo = opts.replyTo;\n if (opts.headers !== undefined) payload.headers = opts.headers;\n const res = await client.emails.send(payload);\n if (res.error) {\n const status = res.error.statusCode ?? undefined;\n return {\n ok: false,\n ...(status !== undefined ? { status } : {}),\n error: `${res.error.name ?? \"resend_error\"}: ${res.error.message}`,\n };\n }\n return { ok: true, id: res.data?.id ?? \"\", status: 200 };\n } catch (e) {\n return { ok: false, error: errorMessage(e) };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Slack incoming webhook\n// ---------------------------------------------------------------------------\n\nexport interface SlackMessage {\n text: string;\n /** Block Kit blocks; passed through untouched. */\n blocks?: unknown[];\n}\n\nexport interface ChannelOptions {\n fetch?: FetchLike;\n}\n\nasync function postJson(\n url: string,\n body: unknown,\n headers: Record<string, string>,\n fetchImpl: FetchLike | undefined,\n): Promise<{ res: Response; text: string } | { error: string }> {\n if (!fetchImpl) return { error: \"fetch is not available\" };\n try {\n const res = await fetchImpl(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", \"User-Agent\": USER_AGENT, ...headers },\n body: typeof body === \"string\" ? body : JSON.stringify(body),\n });\n return { res, text: await readBody(res) };\n } catch (e) {\n return { error: errorMessage(e) };\n }\n}\n\n/** Post to a Slack incoming webhook. Never throws. */\nexport async function sendSlack(\n webhookUrl: string,\n message: SlackMessage,\n opts: ChannelOptions = {},\n): Promise<SendResult> {\n const r = await postJson(webhookUrl, message, {}, opts.fetch ?? defaultFetch());\n if (\"error\" in r) return { ok: false, error: r.error };\n return r.res.ok\n ? { ok: true, status: r.res.status }\n : { ok: false, status: r.res.status, error: r.text || r.res.statusText || \"slack error\" };\n}\n\n// ---------------------------------------------------------------------------\n// Discord webhook\n// ---------------------------------------------------------------------------\n\nexport const DISCORD_CONTENT_LIMIT = 2000;\n\nexport interface DiscordEmbed {\n title?: string;\n description?: string;\n url?: string;\n color?: number;\n fields?: { name: string; value: string; inline?: boolean }[];\n footer?: { text: string };\n timestamp?: string;\n}\n\nexport interface DiscordMessage {\n content: string;\n embeds?: DiscordEmbed[];\n username?: string;\n}\n\n/** Truncate to `max` UTF-16 units without splitting a surrogate pair; appends an ellipsis. */\nexport function truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n let cut = text.slice(0, Math.max(0, max - 1));\n const last = cut.charCodeAt(cut.length - 1);\n if (last >= 0xd800 && last <= 0xdbff) cut = cut.slice(0, -1);\n return `${cut}…`;\n}\n\n/** Post to a Discord webhook. Content is truncated to 2000 chars. Never throws. */\nexport async function sendDiscord(\n webhookUrl: string,\n message: DiscordMessage,\n opts: ChannelOptions = {},\n): Promise<SendResult> {\n let url: URL;\n try {\n url = new URL(webhookUrl);\n } catch {\n return { ok: false, error: \"invalid webhook url\" };\n }\n url.searchParams.set(\"wait\", \"true\"); // return the created message so we get an id\n const body: DiscordMessage = {\n ...message,\n content: truncate(message.content, DISCORD_CONTENT_LIMIT),\n };\n const r = await postJson(url.toString(), body, {}, opts.fetch ?? defaultFetch());\n if (\"error\" in r) return { ok: false, error: r.error };\n if (!r.res.ok) {\n return {\n ok: false,\n status: r.res.status,\n error: r.text || r.res.statusText || \"discord error\",\n };\n }\n const json = parseJson(r.text);\n const id = typeof json?.id === \"string\" ? json.id : undefined;\n return { ok: true, status: r.res.status, ...(id !== undefined ? { id } : {}) };\n}\n\n// ---------------------------------------------------------------------------\n// Generic signed webhook\n// ---------------------------------------------------------------------------\n\nexport const SIGNATURE_HEADER = \"X-Agentwares-Signature\";\n\nconst encoder = new TextEncoder();\n\nfunction toHex(bytes: ArrayBuffer): string {\n return Array.from(new Uint8Array(bytes), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/** HMAC-SHA256 of `body` keyed by `secret`, hex encoded. */\nexport async function hmacSha256Hex(secret: string, body: string): Promise<string> {\n const key = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n return toHex(await crypto.subtle.sign(\"HMAC\", key, encoder.encode(body)));\n}\n\n/** Verify an `X-Agentwares-Signature: sha256=<hex>` header against the raw body. */\nexport async function verifyWebhookSignature(\n body: string,\n secret: string,\n header: string | null | undefined,\n): Promise<boolean> {\n if (!header) return false;\n const expected = `sha256=${await hmacSha256Hex(secret, body)}`;\n if (expected.length !== header.length) return false;\n let diff = 0;\n for (let i = 0; i < expected.length; i++) diff |= expected.charCodeAt(i) ^ header.charCodeAt(i);\n return diff === 0;\n}\n\nexport interface WebhookOptions extends ChannelOptions {\n /** When set, the request carries `X-Agentwares-Signature: sha256=<hmac hex of the body>`. */\n secret?: string;\n headers?: Record<string, string>;\n}\n\n/** POST a JSON payload to any URL, optionally HMAC-signed. Never throws. */\nexport async function sendWebhook(\n url: string,\n payload: unknown,\n opts: WebhookOptions = {},\n): Promise<SendResult> {\n const body = JSON.stringify(payload);\n const headers: Record<string, string> = { ...(opts.headers ?? {}) };\n if (opts.secret) headers[SIGNATURE_HEADER] = `sha256=${await hmacSha256Hex(opts.secret, body)}`;\n const r = await postJson(url, body, headers, opts.fetch ?? defaultFetch());\n if (\"error\" in r) return { ok: false, error: r.error };\n return r.res.ok\n ? { ok: true, status: r.res.status }\n : { ok: false, status: r.res.status, error: r.text || r.res.statusText || \"webhook error\" };\n}\n","/**\n * `createNotify()` binds the channels to one configuration and adds fan-out helpers that\n * render a template once and deliver it everywhere the caller configured. Email gets the\n * full HTML; Slack/Discord get a one-line summary with the link; webhooks get the payload.\n */\nimport { Resend } from \"resend\";\nimport {\n sendDiscord,\n sendEmail,\n sendSlack,\n sendWebhook,\n type DiscordMessage,\n type FetchLike,\n type ResendLike,\n type SendEmailOptions,\n type SendResult,\n type SlackMessage,\n type WebhookOptions,\n} from \"./channels.js\";\nimport {\n alertTemplate,\n digestTemplate,\n driftTemplate,\n recoveredTemplate,\n sortDriftChanges,\n type AlertTemplateInput,\n type DigestTemplateInput,\n type DriftTemplateInput,\n type RecoveredTemplateInput,\n type RenderedEmail,\n} from \"./templates/index.js\";\nimport { plural } from \"./html.js\";\n\nexport interface NotifyChannels {\n /** Recipient addresses. */\n email?: string[];\n /** Slack incoming-webhook URL. */\n slack?: string;\n /** Discord webhook URL. */\n discord?: string;\n /** Generic JSON webhook, HMAC-signed when `secret` is set. */\n webhook?: { url: string; secret?: string };\n}\n\nexport interface FanoutResult {\n email?: SendResult;\n slack?: SendResult;\n discord?: SendResult;\n webhook?: SendResult;\n}\n\nexport type NotifyEvent = \"alert\" | \"recovered\" | \"drift\" | \"digest\";\n\nexport interface CreateNotifyOptions {\n /** Resend API key. Omit to get structured `RESEND_API_KEY not configured` failures. */\n resendApiKey?: string;\n /** From address, e.g. `acme <alerts@example.com>`. */\n from: string;\n replyTo?: string;\n /** Injected fetch for Slack/Discord/webhooks (and Resend REST when no client is given). */\n fetch?: FetchLike;\n /** Injected Resend client (tests). Takes precedence over `resendApiKey`. */\n resend?: ResendLike;\n}\n\nexport type NotifyEmailOptions = Omit<SendEmailOptions, \"from\" | \"apiKey\" | \"resend\" | \"fetch\"> & {\n from?: string;\n};\n\nexport interface Notify {\n email(opts: NotifyEmailOptions): Promise<SendResult>;\n slack(webhookUrl: string, message: SlackMessage): Promise<SendResult>;\n discord(webhookUrl: string, message: DiscordMessage): Promise<SendResult>;\n webhook(url: string, payload: unknown, opts?: Omit<WebhookOptions, \"fetch\">): Promise<SendResult>;\n alert(channels: NotifyChannels, payload: AlertTemplateInput): Promise<FanoutResult>;\n recovered(channels: NotifyChannels, payload: RecoveredTemplateInput): Promise<FanoutResult>;\n drift(channels: NotifyChannels, payload: DriftTemplateInput): Promise<FanoutResult>;\n digest(channels: NotifyChannels, payload: DigestTemplateInput): Promise<FanoutResult>;\n}\n\ninterface Summary {\n /** One line, no markup. */\n text: string;\n /** Primary link for the message. */\n url: string;\n label: string;\n}\n\nexport function summarizeAlert(p: AlertTemplateInput): Summary {\n const cause = p.error.cause ? `: ${p.error.cause}` : \"\";\n return {\n text: `FAILING: ${p.targetName} · ${p.checkName} — ${p.error.code}${cause} (${plural(p.consecutiveFailures, \"consecutive failure\")})`,\n url: p.statusUrl,\n label: \"Open status page\",\n };\n}\n\nexport function summarizeRecovered(p: RecoveredTemplateInput): Summary {\n return {\n text: `RECOVERED: ${p.targetName} · ${p.checkName} — back after ${plural(Math.max(0, Math.round(p.downtimeMinutes)), \"minute\")}`,\n url: p.statusUrl,\n label: \"Open status page\",\n };\n}\n\nexport function summarizeDrift(p: DriftTemplateInput): Summary {\n const counts = { regressed: 0, improved: 0, unchanged: 0 };\n for (const c of sortDriftChanges(p.changes)) counts[c.verdict] += 1;\n return {\n text: `${p.model} shipped: ${counts.regressed} regressed, ${counts.improved} improved, ${counts.unchanged} unchanged in ${p.targetName}`,\n url: p.runUrl,\n label: \"See the full run\",\n };\n}\n\nexport function summarizeDigest(p: DigestTemplateInput): Summary {\n const decisions = (p.decisionsNeeded ?? []).length;\n const items = p.sections.reduce((n, s) => n + s.items.length, 0);\n const head = decisions ? `${plural(decisions, \"decision\")} needed; ` : \"\";\n return {\n text: `Nightly report ${p.date}: ${head}${plural(items, \"item\")} across ${plural(p.sections.length, \"section\")}`,\n url: p.reportUrl,\n label: \"Open full report\",\n };\n}\n\nfunction slackText(product: string, s: Summary): string {\n return `[${product}] ${s.text}\\n<${s.url}|${s.label}>`;\n}\n\nfunction discordContent(product: string, s: Summary): string {\n return `[${product}] ${s.text}\\n<${s.url}>`;\n}\n\nexport function createNotify(options: CreateNotifyOptions): Notify {\n const { from, replyTo } = options;\n const fetchImpl = options.fetch;\n const resendClient: ResendLike | undefined =\n options.resend ??\n (options.resendApiKey && !fetchImpl ? new Resend(options.resendApiKey) : undefined);\n\n const email: Notify[\"email\"] = (opts) =>\n sendEmail({\n ...opts,\n from: opts.from ?? from,\n ...(replyTo !== undefined && opts.replyTo === undefined ? { replyTo } : {}),\n ...(options.resendApiKey !== undefined ? { apiKey: options.resendApiKey } : {}),\n ...(resendClient !== undefined ? { resend: resendClient } : {}),\n ...(fetchImpl !== undefined ? { fetch: fetchImpl } : {}),\n });\n\n const channelOpts = fetchImpl !== undefined ? { fetch: fetchImpl } : {};\n const slack: Notify[\"slack\"] = (url, message) => sendSlack(url, message, channelOpts);\n const discord: Notify[\"discord\"] = (url, message) => sendDiscord(url, message, channelOpts);\n const webhook: Notify[\"webhook\"] = (url, payload, opts = {}) =>\n sendWebhook(url, payload, { ...opts, ...channelOpts });\n\n async function fanout(\n channels: NotifyChannels,\n event: NotifyEvent,\n payload: unknown,\n rendered: RenderedEmail,\n summary: Summary,\n productName: string,\n ): Promise<FanoutResult> {\n const jobs: Promise<[keyof FanoutResult, SendResult]>[] = [];\n if (channels.email && channels.email.length > 0) {\n jobs.push(\n email({\n to: channels.email,\n subject: rendered.subject,\n html: rendered.html,\n text: rendered.text,\n }).then((r) => [\"email\", r]),\n );\n }\n if (channels.slack) {\n jobs.push(\n slack(channels.slack, { text: slackText(productName, summary) }).then((r) => [\"slack\", r]),\n );\n }\n if (channels.discord) {\n jobs.push(\n discord(channels.discord, { content: discordContent(productName, summary) }).then((r) => [\n \"discord\",\n r,\n ]),\n );\n }\n if (channels.webhook) {\n const { url, secret } = channels.webhook;\n const body = {\n event,\n product: productName,\n subject: rendered.subject,\n summary: summary.text,\n url: summary.url,\n occurredAt: new Date().toISOString(),\n data: payload,\n };\n jobs.push(\n webhook(url, body, secret !== undefined ? { secret } : {}).then((r) => [\"webhook\", r]),\n );\n }\n const settled = await Promise.all(jobs);\n const out: FanoutResult = {};\n for (const [key, result] of settled) out[key] = result;\n return out;\n }\n\n return {\n email,\n slack,\n discord,\n webhook,\n alert: (channels, payload) =>\n fanout(\n channels,\n \"alert\",\n payload,\n alertTemplate(payload),\n summarizeAlert(payload),\n payload.productName,\n ),\n recovered: (channels, payload) =>\n fanout(\n channels,\n \"recovered\",\n payload,\n recoveredTemplate(payload),\n summarizeRecovered(payload),\n payload.productName,\n ),\n drift: (channels, payload) =>\n fanout(\n channels,\n \"drift\",\n payload,\n driftTemplate(payload),\n summarizeDrift(payload),\n payload.productName,\n ),\n digest: (channels, payload) =>\n fanout(\n channels,\n \"digest\",\n payload,\n digestTemplate(payload),\n summarizeDigest(payload),\n payload.productName,\n ),\n };\n}\n","/**\n * Alerts: Slack / generic webhook on halts and approvals, through `@agentwares/notify`.\n * No email in the OSS CLI (no Resend key), no phone-home.\n */\nimport { sendSlack, sendWebhook } from \"@agentwares/notify\";\nimport type { ApprovalRecord, GuardEvent, Policy } from \"@agentwares/agentguard-core\";\n\nexport interface AlerterOptions {\n policy: Policy;\n approvalUrl?: (record: ApprovalRecord) => string | undefined;\n log?: (line: string) => void;\n fetch?: typeof fetch;\n}\n\nexport function approvalSlackMessage(\n event: GuardEvent,\n url: string | undefined,\n): { text: string; blocks: unknown[] } {\n const a = event.approval!;\n const argsText = JSON.stringify(a.args ?? {}, null, 2).slice(0, 1500);\n const text = `[agentguard] approval needed: ${a.tool} (run ${a.run_id}) — run \\`agentguard approve ${a.id}\\`${url ? ` or open ${url}` : \"\"}`;\n const blocks: unknown[] = [\n { type: \"header\", text: { type: \"plain_text\", text: `Approval needed: ${a.tool}` } },\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*run* \\`${a.run_id}\\`${a.agent ? ` · *agent* \\`${a.agent}\\`` : \"\"}${a.upstream ? ` · *upstream* \\`${a.upstream}\\`` : \"\"}\\n\\`\\`\\`${argsText}\\`\\`\\``,\n },\n },\n {\n type: \"context\",\n elements: [\n {\n type: \"mrkdwn\",\n text: `Approve: \\`agentguard approve ${a.id}\\` · Deny: \\`agentguard deny ${a.id}\\` · expires ${a.expires_at}`,\n },\n ],\n },\n ];\n if (url) {\n blocks.push({\n type: \"actions\",\n elements: [\n { type: \"button\", text: { type: \"plain_text\", text: \"Approve\" }, style: \"primary\", url },\n {\n type: \"button\",\n text: { type: \"plain_text\", text: \"Deny\" },\n style: \"danger\",\n url: url.replace(\"/approve/\", \"/deny/\"),\n },\n ],\n });\n }\n return { text, blocks };\n}\n\nexport function haltSlackMessage(event: GuardEvent): { text: string; blocks: unknown[] } {\n const cause = event.error?.cause ?? \"\";\n const text = `[agentguard] ${event.type}: ${event.tool} (run ${event.runId}) — ${cause}`;\n return {\n text,\n blocks: [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*${event.type}* on \\`${event.tool}\\` (run \\`${event.runId}\\`)\\n${cause}`,\n },\n },\n {\n type: \"context\",\n elements: [\n {\n type: \"mrkdwn\",\n text: `\\`agentguard report --run ${event.runId}\\` for the full picture${event.type === \"KILLED\" ? \"\" : \" · `agentguard kill` to stop everything\"}`,\n },\n ],\n },\n ],\n };\n}\n\n/** Returns a `Guard.onEvent` handler. Never throws; failures are logged. */\nexport function createAlerter(opts: AlerterOptions): (event: GuardEvent) => Promise<void> {\n const { policy } = opts;\n const log = opts.log ?? (() => undefined);\n const channel = { fetch: opts.fetch };\n return async (event) => {\n if (event.type === \"APPROVAL_DECIDED\") return;\n if (!policy.alerts.on.includes(event.type)) return;\n const slack =\n event.type === \"APPROVAL_REQUIRED\"\n ? policy.approval.notify.slack || policy.alerts.slack\n : policy.alerts.slack;\n const webhook =\n event.type === \"APPROVAL_REQUIRED\"\n ? policy.approval.notify.webhook || policy.alerts.webhook\n : policy.alerts.webhook;\n const url = event.approval ? opts.approvalUrl?.(event.approval) : undefined;\n const message =\n event.type === \"APPROVAL_REQUIRED\" && event.approval\n ? approvalSlackMessage(event, url)\n : haltSlackMessage(event);\n const jobs: Promise<unknown>[] = [];\n if (slack) {\n jobs.push(\n sendSlack(slack, message, channel).then((r) => {\n if (!r.ok) log(`slack alert failed: ${r.error ?? r.status}`);\n }),\n );\n }\n if (webhook) {\n jobs.push(\n sendWebhook(\n webhook,\n {\n event: event.type,\n product: \"agentguard\",\n subject: message.text,\n summary: event.error?.cause ?? \"\",\n occurredAt: event.at,\n data: {\n runId: event.runId,\n tool: event.tool,\n error: event.error,\n approval: event.approval,\n approveUrl: url,\n },\n },\n channel,\n ).then((r) => {\n if (!r.ok) log(`webhook alert failed: ${r.error ?? r.status}`);\n }),\n );\n }\n await Promise.all(jobs);\n };\n}\n","/**\n * Shared CLI plumbing: locate and load the policy, build the file-backed guard, print things.\n */\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { Guard, type ApprovalRecord, type GuardEvent } from \"@agentwares/agentguard-core\";\nimport {\n FileApprovalStore,\n FileAuditSink,\n FileKillSwitch,\n FileStateStore,\n loadPolicyFile,\n type LoadedPolicy,\n} from \"@agentwares/agentguard-core/node\";\nimport { existsSync as exists, readFileSync } from \"node:fs\";\nimport { registrationPath, type HttpRegistration } from \"./registration.js\";\nimport { createAlerter } from \"./notify.js\";\nimport { flagString, type ParsedArgs } from \"./args.js\";\n\nexport const DEFAULT_POLICY_FILE = \"agentguard.yaml\";\n\nimport { homedir } from \"node:os\";\n\nexport interface Io {\n out: (line: string) => void;\n err: (line: string) => void;\n cwd: string;\n env: NodeJS.ProcessEnv;\n /** false when stdout is a pipe — an MCP client spawned us and wants a server, not the help text */\n tty?: boolean;\n /** everything on stdin (hook mode reads the harness's JSON from it) */\n stdin?: () => Promise<string>;\n}\n\n/** Read stdin to the end, at most `maxBytes`, giving up after `timeoutMs`. Empty on a terminal. */\nexport function readStdin(maxBytes = 16 * 1024 * 1024, timeoutMs = 10_000): Promise<string> {\n if (process.stdin.isTTY) return Promise.resolve(\"\");\n return new Promise((resolveText) => {\n const chunks: Buffer[] = [];\n let size = 0;\n const done = (): void => {\n clearTimeout(timer);\n process.stdin.removeAllListeners(\"data\");\n process.stdin.removeAllListeners(\"end\");\n process.stdin.pause();\n resolveText(Buffer.concat(chunks).toString(\"utf8\"));\n };\n const timer = setTimeout(done, timeoutMs);\n process.stdin.on(\"data\", (chunk: Buffer) => {\n size += chunk.length;\n if (size <= maxBytes) chunks.push(chunk);\n });\n process.stdin.on(\"end\", done);\n process.stdin.on(\"error\", done);\n });\n}\n\n/**\n * The user's home directory as this invocation sees it. Reads `io.env` rather than\n * calling homedir() so an injected environment is honoured — without this, tests\n * (and any sandboxed run) silently read the real user's client configs.\n */\nexport function homeFrom(io: Io): string {\n return io.env.HOME ?? io.env.USERPROFILE ?? homedir();\n}\n\nexport function defaultIo(): Io {\n return {\n out: (line) => process.stdout.write(line + \"\\n\"),\n err: (line) => process.stderr.write(line + \"\\n\"),\n cwd: process.cwd(),\n env: process.env,\n tty: process.stdout.isTTY === true,\n stdin: () => readStdin(),\n };\n}\n\nexport function policyPathFrom(args: ParsedArgs, io: Io): string {\n return resolve(\n io.cwd,\n flagString(args, \"config\") ?? io.env.AGENTGUARD_CONFIG ?? DEFAULT_POLICY_FILE,\n );\n}\n\nexport function loadPolicyFor(\n args: ParsedArgs,\n io: Io,\n opts: { allowMissingEnv?: boolean } = {},\n): LoadedPolicy {\n return loadPolicyFile(policyPathFrom(args, io), {\n env: io.env,\n allowMissingEnv: opts.allowMissingEnv,\n });\n}\n\nexport interface FileGuard {\n guard: Guard;\n kill: FileKillSwitch;\n audit: FileAuditSink;\n approvals: FileApprovalStore;\n loaded: LoadedPolicy;\n}\n\n/** A guard wired to the state dir, audit file, KILL file and approvals of a loaded policy. */\nexport function createFileGuard(\n loaded: LoadedPolicy,\n opts: {\n onEvent?: (e: GuardEvent) => void | Promise<void>;\n approvalUrl?: (r: ApprovalRecord) => string | undefined;\n log?: (line: string) => void;\n alerts?: boolean;\n env?: NodeJS.ProcessEnv;\n } = {},\n): FileGuard {\n const kill = new FileKillSwitch(loaded.killPath);\n const audit = new FileAuditSink(loaded.auditPath);\n const approvals = new FileApprovalStore(loaded.stateDir);\n const alerter =\n opts.alerts === false\n ? undefined\n : createAlerter({ policy: loaded.policy, approvalUrl: opts.approvalUrl, log: opts.log });\n const guard = new Guard({\n policy: loaded.policy,\n state: new FileStateStore(loaded.stateDir),\n audit,\n kill,\n approvals,\n env: opts.env ?? process.env,\n approvalUrl: opts.approvalUrl,\n onEvent: async (event) => {\n await opts.onEvent?.(event);\n await alerter?.(event);\n },\n });\n return { guard, kill, audit, approvals, loaded };\n}\n\n/** A running HTTP proxy for this policy, if one registered itself. */\nexport function readRegistration(loaded: LoadedPolicy): HttpRegistration | undefined {\n const file = registrationPath(loaded.stateDir);\n if (!exists(file)) return undefined;\n try {\n const reg = JSON.parse(readFileSync(file, \"utf8\")) as HttpRegistration;\n return reg;\n } catch {\n return undefined;\n }\n}\n\nexport function approvalUrlFor(\n reg: HttpRegistration | undefined,\n): ((r: ApprovalRecord) => string | undefined) | undefined {\n if (!reg) return undefined;\n return (r) => `${reg.baseUrl}/approve/${r.id}?token=${reg.token}`;\n}\n\nexport function fileExists(path: string): boolean {\n return existsSync(path);\n}\n\nexport function describeError(err: unknown): string {\n if (err && typeof err === \"object\" && \"code\" in err && \"cause\" in err) {\n const e = err as { code: string; cause: string; fix?: string };\n return `${e.code}: ${e.cause}${e.fix ? `\\n fix: ${e.fix}` : \"\"}`;\n }\n return err instanceof Error ? err.message : String(err);\n}\n"],"mappings":"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","names":["Coder","URLSafeCoder","exports","Hash","HMAC","hmac","Webhook","encoder","version","version","version","readFileSync","readFileSync"]}
|