@agentwares/agentguard 0.1.7 → 0.1.10
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 +108 -0
- package/README.md +223 -16
- package/dist/audit-5LUDXZLG.js +18 -0
- package/dist/audit-5LUDXZLG.js.map +1 -0
- package/dist/chunk-2QDPPTPY.js +179 -0
- package/dist/chunk-2QDPPTPY.js.map +1 -0
- package/dist/chunk-4WTFMFRY.js +1270 -0
- package/dist/chunk-4WTFMFRY.js.map +1 -0
- package/dist/chunk-5WRI5ZAA.js +31 -0
- package/dist/chunk-5WRI5ZAA.js.map +1 -0
- package/dist/chunk-DEVXG3IB.js +113 -0
- package/dist/chunk-DEVXG3IB.js.map +1 -0
- package/dist/chunk-F73VDY3W.js +202 -0
- package/dist/chunk-F73VDY3W.js.map +1 -0
- package/dist/chunk-IEJK7N3B.js +275 -0
- package/dist/chunk-IEJK7N3B.js.map +1 -0
- package/dist/chunk-IS3DAHZI.js +1698 -0
- package/dist/chunk-IS3DAHZI.js.map +1 -0
- package/dist/chunk-JSELR4SG.js +780 -0
- package/dist/chunk-JSELR4SG.js.map +1 -0
- package/dist/chunk-OM5L7A32.js +199 -0
- package/dist/chunk-OM5L7A32.js.map +1 -0
- package/dist/chunk-SWZQMPDG.js +206 -0
- package/dist/chunk-SWZQMPDG.js.map +1 -0
- package/dist/chunk-TJXZBOHL.js +529 -0
- package/dist/chunk-TJXZBOHL.js.map +1 -0
- package/dist/chunk-XOBFANL4.js +119 -0
- package/dist/chunk-XOBFANL4.js.map +1 -0
- package/dist/chunk-XPNBYSIN.js +23 -0
- package/dist/chunk-XPNBYSIN.js.map +1 -0
- package/dist/chunk-YBVD6HTT.js +1036 -0
- package/dist/chunk-YBVD6HTT.js.map +1 -0
- package/dist/chunk-ZG4LGUJE.js +847 -0
- package/dist/chunk-ZG4LGUJE.js.map +1 -0
- package/dist/cli.js +10 -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 +73 -14
- package/dist/index.js +247 -5138
- package/dist/index.js.map +1 -1
- package/dist/init-MKPQU2JG.js +17 -0
- package/dist/init-MKPQU2JG.js.map +1 -0
- package/dist/proxy-6GP63TLD.js +146 -0
- package/dist/proxy-6GP63TLD.js.map +1 -0
- package/dist/tools-XS7PMTLT.js +15 -0
- package/dist/tools-XS7PMTLT.js.map +1 -0
- package/llms.txt +10 -4
- package/package.json +16 -4
- package/server.json +9 -9
package/dist/index.js.map
CHANGED
|
@@ -1 +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/proxy/runtime.ts","../src/version.ts","../../../packages/mcp-kit/src/errors.ts","../../../packages/mcp-kit/src/tool.ts","../../../packages/mcp-kit/src/conformance-fixtures.ts","../../../packages/mcp-kit/src/payment.ts","../../../packages/mcp-kit/src/example.ts","../../../packages/mcp-kit/src/server.ts","../../../packages/mcp-kit/src/http.ts","../../../packages/mcp-kit/src/node-http.ts","../../../packages/x402/src/facilitator.ts","../../../packages/x402/src/index.ts","../../../packages/mcp-kit/src/paging.ts","../../../packages/mcp-kit/src/stdio.ts","../../../packages/mcp-kit/src/registry.ts","../../../packages/mcp-kit/src/docs.ts","../../../packages/mcp-kit/src/discovery.ts","../src/proxy/server.ts","../src/proxy/own-tools.ts","../src/proxy/http.ts","../src/context.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/args.ts","../src/configs.ts","../src/commands/init.ts","../src/commands/tools.ts","../src/commands/permission-diff.ts","../src/fixtures/crm-server.ts","../src/fixtures/demo-agent.ts","../src/commands/connect.ts","../src/commands/control.ts","../src/commands/keys.ts","../src/commands/proxy.ts","../src/commands/report.ts","../src/cli.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,"/**\n * Upstream side of the proxy: one MCP client per upstream (stdio or Streamable HTTP), the merged\n * tool table, resource/prompt routing, notification fan-out to downstream sessions, and\n * `callTool` through the policy engine.\n */\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { version as cliVersion } from \"../version.js\";\nimport {\n getDefaultEnvironment,\n StdioClientTransport,\n} from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport {\n CreateMessageRequestSchema,\n ElicitRequestSchema,\n LoggingMessageNotificationSchema,\n PromptListChangedNotificationSchema,\n ResourceListChangedNotificationSchema,\n ResourceUpdatedNotificationSchema,\n ToolListChangedNotificationSchema,\n type CallToolResult,\n type CompleteRequest,\n type CompleteResult,\n type GetPromptResult,\n type ListPromptsResult,\n type ListResourceTemplatesResult,\n type ListResourcesResult,\n type LoggingLevel,\n type Prompt,\n type ReadResourceResult,\n type Resource,\n type ResourceTemplate,\n type Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { RequestId } from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n GuardError,\n classifyTool,\n upstreamHeaders,\n type AgentScope,\n type Classification,\n type Guard,\n type GuardResult,\n type Upstream,\n} from \"@agentwares/agentguard-core\";\nimport type { LoadedPolicy } from \"@agentwares/agentguard-core/node\";\n// The root export, not `@agentwares/mcp-kit/paging`: tsup bundles mcp-kit into the published CLI\n// by an exact-name match, and a subpath would be left as an undeclared runtime dependency.\nimport { readAllPages } from \"@agentwares/mcp-kit\";\n\nexport interface ExposedTool {\n /** the name the agent sees */\n name: string;\n upstream: string;\n /** the name the upstream knows */\n original: string;\n tool: Tool;\n classification: Classification;\n}\n\nexport interface DownstreamSession {\n id: string;\n server: McpServer;\n lastActive: number;\n /** upstream name → downstream request ids currently waiting on it (newest last) */\n inflight: Map<string, RequestId[]>;\n}\n\nexport interface UpstreamStatus {\n name: string;\n connected: boolean;\n tools: number;\n transport: \"stdio\" | \"http\";\n error?: string;\n}\n\ninterface Connection {\n upstream: Upstream;\n client: Client;\n tools: Tool[];\n capabilities: ReturnType<Client[\"getServerCapabilities\"]>;\n connected: boolean;\n error?: string;\n}\n\nexport interface RuntimeOptions {\n loaded: LoadedPolicy;\n guard: Guard;\n /** fixed agent scope for stdio (`--agent`) */\n agent?: AgentScope | null;\n /** run id when neither `X-Run-Id` nor `_meta.runId` is present */\n defaultRunId: string;\n log?: (line: string) => void;\n /** connect timeout per upstream (ms) */\n connectTimeoutMs?: number;\n /** in-process upstreams for tests: name → already-connected client */\n clients?: Record<string, Client>;\n /**\n * false when no policy file was found and the proxy runs on the default policy with no\n * upstreams, serving only its own read-only tools (default true)\n */\n configured?: boolean;\n}\n\nexport interface CallContext {\n runId: string;\n agent?: AgentScope | null;\n sessionId?: string;\n onprogress?: (progress: { progress: number; total?: number; message?: string }) => void;\n /** downstream session + request id, so upstream notifications can be related to this call */\n session?: DownstreamSession;\n requestId?: RequestId;\n}\n\nexport class ProxyRuntime {\n readonly loaded: LoadedPolicy;\n readonly guard: Guard;\n readonly agent: AgentScope | null | undefined;\n readonly defaultRunId: string;\n readonly configured: boolean;\n readonly sessions = new Set<DownstreamSession>();\n private readonly connections = new Map<string, Connection>();\n private exposed: ExposedTool[] = [];\n private readonly resourceOwner = new Map<string, string>();\n private readonly templateOwner = new Map<string, string>();\n private readonly promptOwner = new Map<string, { upstream: string; original: string }>();\n private readonly log: (line: string) => void;\n private readonly connectTimeoutMs: number;\n private readonly testClients: Record<string, Client>;\n /** stop relaying upstream stderr once we are tearing down — shutdown noise is not the user's problem */\n private closing = false;\n\n constructor(opts: RuntimeOptions) {\n this.loaded = opts.loaded;\n this.guard = opts.guard;\n this.agent = opts.agent;\n this.defaultRunId = opts.defaultRunId;\n this.configured = opts.configured ?? true;\n this.log = opts.log ?? ((line) => process.stderr.write(`[agentguard] ${line}\\n`));\n this.connectTimeoutMs = opts.connectTimeoutMs ?? 15_000;\n this.testClients = opts.clients ?? {};\n }\n\n get policy() {\n return this.loaded.policy;\n }\n\n async start(): Promise<void> {\n await Promise.all(this.policy.upstreams.map((u) => this.connect(u)));\n for (const [name, client] of Object.entries(this.testClients)) {\n if (this.connections.has(name)) continue;\n const upstream: Upstream = {\n name,\n command: \"in-memory\",\n args: [],\n env: {},\n headers: {},\n prefix: false,\n timeout_ms: 60_000,\n };\n const conn: Connection = {\n upstream,\n client,\n tools: [],\n capabilities: client.getServerCapabilities(),\n connected: true,\n };\n this.connections.set(name, conn);\n this.wire(conn);\n await this.refreshTools(name);\n }\n this.rebuildExposed();\n const status = this.upstreamStatus();\n this.log(\n `connected ${status.filter((s) => s.connected).length}/${status.length} upstreams, ${this.exposed.length} tools, mode ${this.policy.mode}`,\n );\n }\n\n private async connect(upstream: Upstream): Promise<void> {\n const client = new Client(\n { name: \"agentguard\", version: cliVersion() },\n { capabilities: { sampling: {}, elicitation: {} } },\n );\n const conn: Connection = {\n upstream,\n client,\n tools: [],\n capabilities: undefined,\n connected: false,\n };\n this.connections.set(upstream.name, conn);\n try {\n const transport = upstream.url\n ? new StreamableHTTPClientTransport(new URL(upstream.url), {\n requestInit: { headers: upstreamHeaders(upstream) },\n })\n : new StdioClientTransport({\n command: upstream.command!,\n args: upstream.args,\n env: { ...getDefaultEnvironment(), ...upstream.env },\n cwd: upstream.cwd,\n stderr: \"pipe\",\n });\n if (transport instanceof StdioClientTransport) {\n transport.stderr?.on(\"data\", (chunk: Buffer) => {\n if (this.closing) return;\n for (const line of chunk.toString(\"utf8\").split(\"\\n\"))\n if (line.trim()) this.log(`${upstream.name}: ${line}`);\n });\n }\n await withTimeout(\n client.connect(transport),\n this.connectTimeoutMs,\n `connect to upstream \"${upstream.name}\"`,\n );\n conn.capabilities = client.getServerCapabilities();\n conn.connected = true;\n this.wire(conn);\n await this.refreshTools(upstream.name);\n } catch (err) {\n conn.connected = false;\n conn.error = err instanceof Error ? err.message : String(err);\n this.log(`upstream \"${upstream.name}\" unavailable: ${conn.error}`);\n }\n }\n\n private wire(conn: Connection): void {\n const { client, upstream } = conn;\n client.onclose = () => {\n conn.connected = false;\n conn.error = \"connection closed\";\n if (!this.closing) this.log(`upstream \"${upstream.name}\" closed`);\n };\n client.setNotificationHandler(LoggingMessageNotificationSchema, async (n) => {\n await this.broadcast(upstream.name, n.method, n.params);\n });\n client.setNotificationHandler(ResourceUpdatedNotificationSchema, async (n) => {\n await this.broadcast(upstream.name, n.method, n.params);\n });\n client.setNotificationHandler(ResourceListChangedNotificationSchema, async () => {\n this.resourceOwner.clear();\n await this.broadcast(upstream.name, \"notifications/resources/list_changed\", undefined);\n });\n client.setNotificationHandler(PromptListChangedNotificationSchema, async () => {\n this.promptOwner.clear();\n await this.broadcast(upstream.name, \"notifications/prompts/list_changed\", undefined);\n });\n client.setNotificationHandler(ToolListChangedNotificationSchema, async () => {\n await this.refreshTools(upstream.name);\n this.rebuildExposed();\n for (const s of this.sessions) s.server.server.sendToolListChanged().catch(() => undefined);\n });\n // Relay server→client requests (sampling, elicitation) to the downstream session that is\n // waiting on this upstream. Clients created without those capabilities (tests) skip this.\n try {\n client.setRequestHandler(CreateMessageRequestSchema, async (req) => {\n const session = this.pickSession(upstream.name);\n if (!session) throw new Error(\"no downstream client is connected to relay sampling to\");\n const related = session.inflight.get(upstream.name)?.at(-1);\n return session.server.server.createMessage(req.params, { relatedRequestId: related });\n });\n client.setRequestHandler(ElicitRequestSchema, async (req) => {\n const session = this.pickSession(upstream.name);\n if (!session) throw new Error(\"no downstream client is connected to relay elicitation to\");\n const related = session.inflight.get(upstream.name)?.at(-1);\n return session.server.server.elicitInput(req.params, { relatedRequestId: related });\n });\n } catch {\n // client declared no sampling/elicitation capability\n }\n }\n\n private pickSession(upstream: string): DownstreamSession | undefined {\n let best: DownstreamSession | undefined;\n for (const s of this.sessions) {\n if ((s.inflight.get(upstream)?.length ?? 0) > 0) return s;\n if (!best || s.lastActive > best.lastActive) best = s;\n }\n return best;\n }\n\n private async broadcast(upstream: string, method: string, params: unknown): Promise<void> {\n for (const s of this.sessions) {\n const related = s.inflight.get(upstream)?.at(-1);\n try {\n await s.server.server.notification(\n { method, params: params as Record<string, unknown> | undefined },\n related !== undefined ? { relatedRequestId: related } : undefined,\n );\n } catch {\n // session gone\n }\n }\n }\n\n /**\n * Re-read an upstream's tools, every page (mcp-kit's `readAllPages`): at most 20 requests, each\n * under the upstream's `timeout_ms`, ending at a cursor already followed. It used to follow\n * `nextCursor` with no bound, so an upstream that echoed its cursor kept the proxy asking for\n * the same page forever. A refresh that fails, or stops at the 20-page / 2,000-tool ceiling,\n * changes nothing: the agent keeps the last good list, and the log says why.\n */\n private async refreshTools(name: string): Promise<void> {\n const conn = this.connections.get(name);\n if (!conn?.connected) return;\n if (conn.capabilities && !conn.capabilities.tools) {\n conn.tools = [];\n return;\n }\n const kept = () =>\n `keeping the last good list (${conn.tools.length} tool${conn.tools.length === 1 ? \"\" : \"s\"})`;\n try {\n const read = await readAllPages<Tool>(async (cursor) => {\n const page = await conn.client.listTools(cursor ? { cursor } : undefined, {\n timeout: conn.upstream.timeout_ms,\n });\n return { items: page.tools, nextCursor: page.nextCursor };\n });\n if (read.truncated) {\n this.log(`tools/list for \"${name}\" not applied: ${read.truncated.reason}; ${kept()}`);\n return;\n }\n conn.tools = read.items;\n } catch (err) {\n this.log(\n `tools/list failed for \"${name}\": ${err instanceof Error ? err.message : String(err)}; ${kept()}`,\n );\n }\n }\n\n private rebuildExposed(): void {\n const taken = new Set<string>();\n const out: ExposedTool[] = [];\n const order = [...this.policy.upstreams.map((u) => u.name), ...Object.keys(this.testClients)];\n for (const name of order) {\n const conn = this.connections.get(name);\n if (!conn) continue;\n const prefix =\n conn.upstream.prefix === true\n ? name\n : typeof conn.upstream.prefix === \"string\"\n ? conn.upstream.prefix\n : undefined;\n for (const tool of conn.tools) {\n let exposedName = prefix ? `${prefix}__${tool.name}` : tool.name;\n if (taken.has(exposedName)) exposedName = `${name}__${tool.name}`;\n if (taken.has(exposedName)) {\n this.log(`skipping duplicate tool ${exposedName} from ${name}`);\n continue;\n }\n taken.add(exposedName);\n out.push({\n name: exposedName,\n upstream: name,\n original: tool.name,\n tool,\n classification: classifyTool(\n {\n name: exposedName,\n description: tool.description,\n annotations: tool.annotations,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema,\n },\n this.policy,\n ),\n });\n }\n }\n this.exposed = out;\n }\n\n listTools(agent?: AgentScope | null): ExposedTool[] {\n if (agent?.upstreams) return this.exposed.filter((t) => agent.upstreams!.includes(t.upstream));\n return this.exposed;\n }\n\n findTool(name: string): ExposedTool | undefined {\n return this.exposed.find((t) => t.name === name);\n }\n\n upstreamStatus(): UpstreamStatus[] {\n return [...this.connections.values()].map((c) => ({\n name: c.upstream.name,\n connected: c.connected,\n tools: c.tools.length,\n transport: c.upstream.url ? \"http\" : \"stdio\",\n error: c.error,\n }));\n }\n\n attach(session: DownstreamSession): void {\n this.sessions.add(session);\n }\n detach(session: DownstreamSession): void {\n this.sessions.delete(session);\n }\n\n /** Run a tool call through the policy engine and, if allowed, the upstream. */\n async callTool(\n name: string,\n args: unknown,\n ctx: CallContext,\n ): Promise<{ result: GuardResult; tool?: ExposedTool }> {\n const tool = this.findTool(name);\n const agent = ctx.agent === undefined ? this.agent : ctx.agent;\n if (!tool) {\n const result = await this.guard.run(\n { tool: { name }, args, runId: ctx.runId, agent, sessionId: ctx.sessionId },\n async () => {\n throw new GuardError({\n code: \"UNKNOWN_TOOL\",\n cause: `no upstream exposes a tool named \"${name}\"`,\n fix: \"call tools/list and use one of the listed names\",\n retryable: false,\n });\n },\n );\n return { result };\n }\n const conn = this.connections.get(tool.upstream);\n const track = (): (() => void) => {\n if (!ctx.session || ctx.requestId === undefined) return () => undefined;\n const list = ctx.session.inflight.get(tool.upstream) ?? [];\n list.push(ctx.requestId);\n ctx.session.inflight.set(tool.upstream, list);\n return () => {\n const l = ctx.session!.inflight.get(tool.upstream) ?? [];\n const i = l.indexOf(ctx.requestId!);\n if (i >= 0) l.splice(i, 1);\n };\n };\n const result = await this.guard.run(\n {\n tool: {\n name: tool.name,\n description: tool.tool.description,\n annotations: tool.tool.annotations,\n inputSchema: tool.tool.inputSchema,\n outputSchema: tool.tool.outputSchema,\n },\n args,\n runId: ctx.runId,\n agent,\n sessionId: ctx.sessionId,\n upstream: tool.upstream,\n },\n async (finalArgs) => {\n if (!conn?.connected) {\n throw new GuardError({\n code: \"UPSTREAM_ERROR\",\n cause: `upstream \"${tool.upstream}\" is not connected${conn?.error ? ` (${conn.error})` : \"\"}`,\n fix: \"check the upstream command/url in agentguard.yaml and restart the proxy\",\n retryable: true,\n });\n }\n const untrack = track();\n try {\n return (await conn.client.callTool(\n { name: tool.original, arguments: (finalArgs ?? {}) as Record<string, unknown> },\n undefined,\n {\n timeout: conn.upstream.timeout_ms,\n resetTimeoutOnProgress: true,\n onprogress: ctx.onprogress,\n },\n )) as CallToolResult;\n } finally {\n untrack();\n }\n },\n );\n return { result, tool };\n }\n\n private connectedWith(\n capability: \"resources\" | \"prompts\" | \"completions\" | \"logging\",\n ): Connection[] {\n return [...this.connections.values()].filter(\n (c) => c.connected && (c.capabilities?.[capability] || c.capabilities === undefined),\n );\n }\n\n async listResources(): Promise<ListResourcesResult> {\n const resources: Resource[] = [];\n for (const conn of this.connectedWith(\"resources\")) {\n try {\n const page = await conn.client.listResources(undefined, {\n timeout: conn.upstream.timeout_ms,\n });\n for (const r of page.resources) {\n this.resourceOwner.set(r.uri, conn.upstream.name);\n resources.push(r);\n }\n } catch {\n // upstream has no resources\n }\n }\n return { resources };\n }\n\n async listResourceTemplates(): Promise<ListResourceTemplatesResult> {\n const resourceTemplates: ResourceTemplate[] = [];\n for (const conn of this.connectedWith(\"resources\")) {\n try {\n const page = await conn.client.listResourceTemplates(undefined, {\n timeout: conn.upstream.timeout_ms,\n });\n for (const t of page.resourceTemplates) {\n this.templateOwner.set(t.uriTemplate, conn.upstream.name);\n resourceTemplates.push(t);\n }\n } catch {\n // none\n }\n }\n return { resourceTemplates };\n }\n\n private ownerForUri(uri: string): Connection[] {\n const owner = this.resourceOwner.get(uri);\n if (owner && this.connections.get(owner)?.connected) return [this.connections.get(owner)!];\n for (const [template, name] of this.templateOwner) {\n if (templateMatches(template, uri) && this.connections.get(name)?.connected)\n return [this.connections.get(name)!];\n }\n return this.connectedWith(\"resources\");\n }\n\n async readResource(uri: string): Promise<ReadResourceResult> {\n let lastError: unknown;\n for (const conn of this.ownerForUri(uri)) {\n try {\n const result = await conn.client.readResource(\n { uri },\n { timeout: conn.upstream.timeout_ms },\n );\n this.resourceOwner.set(uri, conn.upstream.name);\n return result;\n } catch (err) {\n lastError = err;\n }\n }\n throw lastError ?? new Error(`no upstream serves resource ${uri}`);\n }\n\n async subscribe(uri: string, on: boolean): Promise<void> {\n for (const conn of this.ownerForUri(uri)) {\n try {\n if (on) await conn.client.subscribeResource({ uri });\n else await conn.client.unsubscribeResource({ uri });\n return;\n } catch {\n // try next\n }\n }\n }\n\n async listPrompts(): Promise<ListPromptsResult> {\n const prompts: Prompt[] = [];\n const taken = new Set<string>();\n this.promptOwner.clear();\n for (const conn of this.connectedWith(\"prompts\")) {\n try {\n const page = await conn.client.listPrompts(undefined, {\n timeout: conn.upstream.timeout_ms,\n });\n for (const p of page.prompts) {\n const name = taken.has(p.name) ? `${conn.upstream.name}__${p.name}` : p.name;\n taken.add(name);\n this.promptOwner.set(name, { upstream: conn.upstream.name, original: p.name });\n prompts.push({ ...p, name });\n }\n } catch {\n // none\n }\n }\n return { prompts };\n }\n\n async getPrompt(\n name: string,\n args: Record<string, string> | undefined,\n ): Promise<GetPromptResult> {\n if (this.promptOwner.size === 0) await this.listPrompts();\n const owner = this.promptOwner.get(name);\n const conns = owner ? [this.connections.get(owner.upstream)!] : this.connectedWith(\"prompts\");\n let lastError: unknown;\n for (const conn of conns) {\n try {\n return await conn.client.getPrompt(\n { name: owner?.original ?? name, arguments: args },\n { timeout: conn.upstream.timeout_ms },\n );\n } catch (err) {\n lastError = err;\n }\n }\n throw lastError ?? new Error(`no upstream serves prompt ${name}`);\n }\n\n async complete(params: CompleteRequest[\"params\"]): Promise<CompleteResult> {\n let conns: Connection[];\n if (params.ref.type === \"ref/prompt\") {\n if (this.promptOwner.size === 0) await this.listPrompts();\n const owner = this.promptOwner.get(params.ref.name);\n conns = owner ? [this.connections.get(owner.upstream)!] : this.connectedWith(\"completions\");\n if (owner) params = { ...params, ref: { ...params.ref, name: owner.original } };\n } else {\n if (this.templateOwner.size === 0) await this.listResourceTemplates();\n conns = this.ownerForUri(params.ref.uri);\n }\n let lastError: unknown;\n for (const conn of conns) {\n try {\n return await conn.client.complete(params, { timeout: conn.upstream.timeout_ms });\n } catch (err) {\n lastError = err;\n }\n }\n throw lastError ?? new Error(\"no upstream supports completions\");\n }\n\n async setLevel(level: LoggingLevel): Promise<void> {\n await Promise.all(\n this.connectedWith(\"logging\").map((c) =>\n c.client.setLoggingLevel(level).catch(() => undefined),\n ),\n );\n }\n\n async close(): Promise<void> {\n this.closing = true;\n for (const conn of this.connections.values()) {\n try {\n await conn.client.close();\n } catch {\n // already closed\n }\n }\n this.connections.clear();\n }\n}\n\nfunction templateMatches(template: string, uri: string): boolean {\n const re = new RegExp(\n \"^\" + template.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\\\\\{[^}]+\\\\\\}/g, \"[^/]+\") + \"$\",\n );\n return re.test(uri);\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, ms: number, what: string): Promise<T> {\n let timer: NodeJS.Timeout | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(`${what} timed out after ${ms}ms`)), ms);\n });\n try {\n return await Promise.race([promise, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\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 * Structured tool errors. Every error an agent sees carries `code`, `cause`, `fix` and\n * `retryable` (CLAUDE.md \"Writing for agents\") so the caller can decide what to do next\n * without reading prose.\n */\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\n\n/** Standard error codes. Products may add their own (e.g. `MONITOR_PAUSED`). */\nexport const ERROR_CODES = [\n \"INVALID_INPUT\",\n \"NOT_FOUND\",\n \"UNAUTHORIZED\",\n \"PAYMENT_REQUIRED\",\n \"RATE_LIMITED\",\n \"UPSTREAM_ERROR\",\n \"INTERNAL\",\n] as const;\n\nexport type StandardErrorCode = (typeof ERROR_CODES)[number];\n/** A standard code, or a product-specific UPPER_SNAKE code. */\nexport type ErrorCode = StandardErrorCode | (string & Record<never, never>);\n\n/** Wire shape of every error body (tool result text, structuredContent and HTTP JSON alike). */\nexport type ToolErrorBody = {\n code: string;\n /** what went wrong, in one sentence */\n cause: string;\n /** what the caller should do next */\n fix: string;\n /** whether the same call can succeed on retry without changes */\n retryable: boolean;\n /** machine-readable specifics, e.g. validation issues */\n details?: unknown;\n [extra: string]: unknown;\n};\n\nexport interface ToolErrorInit {\n code: ErrorCode;\n cause: string;\n fix: string;\n /** Defaults per code: PAYMENT_REQUIRED, RATE_LIMITED, UPSTREAM_ERROR are retryable; the rest are not. */\n retryable?: boolean;\n details?: unknown;\n /** HTTP status to use when the error is surfaced over plain HTTP. Defaults per code. */\n httpStatus?: number;\n /** Extra top-level fields merged into the serialized body (e.g. a 402's `accepts`). */\n extra?: Record<string, unknown>;\n}\n\nexport const DEFAULT_RETRYABLE: Readonly<Record<StandardErrorCode, boolean>> = {\n INVALID_INPUT: false,\n NOT_FOUND: false,\n UNAUTHORIZED: false,\n PAYMENT_REQUIRED: true,\n RATE_LIMITED: true,\n UPSTREAM_ERROR: true,\n INTERNAL: false,\n};\n\nexport const DEFAULT_HTTP_STATUS: Readonly<Record<StandardErrorCode, number>> = {\n INVALID_INPUT: 400,\n NOT_FOUND: 404,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n RATE_LIMITED: 429,\n UPSTREAM_ERROR: 502,\n INTERNAL: 500,\n};\n\nexport const INTERNAL_FIX = \"retry; if it persists, report the request id\";\n\nfunction isStandardCode(code: string): code is StandardErrorCode {\n return (ERROR_CODES as readonly string[]).includes(code);\n}\n\n/** Throw this (or `toolError(...)`) from a handler to return a structured error to the caller. */\nexport class McpToolError extends Error {\n readonly code: string;\n override readonly cause: string;\n readonly fix: string;\n readonly retryable: boolean;\n readonly details?: unknown;\n readonly httpStatus: number;\n readonly extra?: Record<string, unknown>;\n\n constructor(init: ToolErrorInit) {\n super(`${init.code}: ${init.cause}`);\n this.name = \"McpToolError\";\n this.code = init.code;\n this.cause = init.cause;\n this.fix = init.fix;\n this.retryable =\n init.retryable ?? (isStandardCode(init.code) ? DEFAULT_RETRYABLE[init.code] : false);\n this.details = init.details;\n this.httpStatus =\n init.httpStatus ?? (isStandardCode(init.code) ? DEFAULT_HTTP_STATUS[init.code] : 500);\n this.extra = init.extra;\n }\n\n /** The body agents see: `{ code, cause, fix, retryable, details?, ...extra }`. */\n toJSON(): ToolErrorBody {\n const body: ToolErrorBody = {\n ...this.extra,\n code: this.code,\n cause: this.cause,\n fix: this.fix,\n retryable: this.retryable,\n };\n if (this.details !== undefined) body.details = this.details;\n return body;\n }\n}\n\n/** Build a structured error. Object form or `(code, cause, fix, extra?)`. */\nexport function toolError(init: ToolErrorInit): McpToolError;\nexport function toolError(\n code: ErrorCode,\n cause: string,\n fix: string,\n extra?: Omit<ToolErrorInit, \"code\" | \"cause\" | \"fix\">,\n): McpToolError;\nexport function toolError(\n codeOrInit: ErrorCode | ToolErrorInit,\n cause?: string,\n fix?: string,\n extra?: Omit<ToolErrorInit, \"code\" | \"cause\" | \"fix\">,\n): McpToolError {\n if (typeof codeOrInit === \"object\") return new McpToolError(codeOrInit);\n return new McpToolError({ code: codeOrInit, cause: cause ?? \"\", fix: fix ?? \"\", ...extra });\n}\n\nfunction describeUnknown(err: unknown): string {\n if (err instanceof Error) return err.message || err.name;\n if (typeof err === \"string\") return err;\n try {\n return JSON.stringify(err);\n } catch {\n return String(err);\n }\n}\n\n/** Coerce anything thrown into a `McpToolError`. Unknown errors become `INTERNAL`. */\nexport function normalizeError(err: unknown): McpToolError {\n if (err instanceof McpToolError) return err;\n return new McpToolError({\n code: \"INTERNAL\",\n cause: describeUnknown(err),\n fix: INTERNAL_FIX,\n retryable: false,\n });\n}\n\nexport interface ErrorResultOptions {\n /** Echoed in `_meta.requestId` so \"report the request id\" is actionable. */\n requestId?: string;\n /** Merged into `_meta` (always includes `httpStatus`). */\n meta?: Record<string, unknown>;\n}\n\n/**\n * Turn an error into a `CallToolResult` with `isError: true`. `content[0].text` is the JSON\n * body and `structuredContent` is the same object, so both text-only and structured clients\n * see `{ code, cause, fix, retryable }`.\n */\nexport function errorResult(err: unknown, opts: ErrorResultOptions = {}): CallToolResult {\n const error = normalizeError(err);\n const body = error.toJSON();\n const meta: Record<string, unknown> = { httpStatus: error.httpStatus };\n if (opts.requestId !== undefined) meta.requestId = opts.requestId;\n Object.assign(meta, opts.meta);\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(body) }],\n structuredContent: body,\n _meta: meta,\n };\n}\n\n/** True when a result is an error result produced by this kit (or shaped like one). */\nexport function isErrorResult(result: CallToolResult): boolean {\n return result.isError === true;\n}\n\n/** Read the `{ code, cause, fix, retryable }` body out of a tool result, if it is an error. */\nexport function readErrorBody(result: CallToolResult): ToolErrorBody | undefined {\n if (result.isError !== true) return undefined;\n const structured = result.structuredContent;\n if (structured && typeof structured.code === \"string\") return structured as ToolErrorBody;\n const first = result.content[0];\n if (first && first.type === \"text\") {\n try {\n const parsed: unknown = JSON.parse(first.text);\n if (parsed && typeof parsed === \"object\" && \"code\" in parsed) return parsed as ToolErrorBody;\n } catch {\n // not JSON\n }\n }\n return undefined;\n}\n","/**\n * `defineTool` — a typed tool definition with a naming lint, zod input validation and\n * structured error results. The same `ToolDef` is served over stdio and Streamable HTTP.\n */\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolResult,\n ServerNotification,\n ServerRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { z } from \"zod\";\nimport { errorResult, toolError, type McpToolError } from \"./errors.js\";\n\n/** MCP tool annotations (hints for clients; not enforced by servers). */\nexport interface ToolAnnotations {\n title?: string;\n /** the tool does not modify anything */\n readOnlyHint?: boolean;\n /** the tool may perform destructive updates (default true when not read-only) */\n destructiveHint?: boolean;\n /** repeated calls with the same arguments have no additional effect */\n idempotentHint?: boolean;\n /** the tool interacts with external entities (default true) */\n openWorldHint?: boolean;\n}\n\nexport type LogLevel =\n \"debug\" | \"info\" | \"notice\" | \"warning\" | \"error\" | \"critical\" | \"alert\" | \"emergency\";\n\n/** Per-call context handed to handlers. Built from the SDK's `extra` by the server adapter. */\nexport interface ToolContext {\n /** HTTP request headers (empty over stdio). Use for `Authorization`, payment headers, etc. */\n headers: Headers;\n /** JSON-RPC request id (string form) — quote it in error reports. */\n requestId?: string;\n /** aborted when the client cancels the request */\n signal?: AbortSignal;\n /** transport session id, when the transport is stateful */\n sessionId?: string;\n /** true when the caller asked for a free sample (set by `withPayment`) */\n sample?: boolean;\n /** set by `withPayment`'s `authorize` when the caller is a known user */\n userId?: string;\n /**\n * The public URL this call arrived at, when it arrived over HTTP.\n *\n * `withPayment` quotes the tool's *name* as the resource by default, which is right for a\n * stdio MCP call and wrong for everything a payment facilitator does with it: a discovery\n * catalog keyed on `realestate_deal_memo` lists something no agent can fetch. An HTTP front\n * door sets this so settlements are attributed to a URL instead.\n */\n resourceUrl?: string;\n /** the request's `_meta` (e.g. `progressToken`) */\n meta?: Record<string, unknown>;\n /** send a log notification to the client (no-op when the transport cannot deliver it) */\n log?: (level: LogLevel, data: unknown) => Promise<void>;\n /** report progress; no-op unless the caller supplied a progress token */\n progress?: (progress: number, total?: number, message?: string) => Promise<void>;\n /**\n * The raw SDK request context — `sendRequest` for sampling (`sampling/createMessage`) and\n * elicitation (`elicitation/create`), `authInfo`, task helpers. Absent when invoked directly.\n */\n extra?: RequestHandlerExtra<ServerRequest, ServerNotification>;\n}\n\n/** Build a context for calling `tool.invoke` directly (tests, cron jobs, in-process use). */\nexport function createToolContext(init: Partial<ToolContext> = {}): ToolContext {\n const { headers, ...rest } = init;\n return { headers: headers ?? new Headers(), ...rest };\n}\n\nexport type ToolInput<TInput extends z.ZodObject> = z.output<TInput>;\nexport type ToolOutput<TOutput> = TOutput extends z.ZodType ? z.output<TOutput> : unknown;\n\nexport interface ToolDef<\n TInput extends z.ZodObject = z.ZodObject,\n TOutput extends z.ZodType | undefined = z.ZodType | undefined,\n> {\n /** `<namespace>_<verb>_<object>`, e.g. `agentcheck_create_monitor` */\n readonly name: string;\n readonly title?: string;\n /** written for a new teammate: what it does, when to use it, what it returns */\n readonly description: string;\n readonly input: TInput;\n /** when given, handler results are validated against it and returned as `structuredContent` */\n readonly output?: TOutput;\n readonly annotations?: ToolAnnotations;\n /** The business logic. Throw `toolError(...)` for structured errors. */\n handler(\n input: z.output<TInput>,\n ctx: ToolContext,\n ): ToolOutput<TOutput> | Promise<ToolOutput<TOutput>>;\n /** Validate raw input, run the handler and shape the result. Never throws. */\n invoke(rawInput: unknown, ctx: ToolContext): Promise<CallToolResult>;\n}\n\nexport interface DefineToolOptions<\n TInput extends z.ZodObject,\n TOutput extends z.ZodType | undefined,\n> {\n name: string;\n title?: string;\n description: string;\n input: TInput;\n output?: TOutput;\n annotations?: ToolAnnotations;\n handler(\n input: z.output<TInput>,\n ctx: ToolContext,\n ): ToolOutput<TOutput> | Promise<ToolOutput<TOutput>>;\n}\n\n/** `namespace_verb_object`: lowercase, digits, single underscores, at least one underscore. */\nexport const TOOL_NAME_PATTERN = /^[a-z][a-z0-9]*(_[a-z0-9]+)+$/;\nexport const MIN_NAMESPACE_LENGTH = 3;\nexport const MIN_DESCRIPTION_LENGTH = 20;\n\nexport function isValidToolName(name: string): boolean {\n if (!TOOL_NAME_PATTERN.test(name)) return false;\n const namespace = name.split(\"_\")[0] ?? \"\";\n return namespace.length >= MIN_NAMESPACE_LENGTH;\n}\n\n/** Naming lint: throws unless `name` is `<namespace>_<verb>_<object>` with a namespace of 3+ chars. */\nexport function assertToolName(name: string): void {\n if (!isValidToolName(name)) {\n throw new Error(\n `tool name must be namespaced: <namespace>_<verb>_<object>, got ${JSON.stringify(name)}`,\n );\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/** A handler may return a ready-made `CallToolResult` (e.g. image/audio content blocks). */\nexport function isCallToolResult(value: unknown): value is CallToolResult {\n if (!isPlainObject(value) || !Array.isArray(value.content)) return false;\n return value.content.every(\n (block: unknown) => isPlainObject(block) && typeof block.type === \"string\",\n );\n}\n\n/** Shape a handler's return value into a `CallToolResult`: JSON text plus `structuredContent`. */\nexport function toCallToolResult(value: unknown): CallToolResult {\n if (isCallToolResult(value)) return value;\n const text = typeof value === \"string\" ? value : JSON.stringify(value ?? null, null, 2);\n const result: CallToolResult = { content: [{ type: \"text\", text }] };\n if (isPlainObject(value)) result.structuredContent = value;\n return result;\n}\n\ninterface IssueLike {\n path: PropertyKey[];\n message: string;\n code?: string;\n}\n\nfunction issuePath(issue: IssueLike): string {\n return issue.path.map(String).join(\".\") || \"(root)\";\n}\n\n/** `INVALID_INPUT` with the offending field names in `fix` and the zod issues in `details`. */\nexport function invalidInputError(issues: readonly IssueLike[]): McpToolError {\n const fields = [...new Set(issues.map(issuePath))];\n const summary = issues.map((issue) => `${issuePath(issue)}: ${issue.message}`).join(\"; \");\n return toolError({\n code: \"INVALID_INPUT\",\n cause: `invalid input for ${fields.join(\", \")} — ${summary}`,\n fix: `fix ${fields.join(\", \")} to match the tool's inputSchema (see details.issues), then retry`,\n retryable: false,\n details: {\n fields,\n issues: issues.map((issue) => ({\n path: issue.path.map(String),\n code: issue.code,\n message: issue.message,\n })),\n },\n });\n}\n\n/**\n * Define a tool. Throws at definition time when the name is not namespaced or the description\n * is too short, so mistakes surface at boot rather than in an agent's transcript.\n */\nexport function defineTool<\n TInput extends z.ZodObject,\n TOutput extends z.ZodType | undefined = undefined,\n>(opts: DefineToolOptions<TInput, TOutput>): ToolDef<TInput, TOutput> {\n assertToolName(opts.name);\n if (\n typeof opts.description !== \"string\" ||\n opts.description.trim().length < MIN_DESCRIPTION_LENGTH\n ) {\n throw new Error(\n `tool ${opts.name}: description must be at least ${MIN_DESCRIPTION_LENGTH} characters — say what it does, when to use it and what it returns`,\n );\n }\n const { name, title, description, input, output, annotations } = opts;\n const handler = opts.handler.bind(opts);\n\n const tool: ToolDef<TInput, TOutput> = {\n name,\n title,\n description,\n input,\n output,\n annotations,\n handler,\n async invoke(rawInput, ctx) {\n // The SDK client validates any structuredContent against the advertised outputSchema, even\n // on error results, so tools with an output schema carry the error body in text only.\n const fail = (err: unknown): CallToolResult => {\n const result = errorResult(err, { requestId: ctx.requestId });\n if (output) delete result.structuredContent;\n return result;\n };\n const parsed = input.safeParse(rawInput ?? {});\n if (!parsed.success) return fail(invalidInputError(parsed.error.issues));\n try {\n const value: unknown = await handler(parsed.data, ctx);\n if (output && !isCallToolResult(value)) {\n const checked = output.safeParse(value);\n if (!checked.success) {\n throw toolError({\n code: \"INTERNAL\",\n cause: `tool ${name} returned a value that does not match its output schema — ${checked.error.issues\n .map((issue) => `${issuePath(issue)}: ${issue.message}`)\n .join(\"; \")}`,\n fix: \"this is a bug in the tool, not in your call; report it with the request id\",\n retryable: false,\n details: { issues: checked.error.issues },\n });\n }\n return toCallToolResult(checked.data);\n }\n return toCallToolResult(value);\n } catch (err) {\n return fail(err);\n }\n },\n };\n return tool;\n}\n","/**\n * Fixture tools, resources and prompts with the names and shapes the official conformance\n * suite (`@modelcontextprotocol/conformance`) expects. Add them to any kit server to run\n * `conformance server --url …` against it. Not for production.\n */\nimport { completable } from \"@modelcontextprotocol/sdk/server/completable.js\";\nimport { type McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport {\n CreateMessageResultSchema,\n ElicitResultSchema,\n SubscribeRequestSchema,\n UnsubscribeRequestSchema,\n type ElicitRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { toolError } from \"./errors.js\";\nimport { defineTool, type ToolContext, type ToolDef } from \"./tool.js\";\n\n/** 1×1 transparent PNG */\nconst PNG_BASE64 =\n \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\";\n/** 44-byte WAV header, zero samples */\nconst WAV_BASE64 = \"UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=\";\n\nconst STATIC_TEXT_URI = \"test://static-text\";\nconst STATIC_TEXT = \"This is a static text resource for testing.\";\n\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n/** Form-mode elicitation schema (the params type is a union with URL-mode elicitation). */\ntype RequestedSchema = Extract<\n ElicitRequest[\"params\"],\n { requestedSchema: unknown }\n>[\"requestedSchema\"];\n\nfunction embeddedResource(): {\n type: \"resource\";\n resource: { uri: string; mimeType: string; text: string };\n} {\n return {\n type: \"resource\",\n resource: { uri: STATIC_TEXT_URI, mimeType: \"text/plain\", text: STATIC_TEXT },\n };\n}\n\nfunction requireExtra(ctx: ToolContext): NonNullable<ToolContext[\"extra\"]> {\n if (!ctx.extra) {\n throw toolError(\"INTERNAL\", \"no client connection in this context\", \"call this tool over MCP\");\n }\n return ctx.extra;\n}\n\nasync function elicit(\n ctx: ToolContext,\n message: string,\n requestedSchema: RequestedSchema,\n): Promise<string> {\n const result = await requireExtra(ctx).sendRequest(\n { method: \"elicitation/create\", params: { message, requestedSchema } },\n ElicitResultSchema,\n );\n return `Elicitation completed: action=${result.action}, content=${JSON.stringify(result.content ?? {})}`;\n}\n\n/** The tool fixtures the suite calls by name. */\nexport const conformanceTools: ToolDef[] = [\n defineTool({\n name: \"test_simple_text\",\n description: \"Conformance fixture: returns a fixed simple text response.\",\n input: z.object({}),\n handler: () => \"This is a simple text response for testing.\",\n }),\n defineTool({\n name: \"test_error_handling\",\n description: \"Conformance fixture: always returns an error result (isError: true).\",\n input: z.object({}),\n handler: () => {\n throw toolError({\n code: \"UPSTREAM_ERROR\",\n cause: \"This tool intentionally returns an error for testing\",\n fix: \"nothing to fix; this fixture always fails\",\n retryable: false,\n });\n },\n }),\n defineTool({\n name: \"test_image_content\",\n description: \"Conformance fixture: returns a 1x1 PNG image content block.\",\n input: z.object({}),\n handler: () => ({ content: [{ type: \"image\", data: PNG_BASE64, mimeType: \"image/png\" }] }),\n }),\n defineTool({\n name: \"test_audio_content\",\n description: \"Conformance fixture: returns an empty WAV audio content block.\",\n input: z.object({}),\n handler: () => ({ content: [{ type: \"audio\", data: WAV_BASE64, mimeType: \"audio/wav\" }] }),\n }),\n defineTool({\n name: \"test_embedded_resource\",\n description: \"Conformance fixture: returns an embedded text resource content block.\",\n input: z.object({}),\n handler: () => ({ content: [embeddedResource()] }),\n }),\n defineTool({\n name: \"test_multiple_content_types\",\n description: \"Conformance fixture: returns text, image and resource content blocks together.\",\n input: z.object({}),\n handler: () => ({\n content: [\n { type: \"text\", text: \"Mixed content response\" },\n { type: \"image\", data: PNG_BASE64, mimeType: \"image/png\" },\n embeddedResource(),\n ],\n }),\n }),\n defineTool({\n name: \"test_tool_with_logging\",\n description: \"Conformance fixture: emits three info log notifications while running.\",\n input: z.object({}),\n handler: async (_input, ctx) => {\n await ctx.log?.(\"info\", \"Tool execution started\");\n await sleep(50);\n await ctx.log?.(\"info\", \"Tool processing data\");\n await sleep(50);\n await ctx.log?.(\"info\", \"Tool execution completed\");\n return \"Tool execution completed with logging\";\n },\n }),\n defineTool({\n name: \"test_tool_with_progress\",\n description: \"Conformance fixture: reports progress 0/100, 50/100, 100/100 while running.\",\n input: z.object({}),\n handler: async (_input, ctx) => {\n await ctx.progress?.(0, 100, \"starting\");\n await sleep(50);\n await ctx.progress?.(50, 100, \"halfway\");\n await sleep(50);\n await ctx.progress?.(100, 100, \"done\");\n return \"Tool execution completed with progress\";\n },\n }),\n defineTool({\n name: \"test_sampling\",\n description: \"Conformance fixture: asks the client to sample a completion and returns it.\",\n input: z.object({ prompt: z.string().describe(\"Prompt to send to the client's model\") }),\n handler: async ({ prompt }, ctx) => {\n const result = await requireExtra(ctx).sendRequest(\n {\n method: \"sampling/createMessage\",\n params: {\n messages: [{ role: \"user\", content: { type: \"text\", text: prompt } }],\n maxTokens: 100,\n },\n },\n CreateMessageResultSchema,\n );\n const content = Array.isArray(result.content) ? result.content[0] : result.content;\n const text = content && content.type === \"text\" ? content.text : JSON.stringify(content);\n return `Sampling completed (${result.model}): ${text}`;\n },\n }),\n defineTool({\n name: \"test_elicitation\",\n description: \"Conformance fixture: asks the client for user input and reports the outcome.\",\n input: z.object({ message: z.string().describe(\"Message shown to the user\") }),\n handler: ({ message }, ctx) =>\n elicit(ctx, message, {\n type: \"object\",\n properties: {\n name: { type: \"string\", title: \"Name\", description: \"Your name\" },\n email: { type: \"string\", title: \"Email\", format: \"email\" },\n },\n required: [\"name\"],\n }),\n }),\n defineTool({\n name: \"test_elicitation_sep1034_defaults\",\n description: \"Conformance fixture: elicitation schema with defaults for every primitive type.\",\n input: z.object({}),\n handler: (_input, ctx) =>\n elicit(ctx, \"Please confirm your details\", {\n type: \"object\",\n properties: {\n name: { type: \"string\", title: \"Name\", default: \"John Doe\" },\n age: { type: \"integer\", title: \"Age\", default: 30 },\n score: { type: \"number\", title: \"Score\", default: 95.5 },\n status: {\n type: \"string\",\n title: \"Status\",\n enum: [\"active\", \"inactive\", \"pending\"],\n default: \"active\",\n },\n verified: { type: \"boolean\", title: \"Verified\", default: true },\n },\n }),\n }),\n defineTool({\n name: \"test_elicitation_sep1330_enums\",\n description:\n \"Conformance fixture: elicitation schema with titled, untitled and multi-select enums.\",\n input: z.object({}),\n handler: (_input, ctx) =>\n elicit(ctx, \"Pick some options\", {\n type: \"object\",\n properties: {\n untitledSingle: {\n type: \"string\",\n title: \"Untitled single\",\n enum: [\"red\", \"green\", \"blue\"],\n },\n titledSingle: {\n type: \"string\",\n title: \"Titled single\",\n oneOf: [\n { const: \"red\", title: \"Red\" },\n { const: \"green\", title: \"Green\" },\n { const: \"blue\", title: \"Blue\" },\n ],\n },\n legacyEnum: {\n type: \"string\",\n title: \"Legacy titled\",\n enum: [\"red\", \"green\", \"blue\"],\n enumNames: [\"Red\", \"Green\", \"Blue\"],\n },\n untitledMulti: {\n type: \"array\",\n title: \"Untitled multi\",\n items: { type: \"string\", enum: [\"red\", \"green\", \"blue\"] },\n },\n titledMulti: {\n type: \"array\",\n title: \"Titled multi\",\n items: {\n anyOf: [\n { const: \"red\", title: \"Red\" },\n { const: \"green\", title: \"Green\" },\n { const: \"blue\", title: \"Blue\" },\n ],\n },\n },\n },\n } as RequestedSchema),\n }),\n defineTool({\n name: \"json_schema_2020_12_tool\",\n description: \"Conformance fixture: input schema with a $defs reference to an address object.\",\n input: z.object({\n name: z.string(),\n address: z.object({ street: z.string(), city: z.string() }).meta({ id: \"address\" }),\n }),\n handler: (input) => input,\n }),\n];\n\n/** Register the resource and prompt fixtures on a kit server (call before connecting). */\nexport function registerConformanceFixtures(server: McpServer): void {\n server.server.registerCapabilities({ resources: { subscribe: true, listChanged: true } });\n\n server.registerResource(\n \"static-text\",\n STATIC_TEXT_URI,\n { title: \"Static text\", description: \"A static text resource\", mimeType: \"text/plain\" },\n async (uri) => ({ contents: [{ uri: uri.href, mimeType: \"text/plain\", text: STATIC_TEXT }] }),\n );\n server.registerResource(\n \"static-binary\",\n \"test://static-binary\",\n { title: \"Static binary\", description: \"A static binary resource\", mimeType: \"image/png\" },\n async (uri) => ({ contents: [{ uri: uri.href, mimeType: \"image/png\", blob: PNG_BASE64 }] }),\n );\n server.registerResource(\n \"watched-resource\",\n \"test://watched-resource\",\n {\n title: \"Watched resource\",\n description: \"Supports subscribe/unsubscribe\",\n mimeType: \"text/plain\",\n },\n async (uri) => ({ contents: [{ uri: uri.href, mimeType: \"text/plain\", text: \"watched\" }] }),\n );\n server.registerResource(\n \"template-data\",\n new ResourceTemplate(\"test://template/{id}/data\", { list: undefined }),\n { title: \"Template data\", description: \"Data for an id\", mimeType: \"text/plain\" },\n async (uri, variables) => ({\n contents: [\n { uri: uri.href, mimeType: \"text/plain\", text: `Data for id ${String(variables.id)}` },\n ],\n }),\n );\n server.server.setRequestHandler(SubscribeRequestSchema, async () => ({}));\n server.server.setRequestHandler(UnsubscribeRequestSchema, async () => ({}));\n\n server.registerPrompt(\n \"test_simple_prompt\",\n { description: \"A simple prompt without arguments\" },\n () => ({\n messages: [\n { role: \"user\", content: { type: \"text\", text: \"This is a simple prompt for testing.\" } },\n ],\n }),\n );\n server.registerPrompt(\n \"test_prompt_with_arguments\",\n {\n description: \"A prompt with two arguments\",\n argsSchema: {\n arg1: completable(z.string().describe(\"First argument\"), (value) =>\n [\"test\", \"testValue1\", \"testing\"].filter((v) => v.startsWith(value)),\n ),\n arg2: z.string().describe(\"Second argument\"),\n },\n },\n ({ arg1, arg2 }) => ({\n messages: [\n {\n role: \"user\",\n content: { type: \"text\", text: `Prompt with arg1=${arg1} and arg2=${arg2}` },\n },\n ],\n }),\n );\n server.registerPrompt(\n \"test_prompt_with_embedded_resource\",\n {\n description: \"A prompt that embeds a resource\",\n argsSchema: { resourceUri: z.string().describe(\"URI of the resource to embed\") },\n },\n ({ resourceUri }) => ({\n messages: [\n { role: \"user\", content: { type: \"text\", text: \"Here is the resource:\" } },\n {\n role: \"user\",\n content: {\n type: \"resource\",\n resource: { uri: resourceUri, mimeType: \"text/plain\", text: STATIC_TEXT },\n },\n },\n ],\n }),\n );\n server.registerPrompt(\n \"test_prompt_with_image\",\n { description: \"A prompt that includes an image\" },\n () => ({\n messages: [\n { role: \"user\", content: { type: \"text\", text: \"Describe this image:\" } },\n { role: \"user\", content: { type: \"image\", data: PNG_BASE64, mimeType: \"image/png\" } },\n ],\n }),\n );\n}\n","/**\n * `withPayment` — gate a tool behind a price. Wave 0: nothing is charged; callers without an\n * entitlement get a 402-shaped `PAYMENT_REQUIRED` result advertising both rails (x402 on Base,\n * Stripe MPP) with `comingSoon: true`, and `sample: true` returns an example for free.\n */\nimport {\n StubVerifier,\n buildPaymentRequired,\n type PaymentRequirement,\n paymentRequiredResponse,\n type PaymentRequiredBody,\n type PaymentVerifier,\n type SelfServe,\n type VerifyResult,\n} from \"@agentwares/x402\";\nimport { z } from \"zod\";\nimport { toolError, type McpToolError } from \"./errors.js\";\nimport { defineTool, type ToolContext, type ToolDef } from \"./tool.js\";\n\nexport interface AuthorizeResult {\n ok: boolean;\n userId?: string;\n /** why not, e.g. \"API key revoked\" — surfaced in `details.reason` */\n reason?: string;\n}\n\nexport interface WithPaymentOptions {\n /** price per successful call, in USD (e.g. 0.05) */\n priceUsd: number;\n /** Entitlement check (API key + credits, subscription tier). `ok: true` skips payment. */\n authorize?: (ctx: ToolContext) => Promise<AuthorizeResult> | AuthorizeResult;\n /** Payment verifier for the request headers. Default: `StubVerifier` (never accepts). */\n verifier?: PaymentVerifier;\n /** set once pay-per-call is live (drops `comingSoon`) */\n live?: boolean;\n /** name of the boolean input field that requests a free sample (default `sample`) */\n sampleField?: string;\n /** shown in the payment requirement */\n description?: string;\n /**\n * Discovery metadata for the x402 `bazaar` extension. Advertised in the 402 so a client can\n * echo it back; without that echo the facilitator will not catalog the resource, however\n * many payments settle against it.\n */\n bazaar?: Record<string, unknown>;\n payTo?: string;\n /** prepaid_credits rail: the URL that takes a card and funds a balance */\n creditsPayTo?: string;\n signupUrl?: string;\n /** the no-human purchase path, advertised in the 402 body once the card rail is live */\n selfServe?: SelfServe;\n /**\n * Called when a call that was already paid for then fails. A verifier that charges up\n * front (the prepaid wallet does) uses this to give the money back, so a caller is never\n * billed for an error. `receipt` is whatever the verifier returned.\n */\n onPaidFailure?: (\n ctx: ToolContext,\n verified: VerifyResult,\n error: unknown,\n ) => Promise<void> | void;\n /**\n * The paid work succeeded but the money did not arrive — an on-chain settlement that was\n * refused or a facilitator that went away. Never throw from here: the buyer has a valid\n * result and this is our accounting problem, not their failed request.\n */\n onSettlementFailure?: (ctx: ToolContext, verified: VerifyResult, reason?: string) => void;\n}\n\n/** A `McpToolError` whose body is the x402 `PaymentRequiredBody` (code `PAYMENT_REQUIRED`). */\nexport function paymentRequiredError(body: PaymentRequiredBody, reason?: string): McpToolError {\n const { code, cause, fix, retryable, ...rest } = body;\n return toolError({\n code,\n cause,\n fix,\n retryable,\n httpStatus: 402,\n details: reason !== undefined ? { reason } : undefined,\n extra: rest,\n });\n}\n\nfunction formatUsd(priceUsd: number): string {\n return priceUsd\n .toFixed(6)\n .replace(/0+$/, \"\")\n .replace(/\\.$/, \".00\")\n .replace(/\\.(\\d)$/, \".$10\");\n}\n\n/**\n * Wrap a tool so it requires an entitlement or payment. The returned tool has the same name,\n * schema and output, plus an optional boolean `sample` input (default false) documented as\n * \"return an example response at no charge\".\n *\n * Flow per call: `sample` → handler with `ctx.sample = true`; else `authorize` ok → handler\n * (with `ctx.userId`); else verifier accepts the request's payment headers → handler; else a\n * `PAYMENT_REQUIRED` error result (`_meta.httpStatus: 402`).\n */\nexport function withPayment(tool: ToolDef, opts: WithPaymentOptions): ToolDef {\n if (!Number.isFinite(opts.priceUsd) || opts.priceUsd < 0) {\n throw new Error(`withPayment(${tool.name}): priceUsd must be a non-negative number`);\n }\n const sampleField = opts.sampleField ?? \"sample\";\n if (sampleField in tool.input.shape) {\n throw new Error(\n `withPayment(${tool.name}): input already has a field named ${JSON.stringify(sampleField)}; pass sampleField to rename it`,\n );\n }\n const verifier: PaymentVerifier = opts.verifier ?? new StubVerifier();\n // A verifier that was configured is a rail that can actually be settled, so when it refuses\n // it knows why (\"insufficient credit: $0.00 available, $0.75 needed\") and its reason is the\n // one the caller can act on. Without one, `authorize`'s reason is all there is.\n const liveRail = opts.verifier !== undefined;\n const input = tool.input.extend({\n [sampleField]: z\n .boolean()\n .default(false)\n .describe(\n \"Set true to return an example response at no charge (sample mode). Default false.\",\n ),\n });\n const description = `${tool.description.trim()} Paid: $${formatUsd(opts.priceUsd)} per call; without credit you get a PAYMENT_REQUIRED result. Set ${sampleField}=true for a free example response.`;\n\n return defineTool({\n name: tool.name,\n title: tool.title,\n description,\n input,\n output: tool.output,\n annotations: tool.annotations,\n async handler(raw, ctx) {\n const record: Record<string, unknown> = { ...raw };\n const sample = record[sampleField] === true;\n delete record[sampleField];\n\n if (sample) return tool.handler(record, { ...ctx, sample: true });\n\n let reason: string | undefined;\n if (opts.authorize) {\n const auth = await opts.authorize(ctx);\n if (auth.ok) return tool.handler(record, { ...ctx, userId: auth.userId });\n reason = auth.reason;\n }\n\n // A tool name is not a resource. Over HTTP the front door knows the real URL and puts\n // it on the context; over stdio there is no URL and the name is the best there is.\n const resource = ctx.resourceUrl ?? tool.name;\n const required = buildPaymentRequired({\n resource,\n priceUsd: opts.priceUsd,\n live: opts.live,\n description: opts.description,\n payTo: opts.payTo,\n creditsPayTo: opts.creditsPayTo,\n signupUrl: opts.signupUrl,\n selfServe: opts.selfServe,\n // withPayment always adds a free `sample` flag to the tool's input schema\n sampleMode: true,\n ...(opts.bazaar ? { bazaar: opts.bazaar } : {}),\n });\n // What we advertise and what we accept are separate questions. `accepts` only lists\n // rails a caller could actually settle, and is empty when none is configured — but a\n // caller may still present credit or a payment header, so the verifier always runs.\n // The card rail is checked first because it is the one that can be settled today.\n const advertised =\n required.body.accepts.find((a) => a.rail === \"prepaid_credits\") ?? required.body.accepts[0];\n const requirement: PaymentRequirement = advertised ?? {\n rail: \"prepaid_credits\",\n amountUsd: String(required.body.priceUsd),\n resource,\n ...(opts.description ? { description: opts.description } : {}),\n };\n const verified = await verifier.verify(\n new Request(`https://mcp.local/${tool.name}`, { headers: ctx.headers }),\n requirement,\n );\n if (verified.ok) {\n let result: Awaited<ReturnType<typeof tool.handler>>;\n try {\n result = await tool.handler(record, ctx);\n } catch (error) {\n // Rails that already took the money refund here. Rails with a `settle` step have\n // not taken it yet, and the early return means they never will — the buyer is not\n // charged for a call that failed.\n await opts.onPaidFailure?.(ctx, verified, error);\n throw error;\n }\n // The work succeeded, so take the money. A settlement that fails now is lost\n // revenue, not a failed request: the buyer has already been served, and turning\n // this into an error would hand them the result *and* a 402.\n const settled = await verifier.settle?.(verified);\n if (settled && !settled.ok) {\n opts.onSettlementFailure?.(ctx, verified, settled.reason);\n }\n return result;\n }\n reason = liveRail ? (verified.reason ?? reason) : (reason ?? verified.reason);\n throw paymentRequiredError(required.body, reason);\n },\n });\n}\n\n/** Web-standard 402 `Response` for plain HTTP endpoints (re-export of `@agentwares/x402`). */\nexport const paymentRequiredHttpResponse = paymentRequiredResponse;\n\nexport { StubVerifier, buildPaymentRequired };\nexport type { PaymentRequiredBody, PaymentVerifier, SelfServe, VerifyResult };\n","/**\n * A tiny example server: two free tools and one paid tool. Used by the README, the HTTP\n * round-trip test and the conformance script.\n */\nimport { z } from \"zod\";\nimport { withPayment } from \"./payment.js\";\nimport { defineTool, type ToolDef } from \"./tool.js\";\n\nexport const exampleServerInfo = {\n name: \"mcp-kit-example\",\n version: \"0.1.0\",\n instructions:\n \"Example server built with @agentwares/mcp-kit. Call example_echo to check the connection, example_add to see typed structured output, and example_paid_lookup (sample=true first) to see how paid tools respond.\",\n};\n\nexport const exampleEcho = defineTool({\n name: \"example_echo\",\n title: \"Echo\",\n description:\n \"Echo a message back unchanged. Use it to check the connection and to see the result shape mcp-kit tools return (JSON text plus structuredContent).\",\n input: z.object({ message: z.string().describe(\"Text to echo back\") }),\n output: z.object({ message: z.string() }),\n annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },\n handler: ({ message }) => ({ message }),\n});\n\nexport const exampleAdd = defineTool({\n name: \"example_add\",\n title: \"Add\",\n description:\n \"Add two numbers and return their sum as { sum }. Demonstrates typed input and output schemas; send non-numbers to see an INVALID_INPUT error result.\",\n input: z.object({\n a: z.number().describe(\"First addend\"),\n b: z.number().describe(\"Second addend\"),\n }),\n output: z.object({ sum: z.number() }),\n annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },\n handler: ({ a, b }) => ({ sum: a + b }),\n});\n\nexport const examplePaidLookup = withPayment(\n defineTool({\n name: \"example_paid_lookup\",\n title: \"Paid lookup\",\n description:\n \"Look up a record by query and return { query, result, sample } (fake data). Demonstrates a paid tool: without an entitlement the call returns a PAYMENT_REQUIRED result with x402 and MPP payment options.\",\n input: z.object({ query: z.string().min(1).describe(\"What to look up\") }),\n output: z.object({ query: z.string(), result: z.string(), sample: z.boolean() }),\n annotations: { readOnlyHint: true, idempotentHint: true },\n handler: ({ query }, ctx) => ({\n query,\n result: ctx.sample ? `SAMPLE: example record for \"${query}\"` : `record for \"${query}\"`,\n sample: ctx.sample === true,\n }),\n }),\n { priceUsd: 0.05, description: \"One record lookup\" },\n);\n\nexport const exampleTools: ToolDef[] = [exampleEcho, exampleAdd, examplePaidLookup];\n","/**\n * `createMcpServer` — an SDK `McpServer` with every `ToolDef` registered, plus the manifest\n * helper used for `llms.txt` and docs.\n */\nimport { McpServer, type RegisteredTool } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n type ServerCapabilities,\n type ServerNotification,\n type ServerRequest,\n type Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport type { ToolAnnotations, ToolContext, ToolDef } from \"./tool.js\";\n\nexport interface McpServerOptions {\n /** server name as shown to clients, e.g. `agentcheck` */\n name: string;\n version: string;\n title?: string;\n websiteUrl?: string;\n /** shown to the model at connect time: what the server is for and how to start */\n instructions?: string;\n tools: ToolDef[];\n /** extra capabilities (tools and logging are always declared) */\n capabilities?: ServerCapabilities;\n}\n\ntype Extra = RequestHandlerExtra<ServerRequest, ServerNotification>;\n\nfunction isZodObject(schema: unknown): schema is z.ZodObject {\n return schema instanceof z.ZodObject;\n}\n\n/** Build a `ToolContext` from the SDK's request `extra` (headers, ids, signal, notifications). */\nexport function contextFromExtra(extra: Extra): ToolContext {\n const headers = new Headers();\n const raw = extra.requestInfo?.headers;\n if (raw) {\n for (const [key, value] of Object.entries(raw)) {\n if (Array.isArray(value)) for (const item of value) headers.append(key, item);\n else if (typeof value === \"string\") headers.append(key, value);\n }\n }\n const progressToken = extra._meta?.progressToken;\n return {\n headers,\n requestId: String(extra.requestId),\n signal: extra.signal,\n sessionId: extra.sessionId,\n meta: extra._meta,\n extra,\n log: async (level, data) => {\n await extra.sendNotification({ method: \"notifications/message\", params: { level, data } });\n },\n progress: async (progress, total, message) => {\n if (progressToken === undefined) return;\n await extra.sendNotification({\n method: \"notifications/progress\",\n params: { progressToken, progress, total, message },\n });\n },\n };\n}\n\n/**\n * Create an `McpServer` with all tools registered. Duplicate names throw.\n *\n * Tools are registered with the SDK (capabilities, enable/disable, list-changed notifications),\n * but `tools/list` and `tools/call` are served by the kit: the listing is exactly\n * `listToolManifest(tools)` (JSON Schema 2020-12, `additionalProperties: false`), and invalid\n * arguments or handler failures come back as in-band `{ code, cause, fix, retryable }` results\n * instead of bare JSON-RPC errors.\n */\nexport function createMcpServer(opts: McpServerOptions): McpServer {\n const byName = new Map<string, ToolDef>();\n for (const tool of opts.tools) {\n if (byName.has(tool.name)) throw new Error(`duplicate tool name: ${tool.name}`);\n byName.set(tool.name, tool);\n }\n\n const server = new McpServer(\n { name: opts.name, version: opts.version, title: opts.title, websiteUrl: opts.websiteUrl },\n { instructions: opts.instructions, capabilities: { logging: {}, ...opts.capabilities } },\n );\n\n const registered = new Map<string, RegisteredTool>();\n for (const tool of byName.values()) {\n const config: {\n title?: string;\n description: string;\n inputSchema: z.ZodObject;\n outputSchema?: z.ZodObject;\n annotations?: ToolAnnotations;\n } = {\n title: tool.title,\n description: tool.description,\n inputSchema: tool.input,\n annotations: tool.annotations,\n };\n if (isZodObject(tool.output)) config.outputSchema = tool.output;\n registered.set(\n tool.name,\n server.registerTool(tool.name, config, () => {\n throw new Error(\"unreachable: mcp-kit dispatches tools/call itself\");\n }),\n );\n }\n\n if (byName.size > 0) {\n server.server.setRequestHandler(ListToolsRequestSchema, async () => {\n const enabled = [...byName.values()].filter(\n (tool) => registered.get(tool.name)?.enabled !== false,\n );\n return {\n tools: listToolManifest(enabled).map((entry) => ({\n ...entry,\n inputSchema: entry.inputSchema as Tool[\"inputSchema\"],\n outputSchema: entry.outputSchema as Tool[\"outputSchema\"],\n })),\n };\n });\n server.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {\n const name = request.params.name;\n const tool = byName.get(name);\n const entry = registered.get(name);\n if (!tool || !entry) throw new McpError(ErrorCode.InvalidParams, `Tool ${name} not found`);\n if (!entry.enabled) throw new McpError(ErrorCode.InvalidParams, `Tool ${name} disabled`);\n return tool.invoke(request.params.arguments ?? {}, contextFromExtra(extra));\n });\n }\n\n return server;\n}\n\nexport interface ToolManifestEntry {\n name: string;\n title?: string;\n description: string;\n inputSchema: Record<string, unknown>;\n outputSchema?: Record<string, unknown>;\n annotations?: ToolAnnotations;\n}\n\n/**\n * JSON Schema (2020-12) for a zod schema, as advertised to clients. Plain `z.object`s strip\n * unknown keys at runtime, so they are advertised with `additionalProperties: false` (strict\n * schemas keep agents from inventing parameters); `z.looseObject` keeps them open.\n */\nexport function toJsonSchema(\n schema: z.ZodType,\n io: \"input\" | \"output\" = \"input\",\n): Record<string, unknown> {\n const json = z.toJSONSchema(schema, { io, target: \"draft-2020-12\" }) as Record<string, unknown>;\n if (\n isZodObject(schema) &&\n schema._zod.def.catchall === undefined &&\n json.additionalProperties === undefined\n ) {\n json.additionalProperties = false;\n }\n return json;\n}\n\n/** Plain JSON description of the tools — for `llms.txt`, docs pages and registries. */\nexport function listToolManifest(tools: readonly ToolDef[]): ToolManifestEntry[] {\n return tools.map((tool) => {\n const entry: ToolManifestEntry = {\n name: tool.name,\n description: tool.description,\n inputSchema: toJsonSchema(tool.input, \"input\"),\n };\n if (tool.title !== undefined) entry.title = tool.title;\n if (isZodObject(tool.output)) entry.outputSchema = toJsonSchema(tool.output, \"output\");\n if (tool.annotations !== undefined) entry.annotations = tool.annotations;\n return entry;\n });\n}\n","/**\n * Web-standard Streamable HTTP handler: `(Request) => Promise<Response>`. Runs unchanged in\n * Next.js route handlers, Vercel Functions and Cloudflare Workers.\n *\n * Stateless by default: a fresh server and transport per request, closed when the response\n * finishes. Opt into `sessions: true` for a long-lived process that needs server→client\n * requests (sampling, elicitation) or the standalone GET stream.\n */\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { WebStandardStreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js\";\nimport { normalizeError } from \"./errors.js\";\nimport { createMcpServer, type McpServerOptions } from \"./server.js\";\n\nexport interface CorsOptions {\n /** `Access-Control-Allow-Origin` (default `*`) */\n origin?: string;\n methods?: string;\n headers?: string;\n exposeHeaders?: string;\n maxAge?: number;\n}\n\nexport interface SessionOptions {\n /** idle sessions are closed after this long (default 30 minutes) */\n ttlMs?: number;\n}\n\nexport interface HttpTransportOptions {\n /** `true` for permissive defaults, or explicit values. Off by default. */\n cors?: boolean | CorsOptions;\n /**\n * `true`: each POST is answered with one JSON body — simplest for curl and serverless\n * (default when stateless). `false`: answer with an SSE stream so `ctx.log` / `ctx.progress`\n * notifications and server→client requests reach the client mid-call (default with sessions).\n */\n jsonResponse?: boolean;\n /**\n * `false` (default): stateless — no session ids, safe on serverless. `true` (or options):\n * sessions kept in this process's memory under `Mcp-Session-Id`; needed for sampling,\n * elicitation and the standalone GET stream. Single long-lived process only.\n */\n sessions?: boolean | SessionOptions;\n /** Host header allow-list (DNS-rebinding protection for localhost servers). */\n allowedHosts?: string[];\n allowedOrigins?: string[];\n enableDnsRebindingProtection?: boolean;\n}\n\nexport type HttpHandlerOptions = McpServerOptions & HttpTransportOptions;\nexport type HttpHandler = (request: Request) => Promise<Response>;\n\nconst DEFAULT_CORS: Required<CorsOptions> = {\n origin: \"*\",\n methods: \"GET, POST, DELETE, OPTIONS\",\n headers:\n \"Content-Type, Accept, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, PAYMENT, X-PAYMENT\",\n exposeHeaders:\n \"Mcp-Session-Id, Mcp-Protocol-Version, WWW-Authenticate, X-Payment-Requirements, PAYMENT-REQUIRED\",\n maxAge: 86_400,\n};\n\nconst DEFAULT_SESSION_TTL_MS = 30 * 60_000;\n\nfunction corsHeaders(cors: boolean | CorsOptions | undefined): Record<string, string> {\n if (!cors) return {};\n const c = { ...DEFAULT_CORS, ...(typeof cors === \"object\" ? cors : {}) };\n return {\n \"Access-Control-Allow-Origin\": c.origin,\n \"Access-Control-Allow-Methods\": c.methods,\n \"Access-Control-Allow-Headers\": c.headers,\n \"Access-Control-Expose-Headers\": c.exposeHeaders,\n \"Access-Control-Max-Age\": String(c.maxAge),\n };\n}\n\nfunction jsonResponse(\n body: unknown,\n status: number,\n headers: Record<string, string> = {},\n): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\", ...headers },\n });\n}\n\nfunction methodNotAllowed(method: string, allow: string, cors: Record<string, string>): Response {\n return jsonResponse(\n {\n code: \"METHOD_NOT_ALLOWED\",\n cause: `${method} is not supported here without a session`,\n fix: \"send JSON-RPC over POST with `Accept: application/json, text/event-stream` (start with `initialize`)\",\n retryable: false,\n },\n 405,\n { Allow: allow, ...cors },\n );\n}\n\nfunction splitOptions(\n opts: HttpHandlerOptions | (() => McpServer),\n transport: HttpTransportOptions,\n): { factory: () => McpServer; transport: HttpTransportOptions } {\n if (typeof opts === \"function\") return { factory: opts, transport };\n const {\n cors,\n jsonResponse,\n sessions,\n allowedHosts,\n allowedOrigins,\n enableDnsRebindingProtection,\n ...server\n } = opts;\n return {\n factory: () => createMcpServer(server),\n transport: {\n cors,\n jsonResponse,\n sessions,\n allowedHosts,\n allowedOrigins,\n enableDnsRebindingProtection,\n ...transport,\n },\n };\n}\n\ninterface TransportBase {\n enableJsonResponse: boolean;\n allowedHosts?: string[];\n allowedOrigins?: string[];\n enableDnsRebindingProtection?: boolean;\n}\n\ninterface HandlerContext {\n factory: () => McpServer;\n cors: Record<string, string>;\n transportBase: TransportBase;\n}\n\nfunction withCors(response: Response, cors: Record<string, string>): Response {\n const keys = Object.keys(cors);\n if (keys.length === 0) return response;\n const headers = new Headers(response.headers);\n for (const key of keys) headers.set(key, cors[key] ?? \"\");\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nfunction errorResponse(err: unknown, cors: Record<string, string>): Response {\n const error = normalizeError(err);\n return jsonResponse(error.toJSON(), error.httpStatus, cors);\n}\n\nfunction createStatelessHandler({ factory, cors, transportBase }: HandlerContext): HttpHandler {\n return async (request) => {\n if (request.method !== \"POST\") return methodNotAllowed(request.method, \"POST, OPTIONS\", cors);\n\n const server = factory();\n const transport = new WebStandardStreamableHTTPServerTransport({\n ...transportBase,\n sessionIdGenerator: undefined,\n });\n let closed = false;\n const cleanup = async (): Promise<void> => {\n if (closed) return;\n closed = true;\n try {\n await server.close();\n } catch {\n // already closed\n }\n };\n\n try {\n await server.connect(transport);\n const response = withCors(await transport.handleRequest(request), cors);\n if (!response.body) {\n await cleanup();\n return response;\n }\n // Close server + transport once the body (JSON or SSE stream) has been fully written.\n request.signal?.addEventListener(\"abort\", () => void cleanup(), { once: true });\n const body = response.body.pipeThrough(\n new TransformStream<Uint8Array, Uint8Array>({ flush: () => cleanup() }),\n );\n return new Response(body, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n } catch (err) {\n await cleanup();\n return errorResponse(err, cors);\n }\n };\n}\n\ninterface Session {\n server: McpServer;\n transport: WebStandardStreamableHTTPServerTransport;\n lastSeen: number;\n}\n\nfunction createStatefulHandler(\n { factory, cors, transportBase }: HandlerContext,\n options: SessionOptions,\n): HttpHandler {\n const ttlMs = options.ttlMs ?? DEFAULT_SESSION_TTL_MS;\n const sessions = new Map<string, Session>();\n\n const drop = (id: string): void => {\n const session = sessions.get(id);\n if (!session) return;\n sessions.delete(id);\n session.server.close().catch(() => undefined);\n };\n const sweep = (): void => {\n const now = Date.now();\n for (const [id, session] of sessions) if (now - session.lastSeen > ttlMs) drop(id);\n };\n\n return async (request) => {\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (sessionId) {\n const session = sessions.get(sessionId);\n if (!session) {\n return jsonResponse(\n {\n code: \"NOT_FOUND\",\n cause: \"unknown or expired Mcp-Session-Id\",\n fix: \"send `initialize` again without an Mcp-Session-Id header and use the id from the response\",\n retryable: true,\n },\n 404,\n cors,\n );\n }\n session.lastSeen = Date.now();\n try {\n return withCors(await session.transport.handleRequest(request), cors);\n } catch (err) {\n return errorResponse(err, cors);\n }\n }\n\n if (request.method !== \"POST\") return methodNotAllowed(request.method, \"POST, OPTIONS\", cors);\n sweep();\n\n const server = factory();\n const transport = new WebStandardStreamableHTTPServerTransport({\n ...transportBase,\n sessionIdGenerator: () => crypto.randomUUID(),\n onsessioninitialized: (id) => {\n sessions.set(id, { server, transport, lastSeen: Date.now() });\n },\n onsessionclosed: (id) => {\n sessions.delete(id);\n },\n });\n\n try {\n await server.connect(transport);\n const previousOnClose = transport.onclose;\n transport.onclose = () => {\n previousOnClose?.();\n if (transport.sessionId) sessions.delete(transport.sessionId);\n };\n const response = withCors(await transport.handleRequest(request), cors);\n // Anything but a successful `initialize` leaves no session behind: release the server.\n if (!transport.sessionId) server.close().catch(() => undefined);\n return response;\n } catch (err) {\n server.close().catch(() => undefined);\n return errorResponse(err, cors);\n }\n };\n}\n\n/**\n * Create the request handler. Pass server options, or a factory returning a configured\n * `McpServer` (e.g. one with resources/prompts added) when you need more than tools.\n */\nexport function createHttpHandler(\n opts: HttpHandlerOptions | (() => McpServer),\n transportOptions: HttpTransportOptions = {},\n): HttpHandler {\n const { factory, transport: t } = splitOptions(opts, transportOptions);\n const cors = corsHeaders(t.cors);\n const sessions = t.sessions ? (typeof t.sessions === \"object\" ? t.sessions : {}) : undefined;\n const context: HandlerContext = {\n factory,\n cors,\n transportBase: {\n enableJsonResponse: t.jsonResponse ?? sessions === undefined,\n allowedHosts: t.allowedHosts,\n allowedOrigins: t.allowedOrigins,\n enableDnsRebindingProtection: t.enableDnsRebindingProtection,\n },\n };\n const handler = sessions\n ? createStatefulHandler(context, sessions)\n : createStatelessHandler(context);\n const allow = sessions ? \"GET, POST, DELETE, OPTIONS\" : \"POST, OPTIONS\";\n\n return async (request: Request): Promise<Response> => {\n if (request.method === \"OPTIONS\") {\n return new Response(null, { status: 204, headers: { Allow: allow, ...cors } });\n }\n return handler(request);\n };\n}\n\n/** Host header values a localhost server should accept (for `allowedHosts`). */\nexport function localhostHosts(port: number): string[] {\n const hosts = [\"localhost\", \"127.0.0.1\", \"[::1]\"];\n return [...hosts, ...hosts.map((h) => `${h}:${port}`)];\n}\n\nexport interface HealthInfo {\n name: string;\n version: string;\n /** tool count or the tool list */\n tools: number | readonly unknown[];\n}\n\n/** `GET /health` → `{ ok: true, name, version, tools }`. */\nexport function handleHealth(info: HealthInfo): Response {\n const tools = typeof info.tools === \"number\" ? info.tools : info.tools.length;\n return jsonResponse({ ok: true, name: info.name, version: info.version, tools }, 200);\n}\n","/**\n * Bridge a Web-standard `(Request) => Promise<Response>` handler onto `node:http` — for local\n * runs, tests and the conformance suite. Node-only; loaded lazily.\n */\nimport type { HttpHandler } from \"./http.js\";\n\nexport interface NodeHttpOptions {\n handler: HttpHandler;\n /** 0 picks a free port (default 8765) */\n port?: number;\n /** default 127.0.0.1 */\n host?: string;\n /** MCP endpoint path (default `/mcp`) */\n path?: string;\n /** optional `GET /health` responder */\n health?: () => Response;\n}\n\nexport interface NodeHttpServer {\n port: number;\n /** MCP endpoint URL, e.g. `http://127.0.0.1:8765/mcp` */\n url: string;\n close(): Promise<void>;\n}\n\n/** Start a `node:http` server that forwards `path` to the handler. */\nexport async function serveNodeHttp(opts: NodeHttpOptions): Promise<NodeHttpServer> {\n const http = await import(\"node:http\");\n const host = opts.host ?? \"127.0.0.1\";\n const path = opts.path ?? \"/mcp\";\n\n const server = http.createServer((req, res) => {\n void (async () => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? host}`);\n let response: Response;\n if (url.pathname === path) {\n const controller = new AbortController();\n res.on(\"close\", () => {\n if (!res.writableFinished) controller.abort();\n });\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (Array.isArray(value)) for (const item of value) headers.append(key, item);\n else if (typeof value === \"string\") headers.set(key, value);\n }\n const method = req.method ?? \"GET\";\n let body: Uint8Array<ArrayBuffer> | undefined;\n if (method !== \"GET\" && method !== \"HEAD\") {\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(chunk as Buffer);\n body = new Uint8Array(Buffer.concat(chunks));\n }\n response = await opts.handler(\n new Request(url, { method, headers, body, signal: controller.signal }),\n );\n } else if (url.pathname === \"/health\" && opts.health) {\n response = opts.health();\n } else {\n response = new Response(\n JSON.stringify({\n code: \"NOT_FOUND\",\n cause: `no route for ${url.pathname}`,\n fix: `POST JSON-RPC to ${path}`,\n retryable: false,\n }),\n { status: 404, headers: { \"Content-Type\": \"application/json\" } },\n );\n }\n\n const outHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n outHeaders[key] = value;\n });\n res.writeHead(response.status, outHeaders);\n if (!response.body) {\n res.end();\n return;\n }\n const reader = response.body.getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(value);\n }\n } catch {\n // client went away mid-stream\n }\n res.end();\n })().catch((err: unknown) => {\n if (!res.headersSent) res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n code: \"INTERNAL\",\n cause: err instanceof Error ? err.message : String(err),\n fix: \"retry; if it persists, report the request id\",\n retryable: false,\n }),\n );\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(opts.port ?? 8765, host, () => resolve());\n });\n const address = server.address();\n const port = typeof address === \"object\" && address ? address.port : (opts.port ?? 8765);\n return {\n port,\n url: `http://${host}:${port}${path}`,\n close: () =>\n new Promise<void>((resolve, reject) => {\n server.closeAllConnections();\n server.close((err) => (err ? reject(err) : resolve()));\n }),\n };\n}\n","/**\n * x402 verification and settlement through a facilitator.\n *\n * The facilitator is the only piece we do not run: it checks the buyer's signature and\n * submits the on-chain transfer. It never holds the money — USDC moves from the buyer\n * straight to `payTo`, an address we control — so this is not custody, and swapping\n * facilitators is changing one URL.\n *\n * PayAI (https://facilitator.payai.network) is the default because it needs no account,\n * no API key and no business relationship, which is the property that matters: an\n * account is a dependency that can be closed. Coinbase's CDP facilitator implements the\n * same two endpoints and can be dropped in by setting X402_FACILITATOR_URL.\n *\n * Verification is free and moves nothing. Settlement moves money, so it is deliberately\n * a separate call the caller makes only after the work succeeded — a failed call is then\n * never charged at all, which is better than charging and refunding.\n */\nimport type { PaymentRail, PaymentRequirement, PaymentVerifier, VerifyResult } from \"./index.js\";\n\nexport const PAYAI_FACILITATOR_URL = \"https://facilitator.payai.network\";\n\n/** Circle's native USDC on Base mainnet. */\nexport const USDC_BASE = \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\";\n\n/** USDC is a 6-decimal token everywhere it is issued. */\nexport const USDC_DECIMALS = 6;\n\n/**\n * The EIP-712 domain of the asset being signed over. The facilitator needs it to reconstruct\n * the buyer's signature; without it, verification fails with\n * `invalid_exact_evm_missing_eip712_domain` and no payment can ever succeed.\n */\nexport const USDC_EIP712_DOMAIN = { name: \"USD Coin\", version: \"2\" };\n\n/**\n * CAIP-2 to the short network names the **v1** verify/settle envelope uses.\n *\n * Only the v1 path needs this. v2 carries CAIP-2 end to end, which is one of the reasons to\n * prefer it: no translation layer between what the 402 advertises and what the facilitator\n * is told.\n */\nconst SHORT_NETWORK: Record<string, string> = {\n \"eip155:8453\": \"base\",\n \"eip155:84532\": \"base-sepolia\",\n \"eip155:137\": \"polygon\",\n \"eip155:80002\": \"polygon-amoy\",\n \"eip155:42161\": \"arbitrum\",\n \"eip155:43114\": \"avalanche\",\n};\n\nexport function toShortNetwork(network: string): string {\n return SHORT_NETWORK[network] ?? network;\n}\n\n/**\n * The x402 `bazaar` extension — how a resource gets into a discovery catalog.\n *\n * There is no registration endpoint (the facilitator's OpenAPI description has only GETs\n * under /discovery). Settling a payment is necessary but **not** sufficient: the catalog is\n * built from this extension, which the resource server declares and the facilitator either\n * accepts or rejects. Without it a resource can be paid for indefinitely and never appear.\n *\n * The facilitator answers in an `EXTENSION-RESPONSES` header — base64 JSON keyed by\n * extension name, `{ bazaar: { status: \"success\" | \"processing\" | \"rejected\", … } }`. That\n * is the only direct feedback there is, so it is surfaced rather than discarded.\n */\nexport interface BazaarExtension {\n info: {\n input: Record<string, unknown>;\n output?: Record<string, unknown>;\n };\n /** JSON Schema (draft 2020-12) that validates `info`. Required by the extension. */\n schema: Record<string, unknown>;\n /** canonical route pattern for a parameterised path, e.g. `/v1/reserves/:symbol` */\n routeTemplate?: string;\n}\n\nexport interface BazaarStatus {\n status?: \"success\" | \"processing\" | \"rejected\";\n rejectedReason?: string;\n}\n\n/**\n * A `bazaar` extension for a plain GET endpoint that answers JSON.\n *\n * The schema is deliberately permissive: its job is to be a valid draft 2020-12 document\n * that `info` satisfies, not to constrain a shape only we produce.\n */\nexport function httpGetBazaar(options: {\n queryParams?: Record<string, string>;\n pathParams?: Record<string, string>;\n routeTemplate?: string;\n outputExample?: unknown;\n}): BazaarExtension {\n return {\n info: {\n input: {\n type: \"http\",\n method: \"GET\",\n ...(options.queryParams ? { queryParams: options.queryParams } : {}),\n ...(options.pathParams ? { pathParams: options.pathParams } : {}),\n },\n ...(options.outputExample !== undefined\n ? { output: { type: \"json\", example: options.outputExample } }\n : {}),\n },\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n required: [\"input\"],\n properties: {\n input: { type: \"object\", required: [\"type\"], properties: { type: { type: \"string\" } } },\n output: { type: \"object\" },\n },\n },\n ...(options.routeTemplate ? { routeTemplate: options.routeTemplate } : {}),\n };\n}\n\nexport interface FacilitatorVerifierOptions {\n /** the address USDC is paid to — ours, self-custody */\n payTo: string;\n /** CAIP-2 chain, e.g. eip155:8453 */\n network: string;\n /** token contract; defaults to native USDC on Base */\n asset?: string;\n /** defaults to PayAI */\n facilitatorUrl?: string;\n /** optional bearer token; PayAI works without one, some facilitators require it */\n apiKey?: string;\n /** EIP-712 domain of the asset; defaults to USDC's. Required by the facilitator. */\n assetDomain?: { name: string; version: string };\n /**\n * Decimals of that asset. Defaults to USDC's six.\n *\n * Set it whenever `asset` is set. The price is signed in atomic units, so the wrong decimals\n * do not fail loudly — they authorise a transfer for the wrong amount, off by a factor of a\n * thousand or a million in whichever direction hurts.\n */\n assetDecimals?: number;\n /**\n * Envelope to speak to the facilitator. Defaults to 2.\n *\n * Both settle money identically — the buyer's signature is the same either way — but only\n * v2 settlements appear in the Bazaar discovery catalog, so v1 is a rail that works and\n * cannot be found. Set it to 1 only for a facilitator that rejects v2.\n */\n protocolVersion?: 1 | 2;\n /**\n * Discovery metadata for this resource. Without it the resource is payable but not\n * listable — see BazaarExtension. Ignored on the v1 path, which has no extensions.\n */\n bazaar?: BazaarExtension;\n fetchImpl?: typeof fetch;\n log?: (message: string, data?: Record<string, unknown>) => void;\n}\n\nexport interface SettleResult {\n ok: boolean;\n /** on-chain transaction hash when the transfer landed */\n transaction?: string;\n payer?: string;\n reason?: string;\n /** whether the facilitator catalogued the resource, when it said so */\n bazaar?: BazaarStatus;\n}\n\n/** What the buyer base64s into the X-PAYMENT header; forwarded to the facilitator verbatim. */\ninterface PaymentPayload {\n x402Version?: number;\n scheme?: string;\n network?: string;\n payload?: unknown;\n /** the client's echo of the server's extensions; its presence is what enables them */\n extensions?: Record<string, unknown>;\n}\n\ninterface VerifyResponse {\n isValid?: boolean;\n invalidReason?: string;\n invalidMessage?: string;\n payer?: string;\n}\n\ninterface SettleResponse {\n success?: boolean;\n errorReason?: string;\n errorMessage?: string;\n transaction?: string;\n network?: string;\n payer?: string;\n}\n\n/**\n * Decimal USD string to the token's atomic units.\n *\n * Done on the string rather than via floating point: 0.07 * 1e6 is 70000.00000000001, and\n * a price that rounds wrong is a payment the facilitator rejects for the wrong amount.\n */\nexport function toAtomicUnits(amountUsd: string, decimals = USDC_DECIMALS): string {\n const trimmed = amountUsd.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) throw new Error(`not a decimal amount: ${amountUsd}`);\n const [whole = \"0\", fraction = \"\"] = trimmed.split(\".\");\n if (fraction.length > decimals) {\n throw new Error(`${amountUsd} has more than ${decimals} decimal places`);\n }\n return `${whole}${fraction.padEnd(decimals, \"0\")}`.replace(/^0+(?=\\d)/, \"\");\n}\n\n/** The buyer's payment, or undefined when the request carries none. */\nfunction readPaymentHeader(request: Request): PaymentPayload | undefined {\n const raw = request.headers.get(\"X-PAYMENT\") ?? request.headers.get(\"PAYMENT\");\n if (!raw) return undefined;\n try {\n // base64 JSON per the spec; tolerate a bare JSON body from a hand-rolled client\n const text = raw.trim().startsWith(\"{\") ? raw : new TextDecoder().decode(base64ToBytes(raw));\n return JSON.parse(text) as PaymentPayload;\n } catch {\n return undefined;\n }\n}\n\nfunction base64ToBytes(b64: string): Uint8Array {\n const binary = atob(b64.trim());\n const out = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);\n return out;\n}\n\nexport interface FacilitatorVerifier extends PaymentVerifier {\n settle(verified: VerifyResult): Promise<SettleResult>;\n}\n\nexport function createFacilitatorVerifier(\n options: FacilitatorVerifierOptions,\n): FacilitatorVerifier {\n const base = (options.facilitatorUrl ?? PAYAI_FACILITATOR_URL).replace(/\\/+$/, \"\");\n const asset = options.asset ?? USDC_BASE;\n const doFetch = options.fetchImpl ?? fetch;\n const log = options.log ?? (() => undefined);\n const version = options.protocolVersion ?? 2;\n\n function requirementsFor(requirement: PaymentRequirement): Record<string, unknown> {\n // Without `extra` the facilitator cannot rebuild the signature and refuses every payment\n // with invalid_exact_evm_missing_eip712_domain.\n const extra = options.assetDomain ?? USDC_EIP712_DOMAIN;\n const amount = toAtomicUnits(requirement.amountUsd, options.assetDecimals);\n const maxTimeoutSeconds = requirement.maxTimeoutSeconds ?? 300;\n\n if (version === 2) {\n // v2 renamed maxAmountRequired to amount and carries CAIP-2 networks unchanged.\n //\n // `resource` is not in the v2 schema and the facilitator does not require it, but it is\n // the only thing that ties a settlement to a URL — a discovery catalog of resources\n // cannot list a payment that names no resource. It is accepted, so send it.\n return {\n scheme: \"exact\",\n network: options.network,\n amount,\n asset,\n payTo: options.payTo,\n maxTimeoutSeconds,\n resource: requirement.resource,\n description: requirement.description ?? \"\",\n mimeType: \"application/json\",\n extra,\n };\n }\n return {\n scheme: \"exact\",\n network: toShortNetwork(options.network),\n maxAmountRequired: amount,\n resource: requirement.resource,\n description: requirement.description ?? \"\",\n mimeType: \"application/json\",\n payTo: options.payTo,\n maxTimeoutSeconds,\n asset,\n extra,\n };\n }\n\n /**\n * The buyer's payload, restated in the envelope the facilitator accepts.\n *\n * v2 nests the terms the buyer agreed to as `accepted` *inside* the payload — that nesting\n * is the whole difference, and getting it wrong returns `invalid_payment_requirements:\n * \": Invalid input\"`, which names no field. v1 instead flattens scheme and network next to\n * the payload.\n */\n function payloadFor(\n payment: PaymentPayload,\n accepted: Record<string, unknown>,\n ): Record<string, unknown> {\n if (version === 2) {\n return {\n x402Version: 2,\n // Not required alongside `accepted`, but the facilitator's own OpenAPI description\n // lists scheme and network as required on a payment payload, and the discovery\n // catalog records a network per resource. Sending them costs nothing.\n scheme: payment.scheme ?? \"exact\",\n network: options.network,\n // A payload-level `resource` OBJECT — a string here is rejected. Every catalogued\n // entry carries url, type, method, description and mimeType, which is exactly this\n // shape, so this is the most likely thing the catalog is built from.\n resource: {\n url: accepted[\"resource\"],\n type: \"http\",\n method: \"GET\",\n description: accepted[\"description\"],\n mimeType: accepted[\"mimeType\"],\n },\n accepted,\n payload: payment.payload,\n // the client's echo, verbatim: the facilitator compares it against serverExtensions\n ...(payment.extensions ? { extensions: payment.extensions } : {}),\n };\n }\n return {\n x402Version: 1,\n scheme: payment.scheme ?? \"exact\",\n network: toShortNetwork(payment.network ?? options.network),\n payload: payment.payload,\n };\n }\n\n /**\n * v2 only: extensions the resource server declares.\n *\n * Sent **only when the client echoed one back**. Declaring an extension the client did not\n * echo is refused outright — `403 Extension validation failed: client must echo server\n * extensions` — so sending it unconditionally would turn every payment from an older client\n * into a refusal. Discovery is worth having; it is not worth failing a sale for.\n */\n function serverExtensions(payment: PaymentPayload, declared: unknown): Record<string, unknown> {\n const bazaar = declared ?? options.bazaar;\n if (version !== 2 || !bazaar) return {};\n if (!payment.extensions?.[\"bazaar\"]) return {};\n return { serverExtensions: { bazaar } };\n }\n\n type Call<T> =\n { reached: true; body: T; bazaar?: BazaarStatus } | { reached: false; error: string };\n\n /** `EXTENSION-RESPONSES`: base64 JSON keyed by extension name. Absent on the v1 path. */\n function readBazaarStatus(headers: Headers): BazaarStatus | undefined {\n const raw = headers.get(\"extension-responses\");\n if (!raw) return undefined;\n try {\n const text = new TextDecoder().decode(base64ToBytes(raw));\n return (JSON.parse(text) as Record<string, BazaarStatus>)[\"bazaar\"];\n } catch {\n return undefined;\n }\n }\n\n async function call<T>(path: string, body: unknown): Promise<Call<T>> {\n try {\n const res = await doFetch(`${base}${path}`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...(options.apiKey ? { authorization: `Bearer ${options.apiKey}` } : {}),\n },\n body: JSON.stringify(body),\n });\n // Check the status before the body. A facilitator answering 500 or 403 can still return\n // JSON carrying `isValid` or `success`, and reading it regardless means an error page\n // decides whether we were paid. This rail must fail closed.\n if (!res.ok && res.status >= 500) {\n return { reached: false, error: `facilitator returned HTTP ${res.status}` };\n }\n const bazaar = readBazaarStatus(res.headers);\n // A rejected declaration is silent otherwise: payments keep working and the resource\n // simply never appears in the catalog, which is the failure that took longest to see.\n if (bazaar?.status === \"rejected\") {\n log(\"x402 bazaar listing rejected\", { reason: bazaar.rejectedReason });\n }\n return { reached: true, body: (await res.json()) as T, ...(bazaar ? { bazaar } : {}) };\n } catch (err) {\n return { reached: false, error: err instanceof Error ? err.message : String(err) };\n }\n }\n\n return {\n /**\n * Checks the buyer's signature. Free, and moves nothing — call `settle` once the work\n * has actually succeeded.\n */\n async verify(request: Request, requirement: PaymentRequirement): Promise<VerifyResult> {\n const payment = readPaymentHeader(request);\n if (!payment) {\n return { ok: false, rail: \"x402\", reason: \"no payment header present\" };\n }\n const paymentRequirements = requirementsFor(requirement);\n const call1 = await call<VerifyResponse>(\"/verify\", {\n x402Version: version,\n paymentPayload: payloadFor(payment, paymentRequirements),\n // v2 keeps this alongside the payload as well as inside it. PayAI rejects the body\n // outright without it, so it is not the redundancy it looks like.\n paymentRequirements,\n ...serverExtensions(payment, requirement.bazaar),\n });\n if (!call1.reached) {\n // Fail closed: an unreachable facilitator must never be read as a valid payment.\n log(\"x402 facilitator unreachable\", { error: call1.error });\n return { ok: false, rail: \"x402\", reason: \"payment facilitator unreachable\" };\n }\n const verified = call1.body;\n if (!verified.isValid) {\n return {\n ok: false,\n rail: \"x402\",\n reason: verified.invalidReason\n ? `${verified.invalidReason}${verified.invalidMessage ? `: ${verified.invalidMessage}` : \"\"}`\n : \"payment refused by the facilitator\",\n };\n }\n return {\n ok: true,\n rail: \"x402\",\n // everything settle() needs, so it does not have to re-read the request\n receipt: {\n payment,\n paymentRequirements,\n payer: verified.payer,\n // settle() never sees the requirement again, so carry the declaration with it\n ...(requirement.bazaar ? { bazaar: requirement.bazaar } : {}),\n },\n };\n },\n\n /** Submits the transfer. Only call this once the paid work has succeeded. */\n async settle(verified: VerifyResult): Promise<SettleResult> {\n const receipt = verified.receipt as\n | {\n payment: PaymentPayload;\n paymentRequirements: Record<string, unknown>;\n bazaar?: unknown;\n }\n | undefined;\n if (!receipt?.payment) return { ok: false, reason: \"nothing to settle\" };\n const call2 = await call<SettleResponse>(\"/settle\", {\n x402Version: version,\n paymentPayload: payloadFor(receipt.payment, receipt.paymentRequirements),\n paymentRequirements: receipt.paymentRequirements,\n ...serverExtensions(receipt.payment, receipt.bazaar),\n });\n if (!call2.reached) {\n log(\"x402 settlement failed to reach the facilitator\", { error: call2.error });\n return { ok: false, reason: call2.error };\n }\n const result = call2.body;\n if (!result.success) {\n // The buyer already has the resource. Worth logging loudly: it is lost revenue,\n // not a failed request, and the caller should not turn it into an error.\n log(\"x402 settlement refused after the work was served\", {\n reason: result.errorReason,\n message: result.errorMessage,\n });\n return {\n ok: false,\n reason: result.errorReason ?? \"settlement refused\",\n ...(result.payer ? { payer: result.payer } : {}),\n };\n }\n if (call2.bazaar) log(\"x402 bazaar listing\", { ...call2.bazaar });\n // A settlement we cannot name cannot be made idempotent: the caller keys the credit on\n // this hash, and without one it would invent a fresh key per attempt and credit the same\n // authorisation again on every retry. Treat it as unsettled rather than as money.\n if (!result.transaction) {\n log(\"x402 settlement reported success with no transaction\", { payer: result.payer });\n return {\n ok: false,\n reason:\n \"the facilitator reported success but named no transaction, so the payment cannot be confirmed\",\n ...(result.payer ? { payer: result.payer } : {}),\n };\n }\n return {\n ok: true,\n transaction: result.transaction,\n ...(result.payer ? { payer: result.payer } : {}),\n ...(call2.bazaar ? { bazaar: call2.bazaar } : {}),\n };\n },\n };\n}\n\n/**\n * One verifier over several rails: try each in turn, first acceptance wins.\n *\n * A caller presents whatever it has — a USDC payment header or a prepaid key — and should\n * not have to be told which rail the server prefers. Refusals are reported from the rail\n * that got furthest: \"insufficient credit\" is useful, \"no payment header present\" from a\n * rail the caller never intended to use is noise.\n *\n * `settle` dispatches on the rail that accepted, so a rail that already took its money\n * during verification is never asked to take it twice.\n */\nexport function createAnyVerifier(verifiers: readonly PaymentVerifier[]): PaymentVerifier {\n return {\n async verify(request: Request, requirement: PaymentRequirement): Promise<VerifyResult> {\n const refusals: VerifyResult[] = [];\n for (const verifier of verifiers) {\n const result = await verifier.verify(request, requirement);\n if (result.ok) return result;\n refusals.push(result);\n }\n const informative = refusals.find(\n (r) => r.reason && !/no payment header|no API key/i.test(r.reason),\n );\n return informative ?? refusals[0] ?? { ok: false, reason: \"no payment presented\" };\n },\n async settle(verified: VerifyResult) {\n const owner = verifiers.find(\n (v) => v.settle && verified.rail !== undefined && railOf(v) === verified.rail,\n );\n const settled = await owner?.settle?.(verified);\n if (settled) return settled;\n // No verifier owns this rail's settlement. That is correct for a rail which already took\n // its money during verification (prepaid credits), and a bug for anything else — so say\n // which, rather than reporting a success nobody performed.\n if (verified.rail === \"prepaid_credits\") return { ok: true };\n return {\n ok: false,\n reason: `nothing settles the ${verified.rail ?? \"unknown\"} rail on this deployment`,\n };\n },\n };\n}\n\n/** Which rail a verifier settles. Only the facilitator verifier settles anything today. */\nfunction railOf(verifier: PaymentVerifier): PaymentRail | undefined {\n return \"settle\" in verifier && typeof verifier.settle === \"function\" ? \"x402\" : undefined;\n}\n","/**\n * @agentwares/x402 — 402 Payment Required helper + verifier interface.\n *\n * The 402 body advertises both rails. Both settle; only one of them settles without a person:\n *\n * - **prepaid_credits (card, via Stripe)** — live. `payTo` is a self-serve endpoint that mints a\n * prepaid key and hands back a Stripe Checkout URL, so an agent can go from a 402 to\n * a paid call without a human. The verifier lives in `@agentwares/billing`\n * (`createCreditsVerifier`), which is where the database and the Stripe client are.\n * - **x402 (USDC on Base)** — live, and the only rail an unattended agent can complete.\n * `createFacilitatorVerifier` checks the buyer's EIP-3009 signature with the PayAI\n * facilitator and settles after the work succeeds. `StubVerifier` remains for a\n * deployment with no receiving address, where it refuses rather than pretending.\n *\n * Nothing here holds funds.\n */\n\n/**\n * `prepaid_credits` is deliberately not called `mpp`. MPP is the Machine Payments Protocol\n * (Stripe + Tempo, March 2026): pre-authorised spending sessions an agent settles on its own.\n * This rail is a Stripe Checkout page that funds a balance — a different thing, needing a\n * person. An agent that knows MPP and sees `mpp` will attempt MPP semantics and fail, so the\n * name stays free for a real implementation.\n */\nimport { USDC_BASE, USDC_EIP712_DOMAIN, toAtomicUnits } from \"./facilitator.js\";\n\nexport type PaymentRail = \"x402\" | \"prepaid_credits\";\n\nexport interface PaymentRequirement {\n rail: PaymentRail;\n /** decimal USD string, e.g. \"0.05\" */\n amountUsd: string;\n /** resource being paid for, usually the request URL or tool name */\n resource: string;\n description?: string;\n /** x402: network + asset; mpp: currency */\n network?: string;\n /**\n * x402: the token's **contract address**, not its symbol.\n *\n * It used to be the string \"USDC\", which no client can act on — a buyer needs the address to\n * build the EIP-3009 signature. Every catalogued resource in the Bazaar carries an address\n * here; ours carried a ticker, and that alone made our 402s unpayable by anything but our\n * own script.\n */\n asset?: string;\n currency?: string;\n /**\n * x402: the settlement scheme. `exact` is the only one defined today, and a client that\n * does not see it cannot tell which signature to produce.\n */\n scheme?: string;\n /** x402: the price in the token's atomic units, which is what gets signed. */\n amount?: string;\n /**\n * x402: the EIP-712 domain of the asset. Without it a buyer cannot build the typed data and\n * the facilitator rejects the payment with `invalid_exact_evm_missing_eip712_domain`.\n */\n extra?: Record<string, unknown>;\n /** x402: the media type of what payment buys. */\n mimeType?: string;\n /** where to pay; absent while payments are not live */\n payTo?: string;\n /** seconds the quote is valid */\n maxTimeoutSeconds?: number;\n /**\n * True when settling this rail needs a person — today, a hosted Stripe Checkout card form.\n * An autonomous caller should pick a requirement without this flag; one that has it is\n * offered so an agent working alongside a human can hand the URL over rather than fail.\n */\n humanRequired?: boolean;\n /**\n * Discovery metadata for the x402 `bazaar` extension, when this resource declares one.\n * Carried per requirement rather than per verifier so a product with several priced routes\n * can describe each one; see BazaarExtension in ./facilitator.ts.\n */\n bazaar?: Record<string, unknown>;\n}\n\n/** Everything an agent needs to buy a key and fund it without a human. */\nexport interface SelfServe {\n /** POST here with no auth to get a key with a zero balance + a Checkout URL. */\n keysUrl: string;\n /** GET with the key to read the balance; POST to create another top-up. */\n creditsUrl?: string;\n /**\n * POST here with the key to fund it in USDC over x402 — the only top-up an unattended\n * agent can finish. `creditsUrl` ends at a hosted card page.\n */\n creditsX402Url?: string;\n /** credit pack sizes in USD */\n packsUsd: number[];\n /** header that makes a retried paid call charge only once */\n idempotencyHeader: \"Idempotency-Key\";\n}\n\nexport interface PaymentRequiredBody {\n code: \"PAYMENT_REQUIRED\";\n cause: string;\n fix: string;\n retryable: true;\n priceUsd: number;\n accepts: PaymentRequirement[];\n /** true while neither rail can actually be settled */\n comingSoon: boolean;\n /** how to pay today: API key + prepaid credits */\n alternatives: string[];\n /** present once the card rail is live: the whole no-human purchase path */\n selfServe?: SelfServe;\n /**\n * x402 v2 extensions. `bazaar` is discovery metadata a client is expected to echo back in\n * its payment payload; without that echo the facilitator will not catalog the resource, so\n * a resource that omits this is payable but permanently unlistable.\n */\n extensions?: Record<string, unknown>;\n}\n\nexport interface PaymentRequiredResponse {\n status: 402;\n headers: Record<string, string>;\n body: PaymentRequiredBody;\n}\n\nexport interface BuildPaymentRequiredOptions {\n resource: string;\n priceUsd: number;\n description?: string;\n /** set once a rail can actually be settled (drops `comingSoon`) */\n live?: boolean;\n /** x402 rail: the USDC address payment is sent to. Unset = the rail is not advertised. */\n payTo?: string;\n /** CAIP-2 chain for the x402 rail; Base mainnet unless the receive address lives elsewhere. */\n network?: string;\n /** x402 token contract address. Defaults to USDC on Base; set it when the chain differs. */\n asset?: string;\n /** EIP-712 domain of that token. Must match the asset or the facilitator rejects the payment. */\n assetDomain?: Record<string, unknown>;\n /**\n * Decimals of that token. Defaults to USDC's six.\n *\n * Set it whenever `asset` is set, and set the same value on the verifier. The price is signed\n * in atomic units, so the wrong decimals do not fail loudly — the 402 quotes an amount off by\n * a factor of a thousand or a million, and a buyer signs for exactly that.\n */\n assetDecimals?: number;\n /** prepaid_credits rail: the URL that takes a card and funds a balance. */\n creditsPayTo?: string;\n signupUrl?: string;\n /** the no-human purchase path; included in the body when the card rail is live */\n selfServe?: SelfServe;\n /**\n * Discovery metadata for the x402 `bazaar` extension. Advertised in the 402 so a client\n * can echo it; see BazaarExtension in ./facilitator.ts for why that echo is the whole\n * mechanism.\n */\n bazaar?: Record<string, unknown>;\n /**\n * True when this resource really does answer `sample=true` free and keyless.\n *\n * The 402's `fix` prose used to promise one unconditionally, which was a lie on every\n * product without sample mode and absurd on a credit top-up. An agent that believes it\n * spends a call finding out.\n */\n sampleMode?: boolean;\n}\n\n/** Base mainnet. The CDP facilitator also settles Polygon, Arbitrum, World and Solana. */\nexport const DEFAULT_X402_NETWORK = \"eip155:8453\";\n\nexport const X402_HEADER = \"X-Payment-Requirements\";\nexport const X402_REQUIRED_HEADER = \"PAYMENT-REQUIRED\";\n\nfunction toAmount(priceUsd: number): string {\n if (!Number.isFinite(priceUsd) || priceUsd < 0)\n throw new Error(\"priceUsd must be a non-negative number\");\n return priceUsd.toFixed(6).replace(/0+$/, \"\").replace(/\\.$/, \".0\");\n}\n\n/** Build the 402 response (status, headers, JSON body) for a paid resource. */\nexport function buildPaymentRequired(opts: BuildPaymentRequiredOptions): PaymentRequiredResponse {\n const amountUsd = toAmount(opts.priceUsd);\n // `accepts` is a promise that the rail can be settled, so a rail with nowhere to send the\n // money is left out entirely. The x402 entry used to be advertised with `payTo: undefined`\n // while no CDP account existed: an agent that picked it had no address to pay and burned a\n // retry on a method we could never have honoured.\n const creditsPayTo = opts.creditsPayTo ?? opts.selfServe?.keysUrl;\n const accepts: PaymentRequirement[] = [];\n if (opts.payTo) {\n // The fields a standard x402 client needs to construct a payment, in the shape every\n // catalogued resource in the Bazaar actually serves: `scheme`, the price in atomic units,\n // the token's contract address and its EIP-712 domain.\n //\n // These were missing. The entry carried `amountUsd: \"0.02\"` and `asset: \"USDC\"`, which is\n // readable by a person and unusable by a buyer: no scheme to pick, no atomic amount to\n // sign, and a ticker where the signature needs an address. Our own bootstrap script filled\n // the gaps from local knowledge, which is why payments settled in testing and never once\n // from outside. `rail` and `amountUsd` stay because they are useful and harmless.\n accepts.push({\n rail: \"x402\",\n scheme: \"exact\",\n amountUsd,\n amount: toAtomicUnits(amountUsd, opts.assetDecimals),\n resource: opts.resource,\n description: opts.description,\n mimeType: \"application/json\",\n network: opts.network ?? DEFAULT_X402_NETWORK,\n asset: opts.asset ?? USDC_BASE,\n extra: opts.assetDomain ?? USDC_EIP712_DOMAIN,\n payTo: opts.payTo,\n maxTimeoutSeconds: 300,\n ...(opts.bazaar ? { bazaar: opts.bazaar } : {}),\n });\n }\n if (creditsPayTo) {\n accepts.push({\n rail: \"prepaid_credits\",\n amountUsd,\n resource: opts.resource,\n description: opts.description,\n currency: \"usd\",\n payTo: creditsPayTo,\n maxTimeoutSeconds: 300,\n // funding a balance ends at a hosted Stripe Checkout page, which an agent cannot fill in\n humanRequired: true,\n });\n }\n const live = opts.live === true;\n const selfServe = opts.selfServe;\n // Say plainly which step a machine can do and which one it cannot. An agent that reads\n // \"pay the card form\" as an instruction to itself will loop: the Checkout URL is a hosted\n // web page.\n //\n // Order matters more than it looks. Many agents act on `fix` prose rather than parsing\n // `accepts`, so whatever is named first is what gets attempted. This text used to describe\n // only the card rail — the one that needs a person — while the USDC rail settled fine and\n // went unmentioned, which told every unattended caller to give up in front of a working\n // checkout. Lead with the rail that needs nobody.\n const x402Rail = accepts.find((a) => a.rail === \"x402\" && a.payTo);\n const usdcFix = x402Rail\n ? `Pay in USDC with no account and no human: take the \\`accepts\\` entry with ` +\n `\\`rail: \"x402\"\\`, sign an EIP-3009 transferWithAuthorization for ${x402Rail.amountUsd} ` +\n `USDC to ${x402Rail.payTo} on ${x402Rail.network}, and retry with it base64 in the ` +\n `X-PAYMENT header. The facilitator submits the transfer, so you need USDC and no gas. `\n : \"\";\n // Only when there is one. This was unconditional, so every 402 in the portfolio promised a\n // free sample — including products that have none, and including the credit top-up endpoint,\n // where it read as an offer of free credit.\n const sampleFix = opts.sampleMode\n ? \"Free first: retry with sample=true — no key, no payment. \"\n : \"\";\n const cardFix = selfServe\n ? `Or pay by card: POST ${selfServe.keysUrl} (no auth, no signup) returns a key and a Stripe ` +\n `Checkout URL. Funding that key needs a person at a browser; if you are running unattended, ` +\n `surface the URL to your operator rather than retrying, or use the USDC rail above. Once ` +\n `funded, send Authorization: Bearer <key>, plus Idempotency-Key so a repeated call is ` +\n `charged once.`\n : \"\";\n const liveFix =\n usdcFix || cardFix\n ? `${sampleFix}${usdcFix}${cardFix}`.trim()\n : \"Retry with a PAYMENT header satisfying one of `accepts`, or send an API key with credit balance.\";\n const body: PaymentRequiredBody = {\n code: \"PAYMENT_REQUIRED\",\n cause: live\n ? `This call costs $${amountUsd}. No valid payment or credit was presented.`\n : `This call costs $${amountUsd}. Pay-per-call (x402 / Stripe MPP) is coming soon; use an API key with prepaid credits.`,\n fix: live\n ? liveFix\n : `Create an API key${opts.signupUrl ? ` at ${opts.signupUrl}` : \"\"} and retry with Authorization: Bearer <key>. Try the free sample mode first.`,\n retryable: true,\n priceUsd: opts.priceUsd,\n accepts,\n comingSoon: !live,\n alternatives: [\n ...(creditsPayTo ? [\"api_key_credits\"] : []),\n ...(opts.sampleMode ? [\"sample_mode\"] : []),\n ],\n ...(selfServe ? { selfServe } : {}),\n ...(opts.bazaar ? { extensions: { bazaar: opts.bazaar } } : {}),\n };\n // The machine-readable header carries the extension too: a client that reads only the\n // header, which the spec allows, still sees what it has to echo.\n const encoded = JSON.stringify({\n x402Version: 2,\n accepts,\n resource: opts.resource,\n ...(opts.bazaar ? { extensions: { bazaar: opts.bazaar } } : {}),\n });\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"WWW-Authenticate\": `Payment realm=\"agentwares\", methods=\"x402 prepaid_credits\", price=\"${amountUsd} USD\"`,\n [X402_HEADER]: encoded,\n [X402_REQUIRED_HEADER]: btoa(encoded),\n \"Cache-Control\": \"no-store\",\n };\n return { status: 402, headers, body };\n}\n\nexport interface VerifyResult {\n ok: boolean;\n rail?: PaymentRail;\n receipt?: unknown;\n reason?: string;\n}\n\n/** Given a request, decide whether it carries a valid payment. */\nexport interface PaymentVerifier {\n verify(request: Request, requirement: PaymentRequirement): Promise<VerifyResult>;\n /**\n * Optional second step for rails where verifying and taking the money are separate acts.\n * x402 works this way: checking a signature is free, submitting the transfer is not, so\n * settlement happens only after the paid work succeeded and a failed call is never\n * charged. Rails that debit during `verify` (prepaid credits) leave this unimplemented\n * and refund through `onPaidFailure` instead.\n */\n settle?(verified: VerifyResult): Promise<{ ok: boolean; reason?: string }>;\n}\n\n/**\n * Never accepts a payment, never touches funds. Still the verifier for the x402/USDC rail\n * (no CDP account yet); the card rail uses `createCreditsVerifier` from @agentwares/billing.\n */\nexport class StubVerifier implements PaymentVerifier {\n async verify(request: Request, requirement: PaymentRequirement): Promise<VerifyResult> {\n const hasHeader = request.headers.has(\"PAYMENT\") || request.headers.has(\"X-PAYMENT\");\n return {\n ok: false,\n rail: requirement.rail,\n reason: hasHeader\n ? \"payments are not live yet (phase 2: wallet). Use an API key with credits.\"\n : \"no payment header present\",\n };\n }\n}\n\n/** Convenience: a Web-standard Response for the 402. */\nexport function paymentRequiredResponse(opts: BuildPaymentRequiredOptions): Response {\n const r = buildPaymentRequired(opts);\n return new Response(JSON.stringify(r.body), { status: r.status, headers: r.headers });\n}\n\nexport * from \"./facilitator.js\";\n","/**\n * Reading every page of a cursor-paginated MCP list (`tools/list`, `resources/list`,\n * `prompts/list`, …), bounded, and never a silent partial list.\n *\n * MCP paginates these with an opaque `nextCursor`; the last page omits it. A reader that stops\n * after one page, or at a fixed page count without saying so, hides whatever comes after — a\n * proxy cannot reach those tools, and a monitor reads them as removed. A reader with no bound\n * loops forever on a server that hands back the cursor it was given.\n *\n * {@link readAllPages} follows the cursor until it is absent or empty, stops at a cursor it has\n * already followed, and stops at a ceiling with `truncated` set, so the caller decides what a\n * partial list is worth: an error, the last good list, or the partial list with a warning. It\n * takes the page fetch as a callback, so it works over the SDK client, a raw JSON-RPC POST, or\n * anything else, and uses only Web-standard JavaScript (Node, Workers, browsers).\n *\n * Same semantics as agentcheck's `McpClient.listTools()` (BUG-2).\n */\n\n/** Pages read before a list counts as truncated (what mcpcheck and mcp-liveness follow). */\nexport const LIST_MAX_PAGES = 20;\n/**\n * Items read before a list counts as truncated. Above the largest tool catalog in\n * mcp-liveness's October 2026 census of the MCP registry (1,408 tools; 128 of 13,235 answering\n * servers list more than 100).\n */\nexport const LIST_MAX_ITEMS = 2_000;\n\nexport interface ListPage<T> {\n items: readonly T[];\n /** the page's `nextCursor`, as the server sent it; anything but a non-empty string ends the list */\n nextCursor?: unknown;\n}\n\nexport interface ReadAllPagesOptions {\n /** default {@link LIST_MAX_PAGES} */\n maxPages?: number;\n /** default {@link LIST_MAX_ITEMS} */\n maxItems?: number;\n /** the method, for the truncation reason (default `\"tools/list\"`) */\n method?: string;\n}\n\nexport interface ListTruncation {\n ceiling: \"pages\" | \"items\";\n /** one sentence a log line, a status field or a cell summary can carry as it is */\n reason: string;\n}\n\nexport interface ReadAllPagesResult<T> {\n /** every item read, in page order; when `truncated` is set, only the pages read */\n items: T[];\n pages: number;\n /** set when a ceiling stopped the read: `items` is then NOT the whole list */\n truncated?: ListTruncation;\n /**\n * true when the read ended at a cursor it had already followed. Not a truncation: following\n * it again could only return pages already read, so `items` is everything the server serves.\n */\n repeatedCursor?: true;\n}\n\n/**\n * Read every page. `fetchPage(cursor, page)` gets `undefined` for the first page (send no\n * cursor) and each `nextCursor` after that; `page` counts from 1. Errors from `fetchPage`\n * propagate unchanged.\n */\nexport async function readAllPages<T>(\n fetchPage: (cursor: string | undefined, page: number) => Promise<ListPage<T>>,\n opts: ReadAllPagesOptions = {},\n): Promise<ReadAllPagesResult<T>> {\n const maxPages = opts.maxPages ?? LIST_MAX_PAGES;\n const maxItems = opts.maxItems ?? LIST_MAX_ITEMS;\n const method = opts.method ?? \"tools/list\";\n const items: T[] = [];\n const followed = new Set<string>();\n let cursor: string | undefined;\n for (let page = 1; ; page++) {\n const res = await fetchPage(cursor, page);\n if (Array.isArray(res.items)) items.push(...res.items);\n const next = res.nextCursor;\n const more = typeof next === \"string\" && next !== \"\";\n if (items.length > maxItems) {\n return {\n items,\n pages: page,\n truncated: {\n ceiling: \"items\",\n reason: `${method} listed more than ${maxItems} items in ${page} page${page === 1 ? \"\" : \"s\"}${more ? \" and had more\" : \"\"}; at most ${maxItems} are read`,\n },\n };\n }\n if (!more) return { items, pages: page };\n if (followed.has(next)) return { items, pages: page, repeatedCursor: true };\n if (page >= maxPages) {\n return {\n items,\n pages: page,\n truncated: {\n ceiling: \"pages\",\n reason: `${method} had more than ${maxPages} pages (${items.length} items read); at most ${maxPages} pages are read`,\n },\n };\n }\n followed.add(next);\n cursor = next;\n }\n}\n","/**\n * `serveStdio` — the same tools over stdio (Claude Desktop, Cursor, `npx` launchers).\n * The only module in the kit that touches Node APIs; loaded lazily so Web-standard bundles\n * never pull it in.\n */\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { createMcpServer, type McpServerOptions } from \"./server.js\";\n\n/** Connect over stdio. Resolves when the transport closes (stdin ends). */\nexport async function serveStdio(serverOrOpts: McpServer | McpServerOptions): Promise<void> {\n const server = serverOrOpts instanceof McpServer ? serverOrOpts : createMcpServer(serverOrOpts);\n const { StdioServerTransport } = await import(\"@modelcontextprotocol/sdk/server/stdio.js\");\n const transport = new StdioServerTransport();\n await server.connect(transport);\n await new Promise<void>((resolve) => {\n const previous = transport.onclose;\n transport.onclose = () => {\n previous?.();\n resolve();\n };\n });\n}\n","/**\n * Official MCP registry: `server.json` generator and the GitHub Actions workflow that publishes\n * it on tag via `mcp-publisher` with GitHub OIDC (no secrets).\n *\n * Field names follow the 2025-12-11 server.json schema\n * (https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json).\n */\n\nexport const SERVER_JSON_SCHEMA_URL =\n \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\";\n\n/** `^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$` — reverse-DNS namespace, one slash, server name. */\nexport const SERVER_NAME_PATTERN = /^[a-zA-Z0-9.-]+\\/[a-zA-Z0-9._-]+$/;\nconst MAX_DESCRIPTION_LENGTH = 100;\n\nexport interface ServerJsonRepository {\n url: string;\n source: \"github\";\n /** path inside a monorepo, e.g. `shelf/deal-memo` */\n subfolder?: string;\n}\n\nexport interface ServerJsonKeyValueInput {\n name: string;\n description?: string;\n isRequired?: boolean;\n isSecret?: boolean;\n default?: string;\n format?: \"string\" | \"number\" | \"boolean\" | \"filepath\";\n}\n\nexport interface ServerJsonNpmPackage {\n /** npm package name, e.g. `@agentwares/deal-memo-mcp` */\n identifier: string;\n version: string;\n /** default `npx` */\n runtimeHint?: string;\n environmentVariables?: ServerJsonKeyValueInput[];\n}\n\nexport interface GenerateServerJsonOptions {\n /** reverse-DNS, e.g. `io.github.agentwares/deal-memo` (OIDC publishing needs `io.github.<owner>/`) */\n name: string;\n /** ≤ 100 chars, capabilities not implementation */\n description: string;\n version: string;\n title?: string;\n repository: ServerJsonRepository;\n websiteUrl?: string;\n /** stdio package published to npm (package.json must carry `mcpName: <name>`) */\n npmPackage?: ServerJsonNpmPackage;\n /** hosted Streamable HTTP endpoint, e.g. `https://deal-memo.agentwares.dev/mcp` */\n remoteUrl?: string;\n /** headers the client must send to the remote (e.g. an API key input) */\n remoteHeaders?: ServerJsonKeyValueInput[];\n}\n\nexport interface ServerJsonPackage {\n registryType: \"npm\";\n registryBaseUrl: string;\n identifier: string;\n version: string;\n runtimeHint?: string;\n transport: { type: \"stdio\" };\n environmentVariables?: ServerJsonKeyValueInput[];\n}\n\nexport interface ServerJsonRemote {\n type: \"streamable-http\";\n url: string;\n headers?: ServerJsonKeyValueInput[];\n}\n\nexport interface ServerJson {\n $schema: string;\n name: string;\n description: string;\n title?: string;\n version: string;\n websiteUrl?: string;\n repository: ServerJsonRepository;\n packages?: ServerJsonPackage[];\n remotes?: ServerJsonRemote[];\n}\n\n/** Build a `server.json` object for the official MCP registry. Validates the fields it can. */\nexport function generateServerJson(opts: GenerateServerJsonOptions): ServerJson {\n if (!SERVER_NAME_PATTERN.test(opts.name)) {\n throw new Error(\n `server.json name must be reverse-DNS with exactly one slash (e.g. io.github.acme/my-server), got ${JSON.stringify(opts.name)}`,\n );\n }\n const description = opts.description.trim();\n if (description.length === 0 || description.length > MAX_DESCRIPTION_LENGTH) {\n throw new Error(\n `server.json description must be 1-${MAX_DESCRIPTION_LENGTH} characters, got ${description.length}`,\n );\n }\n if (!opts.version.trim()) throw new Error(\"server.json version is required\");\n if (!opts.npmPackage && !opts.remoteUrl) {\n throw new Error(\n \"server.json needs at least one of npmPackage (stdio) or remoteUrl (streamable-http)\",\n );\n }\n if (opts.remoteUrl !== undefined && !/^https?:\\/\\/\\S+$/.test(opts.remoteUrl)) {\n throw new Error(`remoteUrl must be an http(s) URL, got ${JSON.stringify(opts.remoteUrl)}`);\n }\n\n const json: ServerJson = {\n $schema: SERVER_JSON_SCHEMA_URL,\n name: opts.name,\n description,\n version: opts.version,\n repository: { ...opts.repository },\n };\n if (opts.title !== undefined) json.title = opts.title;\n if (opts.websiteUrl !== undefined) json.websiteUrl = opts.websiteUrl;\n if (opts.npmPackage) {\n const pkg: ServerJsonPackage = {\n registryType: \"npm\",\n registryBaseUrl: \"https://registry.npmjs.org\",\n identifier: opts.npmPackage.identifier,\n version: opts.npmPackage.version,\n runtimeHint: opts.npmPackage.runtimeHint ?? \"npx\",\n transport: { type: \"stdio\" },\n };\n if (opts.npmPackage.environmentVariables?.length) {\n pkg.environmentVariables = opts.npmPackage.environmentVariables;\n }\n json.packages = [pkg];\n }\n if (opts.remoteUrl !== undefined) {\n const remote: ServerJsonRemote = { type: \"streamable-http\", url: opts.remoteUrl };\n if (opts.remoteHeaders?.length) remote.headers = opts.remoteHeaders;\n json.remotes = [remote];\n }\n return json;\n}\n\nexport interface RegistryPublishWorkflowOptions {\n /** repo-relative path, e.g. `shelf/deal-memo/server.json` */\n serverJsonPath: string;\n /** tag glob that triggers publishing (default `mcp-*`) */\n tagPattern?: string;\n /** workflow display name */\n workflowName?: string;\n /** commands to run before publishing (e.g. build + npm publish); each becomes a step */\n beforePublish?: { name: string; run: string }[];\n /** pin the mcp-publisher release (default: latest) */\n publisherVersion?: string;\n}\n\nfunction yamlString(value: string): string {\n return JSON.stringify(value);\n}\n\n/**\n * GitHub Actions workflow (YAML) that publishes `server.json` to the official MCP registry\n * on tags matching `tagPattern`, authenticating with GitHub OIDC (`permissions.id-token: write`).\n * Steps follow the registry's github-actions guide: install mcp-publisher from GitHub releases,\n * `mcp-publisher login github-oidc`, `mcp-publisher publish`.\n */\nexport function registryPublishWorkflow(opts: RegistryPublishWorkflowOptions): string {\n const tagPattern = opts.tagPattern ?? \"mcp-*\";\n const name = opts.workflowName ?? \"Publish to MCP Registry\";\n const releasePath = opts.publisherVersion\n ? `download/${opts.publisherVersion}`\n : \"latest/download\";\n const before = (opts.beforePublish ?? [])\n .map(\n (step) =>\n ` - name: ${yamlString(step.name)}\\n run: |\\n${step.run\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\")}\\n\\n`,\n )\n .join(\"\");\n\n return `name: ${yamlString(name)}\n\non:\n push:\n tags: [${yamlString(tagPattern)}]\n\njobs:\n publish:\n runs-on: ubuntu-latest\n permissions:\n id-token: write\n contents: read\n env:\n SERVER_JSON: ${yamlString(opts.serverJsonPath)}\n\n steps:\n - name: Checkout code\n uses: actions/checkout@v5\n\n${before} - name: Install mcp-publisher\n run: |\n curl -L \"https://github.com/modelcontextprotocol/registry/releases/${releasePath}/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz\" | tar xz mcp-publisher\n\n - name: Authenticate to MCP Registry (GitHub OIDC)\n run: ./mcp-publisher login github-oidc\n\n - name: Publish server.json to MCP Registry\n run: |\n dir=\"$(dirname \"$SERVER_JSON\")\"\n if [ \"$(basename \"$SERVER_JSON\")\" != \"server.json\" ]; then cp \"$SERVER_JSON\" \"$dir/server.json\"; fi\n cd \"$dir\" && \"$GITHUB_WORKSPACE/mcp-publisher\" publish\n`;\n}\n","/**\n * Machine-readable docs every product ships: `llms.txt` and `pricing.json`.\n */\nimport { listToolManifest } from \"./server.js\";\nimport type { ToolDef } from \"./tool.js\";\n\nexport interface LlmsTxtLink {\n title: string;\n url: string;\n note?: string;\n}\n\nexport interface LlmsTxtSection {\n title: string;\n links: LlmsTxtLink[];\n}\n\nexport interface RenderLlmsTxtOptions {\n /** product name — becomes the H1 */\n name: string;\n /** one-line summary — becomes the blockquote */\n summary: string;\n /** optional paragraphs after the summary */\n description?: string;\n /** primary links (docs, MCP endpoint, pricing.json, openapi) */\n links: LlmsTxtLink[];\n /** extra sections, e.g. \"Optional\" */\n sections?: LlmsTxtSection[];\n /** when given, an \"MCP tools\" section lists name, description and input fields */\n tools?: readonly ToolDef[];\n}\n\nfunction renderLink(link: LlmsTxtLink): string {\n return `- [${link.title}](${link.url})${link.note ? `: ${link.note}` : \"\"}`;\n}\n\n/** Render an llms.txt document (https://llmstxt.org): H1, blockquote summary, link sections. */\nexport function renderLlmsTxt(opts: RenderLlmsTxtOptions): string {\n const lines: string[] = [`# ${opts.name.trim()}`, \"\", `> ${opts.summary.trim()}`, \"\"];\n if (opts.description) lines.push(opts.description.trim(), \"\");\n lines.push(\"## Links\", \"\", ...opts.links.map(renderLink), \"\");\n for (const section of opts.sections ?? []) {\n lines.push(`## ${section.title}`, \"\", ...section.links.map(renderLink), \"\");\n }\n if (opts.tools && opts.tools.length > 0) {\n lines.push(\"## MCP tools\", \"\");\n for (const entry of listToolManifest(opts.tools)) {\n const properties = entry.inputSchema.properties;\n const required = new Set(\n Array.isArray(entry.inputSchema.required) ? (entry.inputSchema.required as string[]) : [],\n );\n const fields =\n properties && typeof properties === \"object\"\n ? Object.keys(properties as Record<string, unknown>).map((key) =>\n required.has(key) ? key : `${key}?`,\n )\n : [];\n lines.push(\n `- \\`${entry.name}\\`${fields.length ? ` (${fields.join(\", \")})` : \"\"}: ${entry.description.trim()}`,\n );\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n}\n\nexport interface PricingTier {\n /** stable id used in checkout, e.g. `starter` */\n id: string;\n name: string;\n /** 0 for free tiers */\n priceUsdMonthly: number;\n /** quotas, e.g. `{ monitors: 5, checks_per_day: 288 }` */\n limits: Record<string, number | string | boolean | null>;\n features: string[];\n checkoutUrl?: string;\n}\n\nexport interface PricingMeter {\n /** Stripe billing meter event name, e.g. `agentcheck_docs_eval_run` */\n eventName: string;\n unitPriceUsd: number;\n /** what one unit is, e.g. `run` */\n unit: string;\n description?: string;\n}\n\nexport interface PricingJsonOptions {\n product: string;\n currency: \"usd\";\n tiers: PricingTier[];\n meters?: PricingMeter[];\n checkoutUrl?: string;\n portalUrl?: string;\n updatedAt: string | Date;\n /**\n * Present when this product is parked or retired. The endpoints keep serving — see\n * `packages/config/src/lifecycle.ts` — but an agent reads this file as a commitment, and it\n * deserves to know nobody is maintaining this before it builds on it.\n */\n lifecycle?: {\n stage: string;\n since: string;\n reason: string;\n insteadUrl?: string;\n };\n}\n\nexport interface PricingJson {\n schema: \"agentwares.pricing/v1\";\n product: string;\n currency: \"usd\";\n tiers: PricingTier[];\n meters: PricingMeter[];\n checkoutUrl?: string;\n portalUrl?: string;\n /** absent while a product is active; see PricingJsonOptions */\n lifecycle?: { stage: string; since: string; reason: string; insteadUrl?: string };\n /** ISO 8601 */\n updatedAt: string;\n}\n\n/** Build the `pricing.json` object served next to every pricing page. */\nexport function pricingJson(opts: PricingJsonOptions): PricingJson {\n if (opts.tiers.length === 0) throw new Error(\"pricing.json needs at least one tier\");\n const ids = new Set<string>();\n for (const tier of opts.tiers) {\n if (ids.has(tier.id)) throw new Error(`pricing.json: duplicate tier id ${tier.id}`);\n ids.add(tier.id);\n if (!Number.isFinite(tier.priceUsdMonthly) || tier.priceUsdMonthly < 0) {\n throw new Error(`pricing.json: tier ${tier.id} has an invalid priceUsdMonthly`);\n }\n }\n const updatedAt = new Date(opts.updatedAt);\n if (Number.isNaN(updatedAt.getTime())) throw new Error(\"pricing.json: updatedAt is not a date\");\n\n const json: PricingJson = {\n schema: \"agentwares.pricing/v1\",\n product: opts.product,\n currency: opts.currency,\n tiers: opts.tiers,\n meters: opts.meters ?? [],\n updatedAt: updatedAt.toISOString(),\n };\n if (opts.checkoutUrl !== undefined) json.checkoutUrl = opts.checkoutUrl;\n if (opts.portalUrl !== undefined) json.portalUrl = opts.portalUrl;\n if (opts.lifecycle !== undefined) json.lifecycle = opts.lifecycle;\n return json;\n}\n","/**\n * The documents an agent or a registry fetches before it decides whether to use you.\n *\n * Checked against the primary sources on 10 September 2026, because the summaries are wrong\n * about this in ways that matter. Two paths that get recommended everywhere are not served\n * here on purpose:\n *\n * - `/.well-known/mcp.json` — no specification defines it. Six live examples were compared\n * and no two share a schema (`servers[]`, `mcpServers{}`, `{name,description,endpoint}`,\n * a registry `server.json`, …). A client that guesses wrong attempts a connection and\n * fails, rather than skipping gracefully, so publishing a seventh shape is worse than\n * publishing nothing.\n * - `/.well-known/mcp/server-card.json` — the MCP extension's own discovery document lists\n * this under \"alternatives considered, not recommended\". A server card is application\n * metadata, not site metadata, so it belongs at the MCP endpoint. `serverCardResponse`\n * serves it at `<mcp-url>/server-card`, which is the reserved location GitHub and\n * Hugging Face already use in production.\n *\n * Nothing here is invented. `ai-catalog.json` follows the AI Catalog specification, which is\n * what GitHub, Vercel, Hugging Face, Supabase, Apify and Zapier serve today and what\n * Hugging Face's `hf discover` reads. `security.txt` is RFC 9116. The server card follows the\n * MCP `ext-server-card` schema, which is still experimental and may change — the shape is\n * additive and inert, so a client that does not know it ignores it.\n *\n * One failure mode is worth more than the rest: **a 200 with the wrong body is worse than a\n * 404.** A framework catch-all that answers every unknown path with an HTML page will serve\n * HTML at `/.well-known/anything`, and a crawler trusting the status code parses it as JSON.\n * Every helper here returns an explicit content type, and anything not served must genuinely\n * 404.\n */\n\n/** RFC 9116 §2.5.3: `Expires` should be under a year out, and a stale file is worse than none. */\nexport interface SecurityTxtOptions {\n /** at least one; mailto: or https: */\n contact: string[];\n /** ISO 8601 instant this file stops being trustworthy */\n expires: string;\n policyUrl?: string;\n acknowledgmentsUrl?: string;\n preferredLanguages?: string;\n /** where this file canonically lives; helps a reader spot a copy served from elsewhere */\n canonicalUrl?: string;\n}\n\nexport function securityTxt(options: SecurityTxtOptions): string {\n const lines: string[] = [];\n for (const contact of options.contact) lines.push(`Contact: ${contact}`);\n lines.push(`Expires: ${options.expires}`);\n if (options.policyUrl) lines.push(`Policy: ${options.policyUrl}`);\n if (options.acknowledgmentsUrl) lines.push(`Acknowledgments: ${options.acknowledgmentsUrl}`);\n if (options.preferredLanguages) lines.push(`Preferred-Languages: ${options.preferredLanguages}`);\n if (options.canonicalUrl) lines.push(`Canonical: ${options.canonicalUrl}`);\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nexport function securityTxtResponse(options: SecurityTxtOptions): Response {\n return new Response(securityTxt(options), {\n headers: {\n \"content-type\": \"text/plain; charset=utf-8\",\n \"cache-control\": \"public, max-age=86400\",\n \"access-control-allow-origin\": \"*\",\n },\n });\n}\n\n/**\n * One thing an agent can use, listed in the catalog.\n *\n * `type` is a media type, and it is how a reader decides whether it can consume the entry at\n * all — `application/mcp-server-card+json` for an MCP server, `application/json` for a REST\n * API with an OpenAPI description. Exactly one of `url` or `data` is allowed.\n */\nexport interface AiCatalogEntry {\n identifier: string;\n type: string;\n url?: string;\n data?: unknown;\n displayName?: string;\n description?: string;\n tags?: string[];\n /**\n * Two to five things somebody would actually ask, in their words. This is what makes an\n * entry findable rather than merely present, and it is the field most publishers skip.\n */\n representativeQueries?: string[];\n}\n\nexport interface AiCatalogOptions {\n /** the publisher's own domain; `identifier` values are namespaced under it */\n host: { displayName: string; identifier: string; documentationUrl?: string };\n entries: AiCatalogEntry[];\n}\n\n/** `urn:air:{publisher}:{namespace}:{name}` — the publisher must be a domain you control. */\nexport function airUrn(publisher: string, namespace: string, name: string): string {\n return `urn:air:${publisher}:${namespace}:${name}`;\n}\n\nexport function aiCatalog(options: AiCatalogOptions): Record<string, unknown> {\n return {\n specVersion: \"1.0\",\n host: options.host,\n entries: options.entries.map((e) => ({\n identifier: e.identifier,\n ...(e.displayName ? { displayName: e.displayName } : {}),\n type: e.type,\n ...(e.url ? { url: e.url } : {}),\n ...(e.data !== undefined ? { data: e.data } : {}),\n ...(e.description ? { description: e.description } : {}),\n ...(e.tags?.length ? { tags: e.tags } : {}),\n ...(e.representativeQueries?.length\n ? { representativeQueries: e.representativeQueries }\n : {}),\n })),\n };\n}\n\nexport function aiCatalogResponse(options: AiCatalogOptions): Response {\n return new Response(`${JSON.stringify(aiCatalog(options), null, 2)}\\n`, {\n headers: {\n // the spec's media type; unregistered with IANA, but it is what every live publisher sends\n \"content-type\": \"application/ai-catalog+json\",\n \"cache-control\": \"public, max-age=3600\",\n \"access-control-allow-origin\": \"*\",\n },\n });\n}\n\n/**\n * An MCP server card, served at `<streamable-http-url>/server-card`.\n *\n * `description` is capped at 100 characters by the schema, which is easy to violate and\n * awkward to debug, so it is enforced here instead of at whatever reads it.\n */\nexport interface ServerCardOptions {\n /** reverse-DNS with exactly one slash, e.g. `io.github.agentwares/stablecoin-attestations` */\n name: string;\n version: string;\n /** at most 100 characters */\n description: string;\n title?: string;\n websiteUrl?: string;\n repository?: { url: string; source?: string; id?: string };\n /** where the server actually answers */\n remotes?: { type: \"streamable-http\" | \"sse\"; url: string }[];\n}\n\nconst SERVER_CARD_NAME = /^[a-zA-Z0-9.-]+\\/[a-zA-Z0-9._-]+$/;\n\nexport function serverCard(options: ServerCardOptions): Record<string, unknown> {\n if (!SERVER_CARD_NAME.test(options.name)) {\n throw new Error(\n `server card name must be reverse-DNS with one slash, got ${JSON.stringify(options.name)}`,\n );\n }\n if (options.description.length > 100) {\n throw new Error(\n `server card description is capped at 100 characters, got ${options.description.length}`,\n );\n }\n return {\n // The schema pattern-requires this exact string. It 404s today, so publish the literal\n // and do not try to fetch it at runtime.\n $schema: \"https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json\",\n name: options.name,\n version: options.version,\n description: options.description,\n ...(options.title ? { title: options.title } : {}),\n ...(options.websiteUrl ? { websiteUrl: options.websiteUrl } : {}),\n ...(options.repository ? { repository: options.repository } : {}),\n ...(options.remotes?.length ? { remotes: options.remotes } : {}),\n };\n}\n\nexport function serverCardResponse(options: ServerCardOptions): Response {\n return new Response(`${JSON.stringify(serverCard(options), null, 2)}\\n`, {\n headers: {\n \"content-type\": \"application/mcp-server-card+json\",\n \"cache-control\": \"public, max-age=3600\",\n \"access-control-allow-origin\": \"*\",\n },\n });\n}\n","/**\n * Downstream side of the proxy: the MCP server an agent connects to. One instance per session\n * (stdio: one; Streamable HTTP: one per `Mcp-Session-Id`). Every request is served from the\n * runtime; tool calls go through the policy engine.\n */\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport {\n CallToolRequestSchema,\n CompleteRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourceTemplatesRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n SetLevelRequestSchema,\n SubscribeRequestSchema,\n UnsubscribeRequestSchema,\n type CallToolResult,\n type ServerNotification,\n type ServerRequest,\n type Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n keyFromHeaders,\n resolveAgent,\n type AgentScope,\n type GuardErrorBody,\n type GuardResult,\n} from \"@agentwares/agentguard-core\";\nimport { version as cliVersion } from \"../version.js\";\nimport {\n INIT_COMMAND,\n callOwnTool,\n createOwnTools,\n ownToolList,\n ownToolsActive,\n} from \"./own-tools.js\";\nimport type { DownstreamSession, ExposedTool, ProxyRuntime } from \"./runtime.js\";\n\n/**\n * Reported to every MCP client in `serverInfo`. Derived from package.json rather than written\n * out, because a hand-maintained copy drifts: this said 0.1.0 while npm served 0.1.2, so a\n * client could not tell which build it was talking to.\n */\nexport const PROXY_VERSION = cliVersion();\n\ntype Extra = RequestHandlerExtra<ServerRequest, ServerNotification>;\n\nexport interface DownstreamOptions {\n /** run id for calls that carry neither `X-Run-Id` nor `_meta.runId` (default: runtime.defaultRunId) */\n defaultRunId?: string;\n}\n\nfunction headerValue(extra: Extra, name: string): string | undefined {\n const raw =\n extra.requestInfo?.headers?.[name] ?? extra.requestInfo?.headers?.[name.toLowerCase()];\n if (Array.isArray(raw)) return raw[0];\n return typeof raw === \"string\" ? raw : undefined;\n}\n\nfunction headersOf(extra: Extra): Record<string, string | undefined> {\n const out: Record<string, string | undefined> = {};\n for (const [k, v] of Object.entries(extra.requestInfo?.headers ?? {}))\n out[k.toLowerCase()] = Array.isArray(v) ? v[0] : v;\n return out;\n}\n\nexport function runIdFor(\n extra: Extra,\n meta: Record<string, unknown> | undefined,\n fallback: string,\n): string {\n const header = headerValue(extra, \"x-run-id\");\n if (header && header.trim()) return header.trim().slice(0, 128);\n const fromMeta = meta?.runId ?? meta?.[\"agentguard/runId\"] ?? meta?.run_id;\n if (typeof fromMeta === \"string\" && fromMeta.trim()) return fromMeta.trim().slice(0, 128);\n if (extra.sessionId) return `sess_${extra.sessionId.slice(0, 12)}`;\n return fallback;\n}\n\n/** Shape the engine's verdict into what the MCP client receives. */\nexport function toCallToolResult(\n result: GuardResult,\n tool: ExposedTool | undefined,\n): CallToolResult {\n const meta = {\n agentguard: {\n class: result.decision.classification.class,\n verb: result.decision.classification.verb,\n mode: result.decision.mode,\n outcome: result.outcome,\n dryRun: result.faked,\n seq: result.entry.seq,\n run_id: result.entry.run_id,\n },\n };\n const hasOutputSchema = Boolean(tool?.tool.outputSchema);\n if (result.error) {\n const upstream = result.value as CallToolResult | undefined;\n if (upstream && upstream.content) {\n return { ...upstream, isError: true, _meta: { ...(upstream._meta ?? {}), ...meta } };\n }\n const body: GuardErrorBody = result.error;\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(body) }],\n ...(hasOutputSchema ? {} : { structuredContent: body }),\n _meta: { ...meta, httpStatus: httpStatusFor(body.code) },\n };\n }\n if (result.faked) {\n const value = result.value;\n const isObject = value !== null && typeof value === \"object\" && !Array.isArray(value);\n return {\n content: [\n { type: \"text\", text: typeof value === \"string\" ? value : JSON.stringify(value, null, 2) },\n ],\n ...(isObject ? { structuredContent: value as Record<string, unknown> } : {}),\n _meta: meta,\n };\n }\n const upstream = result.value as CallToolResult;\n return { ...upstream, _meta: { ...(upstream._meta ?? {}), ...meta } };\n}\n\nfunction httpStatusFor(code: string): number {\n switch (code) {\n case \"KILLED\":\n case \"TOOL_DENIED\":\n case \"APPROVAL_DENIED\":\n return 403;\n case \"APPROVAL_REQUIRED\":\n return 202;\n case \"CAP_EXCEEDED\":\n case \"LOOP_DETECTED\":\n return 429;\n case \"UNKNOWN_TOOL\":\n return 404;\n case \"UPSTREAM_ERROR\":\n return 502;\n default:\n return 500;\n }\n}\n\nexport function annotateTool(t: ExposedTool, mode: string): Tool {\n return {\n ...t.tool,\n name: t.name,\n _meta: {\n ...(t.tool._meta ?? {}),\n agentguard: {\n upstream: t.upstream,\n class: t.classification.class,\n verb: t.classification.verb,\n mode,\n },\n },\n };\n}\n\nfunction killedError(state: { reason?: string; source?: string }): Error {\n return Object.assign(\n new Error(`agentguard kill switch is on (${state.source ?? \"?\"}: ${state.reason ?? \"\"})`),\n { code: -32000 },\n );\n}\n\n/** What the client is told about this server, which depends on whether it fronts anything. */\nexport function serverInstructions(runtime: ProxyRuntime): string {\n if (ownToolsActive(runtime))\n return `agentguard is an MCP policy proxy, and this one fronts no upstream MCP servers${\n runtime.configured ? \"\" : ` (no policy file at ${runtime.loaded.path})`\n }, so it serves only its own read-only tools: agentguard_get_status (what it guards, caps, kill switch), agentguard_get_report (what a run did or would have done) and agentguard_verify_audit_log. To guard the user's MCP servers, run \\`${INIT_COMMAND}\\` in the project directory and restart the client.`;\n return `Tool calls pass through agentguard (${runtime.policy.mode} mode). Errors carry { code, cause, fix, retryable }; follow \"fix\". CAP_EXCEEDED, LOOP_DETECTED and KILLED are not retryable: stop and report to the user. APPROVAL_REQUIRED: relay the approval command to the user, then retry the identical call once.`;\n}\n\n/** Build the per-session MCP server. */\nexport function createDownstreamServer(\n runtime: ProxyRuntime,\n opts: DownstreamOptions = {},\n): McpServer {\n const server = new McpServer(\n { name: \"agentguard\", version: PROXY_VERSION, title: \"agentguard policy proxy\" },\n {\n capabilities: {\n tools: { listChanged: true },\n resources: { subscribe: true, listChanged: true },\n prompts: { listChanged: true },\n logging: {},\n completions: {},\n },\n instructions: serverInstructions(runtime),\n },\n );\n const ownTools = createOwnTools(runtime);\n const session: DownstreamSession = {\n id: crypto.randomUUID(),\n server,\n lastActive: Date.now(),\n inflight: new Map(),\n };\n runtime.attach(session);\n const previousOnClose = server.server.onclose;\n server.server.onclose = () => {\n previousOnClose?.();\n runtime.detach(session);\n };\n const touch = (): void => {\n session.lastActive = Date.now();\n };\n\n const agentFor = async (\n extra: Extra,\n ): Promise<{ agent: AgentScope | null | undefined; error?: GuardErrorBody }> => {\n const key = keyFromHeaders(headersOf(extra));\n if (!key) return { agent: undefined };\n const resolved = await resolveAgent(runtime.policy, { key });\n if (resolved.error) {\n return {\n agent: null,\n error: {\n code: \"TOOL_DENIED\",\n cause: \"the agent key in Authorization / X-Agentguard-Key is not in agentguard.yaml\",\n fix: \"use a key created with `agentguard key create <agent>`, or omit the key to use the global policy\",\n retryable: false,\n },\n };\n }\n return { agent: resolved.agent };\n };\n\n const low = server.server;\n low.setRequestHandler(ListToolsRequestSchema, async (_req, extra) => {\n touch();\n const { agent } = await agentFor(extra);\n const scope = agent === undefined ? runtime.agent : agent;\n if (ownToolsActive(runtime)) return { tools: ownToolList(ownTools) };\n return {\n tools: runtime\n .listTools(scope)\n .map((t) => annotateTool(t, scope?.mode ?? runtime.policy.mode)),\n };\n });\n\n low.setRequestHandler(CallToolRequestSchema, async (req, extra) => {\n touch();\n if (ownToolsActive(runtime)) {\n // Read-only answers about agentguard itself: no upstream, no policy decision, no audit entry.\n const own = await callOwnTool(\n ownTools,\n req.params.name,\n req.params.arguments ?? {},\n String(extra.requestId),\n );\n if (own) return own;\n }\n const { agent, error } = await agentFor(extra);\n const runId = runIdFor(extra, req.params._meta, opts.defaultRunId ?? runtime.defaultRunId);\n if (error) {\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(error) }],\n structuredContent: error,\n _meta: { httpStatus: 401 },\n };\n }\n const progressToken = req.params._meta?.progressToken;\n const { result, tool } = await runtime.callTool(req.params.name, req.params.arguments ?? {}, {\n runId,\n agent,\n sessionId: extra.sessionId ?? session.id,\n session,\n requestId: extra.requestId,\n onprogress:\n progressToken === undefined\n ? undefined\n : (p) => {\n void extra.sendNotification({\n method: \"notifications/progress\",\n params: { progressToken, ...p },\n });\n },\n });\n return toCallToolResult(result, tool);\n });\n\n const guardRead = async (): Promise<void> => {\n const state = await runtime.guard.killState();\n if (state.killed) throw killedError(state);\n };\n\n low.setRequestHandler(ListResourcesRequestSchema, async () => {\n touch();\n return runtime.listResources();\n });\n low.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {\n touch();\n return runtime.listResourceTemplates();\n });\n low.setRequestHandler(ReadResourceRequestSchema, async (req) => {\n touch();\n await guardRead();\n return runtime.readResource(req.params.uri);\n });\n low.setRequestHandler(SubscribeRequestSchema, async (req) => {\n await runtime.subscribe(req.params.uri, true);\n return {};\n });\n low.setRequestHandler(UnsubscribeRequestSchema, async (req) => {\n await runtime.subscribe(req.params.uri, false);\n return {};\n });\n low.setRequestHandler(ListPromptsRequestSchema, async () => {\n touch();\n return runtime.listPrompts();\n });\n low.setRequestHandler(GetPromptRequestSchema, async (req) => {\n touch();\n await guardRead();\n return runtime.getPrompt(req.params.name, req.params.arguments);\n });\n low.setRequestHandler(CompleteRequestSchema, async (req) => {\n touch();\n return runtime.complete(req.params);\n });\n low.setRequestHandler(SetLevelRequestSchema, async (req) => {\n await runtime.setLevel(req.params.level);\n return {};\n });\n return server;\n}\n","/**\n * agentguard's own tools: what an MCP client sees when the proxy has no upstream servers. That is\n * the proxy started with no `agentguard.yaml` at all (an \"Add to Cursor\" button, a registry\n * install, a Glama build) or with a policy that lists none.\n *\n * Three read-only answers: status, a run's report and a verify of the audit log. They call no\n * upstream, write no file, and are not recorded in the audit log they read. With upstreams\n * configured they are not listed, so an agent's tool surface behind the proxy is unchanged.\n */\nimport { createToolContext, defineTool, listToolManifest, toolError } from \"@agentwares/mcp-kit\";\nimport {\n buildReport,\n latestRunId,\n listRuns,\n parseAuditJsonl,\n renderReportMarkdown,\n verifyChain,\n type AuditEntry,\n type Caps,\n} from \"@agentwares/agentguard-core\";\nimport type { CallToolResult, Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { z } from \"zod\";\nimport type { ProxyRuntime } from \"./runtime.js\";\n\nexport const INIT_COMMAND = \"npx -y @agentwares/agentguard init\";\n\nconst READ_ONLY = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n} as const;\n\nconst runIdInput = z\n .string()\n .min(1)\n .max(128)\n .optional()\n .describe(\n \"Run to read, as it appears in the audit log (for example run_20261007093015_ab12, or the X-Run-Id an HTTP client sent). Omit it for the most recent run.\",\n );\n\nconst counters = z\n .record(z.string(), z.number())\n .describe(\n \"counter name (tool_calls, writes, deletes, emails, spend_usd or a custom one) → value\",\n );\n\n/** The audit file, read without creating it. A line that is not JSON is reported, not thrown. */\nfunction readAudit(path: string): { exists: boolean; entries: AuditEntry[]; error?: string } {\n if (!existsSync(path)) return { exists: false, entries: [] };\n try {\n return { exists: true, entries: parseAuditJsonl(readFileSync(path, \"utf8\")) };\n } catch (err) {\n return { exists: true, entries: [], error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction unreadable(path: string, error: string): Error {\n return toolError({\n code: \"AUDIT_UNREADABLE\",\n cause: `the audit log at ${path} could not be read: ${error}`,\n fix: \"call agentguard_verify_audit_log to see where it breaks; a hand-edited or truncated line has to be restored from a copy\",\n retryable: false,\n });\n}\n\nfunction numbers(caps: Caps): Record<string, number> {\n const out: Record<string, number> = {};\n for (const [k, v] of Object.entries(caps)) if (typeof v === \"number\") out[k] = v;\n return out;\n}\n\nfunction nextStep(runtime: ProxyRuntime): string {\n if (!runtime.configured)\n return `agentguard is guarding nothing: no policy file at ${runtime.loaded.path}. Run \\`${INIT_COMMAND}\\` in the project directory: it writes agentguard.yaml in dry-run mode and routes the project's MCP servers through agentguard (backup kept, \\`--undo\\` restores). Then restart the MCP client.`;\n if (runtime.policy.upstreams.length === 0)\n return `${runtime.loaded.path} lists no upstream servers, so agentguard is guarding nothing. Add the MCP servers your agent uses under \\`upstreams:\\` in that file (it has commented examples), then restart the MCP client.`;\n return \"agentguard is running; run your agent, then read agentguard_get_report.\";\n}\n\nconst StatusOutput = z.object({\n configured: z\n .boolean()\n .describe(\n \"true when a policy file was found and loaded; false means agentguard guards nothing\",\n ),\n policy_path: z.string().describe(\"absolute path of the policy file read, or looked for\"),\n mode: z\n .enum([\"dry-run\", \"enforce\"])\n .describe(\"dry-run fakes writes and spends and records them; enforce lets allowed calls run\"),\n upstreams: z\n .array(\n z.object({\n name: z.string().describe(\"upstream name from the policy\"),\n connected: z.boolean().describe(\"whether agentguard is connected to it\"),\n tools: z.number().int().describe(\"tools it exposes\"),\n transport: z.enum([\"stdio\", \"http\"]).describe(\"how agentguard reaches it\"),\n error: z.string().optional().describe(\"why it is not connected\"),\n }),\n )\n .describe(\"the MCP servers this proxy fronts; empty means none are configured\"),\n run_id: z\n .string()\n .nullable()\n .describe(\n \"run the usage is for: the requested run_id, else the latest run in the log, else null\",\n ),\n caps: z\n .object({ per_run: counters, per_day: counters })\n .describe(\"limits from the policy; a counter that is absent has no cap\"),\n used: z\n .object({ per_run: counters, per_day: counters })\n .describe(\"what that run, and today, have used against the caps\"),\n remaining: z\n .record(\n z.string(),\n z.object({ per_run: z.number().optional(), per_day: z.number().optional() }),\n )\n .describe(\"budget left per capped counter, per run and per day\"),\n kill_switch: z\n .object({\n on: z.boolean().describe(\"true halts every tool call with KILLED\"),\n reason: z.string().optional().describe(\"why it was pulled\"),\n source: z.string().optional().describe(\"file, env or memory\"),\n })\n .describe(\"the kill switch state\"),\n pending_approvals: z.number().int().describe(\"destructive calls waiting for a human decision\"),\n audit_log: z\n .object({\n path: z.string().describe(\"absolute path of the hash-chained JSONL audit log\"),\n entries: z.number().int().describe(\"entries in it; 0 when it does not exist yet\"),\n })\n .describe(\"where every tool call is recorded\"),\n next_step: z.string().describe(\"the one thing to do next, with the command when there is one\"),\n});\n\nconst ReportOutput = z.object({\n configured: z\n .boolean()\n .describe(\"false when no policy file was found (agentguard guards nothing)\"),\n audit_log_path: z.string().describe(\"absolute path of the audit log the report was built from\"),\n run_id: z.string().nullable().describe(\"the run reported on; null when the log has no runs\"),\n runs_in_log: z.number().int().describe(\"how many runs the audit log holds\"),\n tool_calls: z.number().int().describe(\"tool calls in this run\"),\n would_have: z\n .object({\n creates: z.number().int(),\n updates: z.number().int(),\n deletes: z.number().int(),\n sends: z.number().int(),\n executes: z.number().int(),\n spends: z.number().int(),\n spend_usd: z.number(),\n })\n .describe(\"what dry-run mode faked: what the run would have done had the calls executed\"),\n did: z\n .object({\n writes: z.number().int(),\n deletes: z.number().int(),\n sends: z.number().int(),\n spend_usd: z.number(),\n })\n .describe(\"what actually executed upstream\"),\n halts: z\n .array(\n z.object({\n seq: z.number().int().describe(\"audit entry number\"),\n ts: z.string().describe(\"ISO time of the call\"),\n code: z.string().describe(\"CAP_EXCEEDED, LOOP_DETECTED, KILLED, APPROVAL_REQUIRED, …\"),\n tool: z.string().describe(\"the tool that was stopped\"),\n cause: z.string().describe(\"why\"),\n }),\n )\n .describe(\"every call agentguard stopped, in order\"),\n top_tools: z\n .array(z.object({ tool: z.string(), calls: z.number().int(), class: z.string() }))\n .describe(\"the most-called tools with their class (read, write, spend)\"),\n markdown: z.string().describe(\"the same report `agentguard report` prints, as Markdown\"),\n});\n\nconst VerifyOutput = z.object({\n configured: z\n .boolean()\n .describe(\"false when no policy file was found (agentguard guards nothing)\"),\n path: z.string().describe(\"absolute path of the audit log checked\"),\n exists: z.boolean().describe(\"false when no call has been recorded yet; an absent log verifies\"),\n ok: z.boolean().describe(\"true when every entry's hash and prev_hash recompute\"),\n entries: z.number().int().describe(\"entries checked\"),\n head_hash: z\n .string()\n .nullable()\n .describe(\n \"hash of the last entry; record it with the count to detect entries cut from the end\",\n ),\n broken_at: z.number().int().nullable().describe(\"seq of the first entry that does not verify\"),\n reason: z.string().nullable().describe(\"why verification failed\"),\n});\n\nexport function createOwnTools(runtime: ProxyRuntime) {\n const status = defineTool({\n name: \"agentguard_get_status\",\n title: \"agentguard status\",\n description:\n \"Report what agentguard is guarding right now: the policy file it loaded (or that none was found), dry-run or enforce mode, each upstream MCP server and whether it connected, a run's cap usage and remaining budget, the kill switch, and pending approvals. Call it first to learn whether agentguard is set up; next_step says what to do when it is not. For what a run did, use agentguard_get_report; to check the log was not edited, agentguard_verify_audit_log. Reads local files only and changes nothing.\",\n input: z.strictObject({ run_id: runIdInput }),\n output: StatusOutput,\n annotations: { title: \"agentguard status\", ...READ_ONLY },\n async handler({ run_id }) {\n const { loaded, guard } = runtime;\n const audit = readAudit(loaded.auditPath);\n if (audit.error) throw unreadable(loaded.auditPath, audit.error);\n const runId = run_id ?? latestRunId(audit.entries) ?? null;\n const state = await guard.status(runId ?? \"(none yet)\");\n const pending = await guard.approvals.list(\"pending\");\n return {\n configured: runtime.configured,\n policy_path: loaded.path,\n mode: runtime.policy.mode,\n upstreams: runtime.upstreamStatus(),\n run_id: runId,\n caps: { per_run: numbers(state.caps.per_run), per_day: numbers(state.caps.per_day) },\n used: state.usage,\n remaining: state.remaining,\n kill_switch: {\n on: state.killed.killed,\n ...(state.killed.reason ? { reason: state.killed.reason } : {}),\n ...(state.killed.source ? { source: state.killed.source } : {}),\n },\n pending_approvals: pending.length,\n audit_log: { path: loaded.auditPath, entries: audit.entries.length },\n next_step: nextStep(runtime),\n };\n },\n });\n\n const report = defineTool({\n name: \"agentguard_get_report\",\n title: \"agentguard run report\",\n description:\n \"Summarize one run from agentguard's audit log: how many tool calls, what dry-run mode faked (records it would have created, updated or deleted, messages sent, dollars spent), what really ran upstream, and every call agentguard halted with its code and cause. Defaults to the most recent run. Use it after an agent run, before switching a policy from dry-run to enforce; for live caps and the kill switch use agentguard_get_status. Read-only: reads the audit file and does not record this call.\",\n input: z.strictObject({ run_id: runIdInput }),\n output: ReportOutput,\n annotations: { title: \"agentguard run report\", ...READ_ONLY },\n handler({ run_id }) {\n const { loaded } = runtime;\n const audit = readAudit(loaded.auditPath);\n if (audit.error) throw unreadable(loaded.auditPath, audit.error);\n const runs = listRuns(audit.entries);\n if (run_id && !runs.some((r) => r.runId === run_id)) {\n throw toolError({\n code: \"NOT_FOUND\",\n cause: `no run \"${run_id}\" in the audit log at ${loaded.auditPath}`,\n fix: `call again without run_id for the latest run${\n runs.length\n ? `; runs in the log: ${runs\n .slice(0, 5)\n .map((r) => r.runId)\n .join(\", \")}`\n : \"; the log has no runs yet\"\n }`,\n retryable: false,\n });\n }\n const runId = run_id ?? latestRunId(audit.entries) ?? null;\n const built = buildReport(audit.entries, { runId: runId ?? undefined });\n const markdown = runId\n ? renderReportMarkdown(built)\n : `# agentguard report\\n\\nNo runs recorded in ${loaded.auditPath} yet. ${nextStep(runtime)}`;\n return {\n configured: runtime.configured,\n audit_log_path: loaded.auditPath,\n run_id: runId,\n runs_in_log: runs.length,\n tool_calls: runId ? audit.entries.filter((e) => e.run_id === runId).length : 0,\n would_have: {\n creates: built.wouldHave.creates,\n updates: built.wouldHave.updates,\n deletes: built.wouldHave.deletes,\n sends: built.wouldHave.sends,\n executes: built.wouldHave.executes,\n spends: built.wouldHave.spends,\n spend_usd: built.wouldHave.spendUsd,\n },\n did: {\n writes: built.did.writes,\n deletes: built.did.deletes,\n sends: built.did.sends,\n spend_usd: built.did.spendUsd,\n },\n halts: built.halts,\n top_tools: built.topTools,\n markdown,\n };\n },\n });\n\n const verify = defineTool({\n name: \"agentguard_verify_audit_log\",\n title: \"Verify agentguard audit log\",\n description:\n \"Recompute the hash chain of agentguard's audit log (JSONL, one entry per tool call) and say whether any entry was edited, removed from the middle or reordered, naming the first broken entry. Returns the entry count and head hash; record both elsewhere, because entries cut from the end of the file still verify. Use it before trusting agentguard_get_report. Takes no arguments: it checks the log the loaded policy names. Read-only; a log that does not exist yet verifies as empty.\",\n input: z.strictObject({}),\n output: VerifyOutput,\n annotations: { title: \"Verify agentguard audit log\", ...READ_ONLY },\n async handler() {\n const { loaded } = runtime;\n const audit = readAudit(loaded.auditPath);\n if (audit.error) {\n return {\n configured: runtime.configured,\n path: loaded.auditPath,\n exists: true,\n ok: false,\n entries: 0,\n head_hash: null,\n broken_at: null,\n reason: audit.error,\n };\n }\n const result = await verifyChain(audit.entries);\n return {\n configured: runtime.configured,\n path: loaded.auditPath,\n exists: audit.exists,\n ok: result.ok,\n entries: result.entries,\n // an empty chain's head is the genesis hash, which is not an entry anyone can record\n head_hash: result.entries > 0 ? (result.head ?? null) : null,\n broken_at: result.brokenAt ?? null,\n reason: result.reason ?? null,\n };\n },\n });\n\n return [status, report, verify];\n}\n\nexport type OwnTool = ReturnType<typeof createOwnTools>[number];\n\n/** Own tools are served only when the proxy fronts no upstream at all. */\nexport function ownToolsActive(runtime: ProxyRuntime): boolean {\n return runtime.upstreamStatus().length === 0;\n}\n\n/** The MCP `tools/list` entries for the own tools. */\nexport function ownToolList(tools: readonly OwnTool[]): Tool[] {\n return listToolManifest(tools) as Tool[];\n}\n\nexport async function callOwnTool(\n tools: readonly OwnTool[],\n name: string,\n args: unknown,\n requestId?: string,\n): Promise<CallToolResult | undefined> {\n const tool = tools.find((t) => t.name === name);\n if (!tool) return undefined;\n return tool.invoke(args, createToolContext({ requestId }));\n}\n","/**\n * Streamable HTTP front door plus the local control endpoints: /health, /status, /kill,\n * /resume, /approve/:id, /deny/:id, /approvals. Control endpoints need the per-process token\n * (written to `<state>/http.json` so the CLI can find a running proxy).\n */\nimport { createHttpHandler, localhostHosts, type HttpHandler } from \"@agentwares/mcp-kit\";\nimport { writeFileSync, unlinkSync, existsSync, mkdirSync } from \"node:fs\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { join } from \"node:path\";\nimport { FileKillSwitch } from \"@agentwares/agentguard-core/node\";\nimport type { ProxyRuntime } from \"./runtime.js\";\nimport { createDownstreamServer, PROXY_VERSION } from \"./server.js\";\n\nexport interface HttpProxyOptions {\n runtime: ProxyRuntime;\n port?: number;\n host?: string;\n path?: string;\n token?: string;\n /** write `<stateDir>/http.json` for the CLI (default true) */\n registerFile?: boolean;\n}\n\nexport interface HttpProxy {\n url: string;\n port: number;\n token: string;\n close(): Promise<void>;\n}\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\nfunction json(res: ServerResponse, status: number, body: unknown): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\" });\n res.end(JSON.stringify(body));\n}\n\nfunction html(res: ServerResponse, status: number, body: string): void {\n res.writeHead(status, {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n });\n res.end(\n `<!doctype html><meta name=\"viewport\" content=\"width=device-width\"><body style=\"font:16px system-ui;padding:2rem;max-width:40rem\">${body}</body>`,\n );\n}\n\nasync function readBody(req: IncomingMessage): Promise<Uint8Array<ArrayBuffer> | undefined> {\n if (req.method === \"GET\" || req.method === \"HEAD\") return undefined;\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(chunk as Buffer);\n return new Uint8Array(Buffer.concat(chunks));\n}\n\nfunction isLoopback(host: string): boolean {\n return host === \"127.0.0.1\" || host === \"localhost\" || host === \"::1\" || host === \"[::1]\";\n}\n\nexport async function startHttpProxy(opts: HttpProxyOptions): Promise<HttpProxy> {\n const { runtime } = opts;\n const host = opts.host ?? \"127.0.0.1\";\n const path = opts.path ?? \"/mcp\";\n const token = opts.token ?? crypto.randomUUID().replace(/-/g, \"\");\n const kill = new FileKillSwitch(runtime.loaded.killPath);\n\n const holder: { mcp?: HttpHandler } = {};\n const server = createServer((req, res) => {\n void (async () => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? host}`);\n const authorized = (): boolean => {\n const q = url.searchParams.get(\"token\");\n const h = req.headers.authorization?.replace(/^Bearer\\s+/i, \"\");\n return q === token || h === token;\n };\n if (url.pathname === path && holder.mcp) {\n const headers = new Headers();\n for (const [k, v] of Object.entries(req.headers)) {\n if (Array.isArray(v)) for (const item of v) headers.append(k, item);\n else if (typeof v === \"string\") headers.set(k, v);\n }\n const controller = new AbortController();\n res.on(\"close\", () => {\n if (!res.writableFinished) controller.abort();\n });\n const response = await holder.mcp(\n new Request(url, {\n method: req.method ?? \"GET\",\n headers,\n body: await readBody(req),\n signal: controller.signal,\n }),\n );\n const out: Record<string, string> = {};\n response.headers.forEach((v, k) => {\n out[k] = v;\n });\n res.writeHead(response.status, out);\n if (!response.body) return res.end();\n const reader = response.body.getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(value);\n }\n } catch {\n // client went away\n }\n return res.end();\n }\n if (url.pathname === \"/health\") {\n const killed = await runtime.guard.killState();\n return json(res, 200, {\n ok: true,\n name: \"agentguard\",\n version: PROXY_VERSION,\n mode: runtime.policy.mode,\n killed: killed.killed,\n upstreams: runtime.upstreamStatus(),\n tools: runtime.listTools().length,\n mcp: `${url.origin}${path}`,\n });\n }\n if (url.pathname === \"/status\") {\n if (!authorized()) return json(res, 401, unauthorized());\n const runId = url.searchParams.get(\"run\") ?? runtime.defaultRunId;\n return json(res, 200, { runId, ...(await runtime.guard.status(runId)) });\n }\n if (url.pathname === \"/kill\" && req.method === \"POST\") {\n if (!authorized()) return json(res, 401, unauthorized());\n const body = await readBody(req);\n let reason = \"killed via HTTP\";\n try {\n const parsed = JSON.parse(Buffer.from(body ?? []).toString(\"utf8\") || \"{}\") as {\n reason?: string;\n };\n if (parsed.reason) reason = String(parsed.reason).slice(0, 200);\n } catch {\n // no body\n }\n kill.kill(reason);\n await runtime.guard.halt(reason);\n return json(res, 200, { killed: true, reason });\n }\n if (url.pathname === \"/resume\" && req.method === \"POST\") {\n if (!authorized()) return json(res, 401, unauthorized());\n kill.resume();\n await runtime.guard.resume();\n return json(res, 200, { killed: false });\n }\n const decision = /^\\/(approve|deny)\\/([A-Za-z0-9_-]+)$/.exec(url.pathname);\n if (decision) {\n if (!authorized()) return json(res, 401, unauthorized());\n const [, action, id] = decision;\n const record = await runtime.guard.decide(\n id!,\n action === \"approve\" ? \"approved\" : \"denied\",\n \"http\",\n );\n if (!record)\n return json(res, 404, {\n code: \"NOT_FOUND\",\n cause: `no approval ${id}`,\n fix: \"list pending approvals with `agentguard approvals`\",\n retryable: false,\n });\n if (req.headers.accept?.includes(\"text/html\")) {\n return html(\n res,\n 200,\n `<h1>${record.status === \"approved\" ? \"Approved\" : record.status === \"denied\" ? \"Denied\" : record.status}</h1><p><code>${record.tool}</code> — approval <code>${record.id}</code>.</p><p>The agent may now retry the call once.</p>`,\n );\n }\n return json(res, 200, record);\n }\n if (url.pathname === \"/approvals\") {\n if (!authorized()) return json(res, 401, unauthorized());\n return json(res, 200, {\n approvals: await runtime.guard.approvals.list(\n url.searchParams.get(\"all\") ? undefined : \"pending\",\n ),\n });\n }\n return json(res, 404, {\n code: \"NOT_FOUND\",\n cause: `no route for ${url.pathname}`,\n fix: `POST JSON-RPC to ${path}; GET /health`,\n retryable: false,\n });\n })().catch((err: unknown) => {\n if (!res.headersSent)\n json(res, 500, {\n code: \"INTERNAL\",\n cause: err instanceof Error ? err.message : String(err),\n fix: \"retry; if it persists, report the request\",\n retryable: false,\n });\n else res.end();\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(opts.port ?? 8788, host, () => resolve());\n });\n const address = server.address();\n const port = typeof address === \"object\" && address ? address.port : (opts.port ?? 8788);\n holder.mcp = createHttpHandler(() => createDownstreamServer(runtime), {\n sessions: true,\n jsonResponse: false,\n cors: true,\n allowedHosts: isLoopback(host) ? localhostHosts(port) : undefined,\n enableDnsRebindingProtection: isLoopback(host),\n });\n\n const baseUrl = `http://${host}:${port}`;\n const url = `${baseUrl}${path}`;\n const regFile = registrationPath(runtime.loaded.stateDir);\n if (opts.registerFile !== false) {\n mkdirSync(runtime.loaded.stateDir, { recursive: true });\n const reg: HttpRegistration = {\n url,\n baseUrl,\n token,\n pid: process.pid,\n startedAt: new Date().toISOString(),\n };\n writeFileSync(regFile, JSON.stringify(reg, null, 2));\n }\n return {\n url,\n port,\n token,\n close: () =>\n new Promise<void>((resolve, reject) => {\n if (opts.registerFile !== false && existsSync(regFile)) {\n try {\n unlinkSync(regFile);\n } catch {\n // fine\n }\n }\n server.closeAllConnections();\n server.close((err) => (err ? reject(err) : resolve()));\n }),\n };\n}\n\nfunction unauthorized(): Record<string, unknown> {\n return {\n code: \"UNAUTHORIZED\",\n cause: \"missing or wrong control token\",\n fix: \"pass ?token=<token> or Authorization: Bearer <token> from <state>/http.json\",\n retryable: false,\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 type { HttpRegistration } from \"./proxy/http.js\";\nimport { registrationPath } from \"./proxy/http.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}\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 };\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","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","/** 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]);\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 * Find the agent's existing MCP config (Claude Code, Claude Desktop, Cursor, VS Code, Windsurf,\n * Gemini CLI, generic `mcp.json`), read its servers, and rewrite it so every server goes through\n * the proxy.\n */\nimport { copyFileSync, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir, platform } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { Upstream } from \"@agentwares/agentguard-core\";\n\nexport type ClientKind =\n | \"claude-code-project\"\n | \"claude-code-user\"\n | \"claude-desktop\"\n | \"cursor-project\"\n | \"cursor-user\"\n | \"vscode\"\n | \"windsurf\"\n | \"gemini-project\"\n | \"gemini-user\"\n | \"generic\";\n\nexport interface ClientConfigFile {\n kind: ClientKind;\n label: string;\n path: string;\n /** `mcpServers` (most clients) or `servers` (VS Code) */\n serversKey: \"mcpServers\" | \"servers\";\n}\n\nexport interface ServerEntry {\n type?: string;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n url?: string;\n /** Gemini CLI's name for a Streamable HTTP endpoint (its `url` means SSE) */\n httpUrl?: string;\n headers?: Record<string, string>;\n [k: string]: unknown;\n}\n\nexport function candidateConfigs(\n cwd: string = process.cwd(),\n home: string = homedir(),\n env: NodeJS.ProcessEnv = process.env,\n): ClientConfigFile[] {\n const desktop =\n platform() === \"darwin\"\n ? join(home, \"Library\", \"Application Support\", \"Claude\", \"claude_desktop_config.json\")\n : platform() === \"win32\"\n ? join(\n env.APPDATA ?? join(home, \"AppData\", \"Roaming\"),\n \"Claude\",\n \"claude_desktop_config.json\",\n )\n : join(\n env.XDG_CONFIG_HOME ?? join(home, \".config\"),\n \"Claude\",\n \"claude_desktop_config.json\",\n );\n return [\n {\n kind: \"claude-code-project\",\n label: \"Claude Code (project .mcp.json)\",\n path: join(cwd, \".mcp.json\"),\n serversKey: \"mcpServers\",\n },\n {\n kind: \"cursor-project\",\n label: \"Cursor (project)\",\n path: join(cwd, \".cursor\", \"mcp.json\"),\n serversKey: \"mcpServers\",\n },\n {\n kind: \"vscode\",\n label: \"VS Code (project)\",\n path: join(cwd, \".vscode\", \"mcp.json\"),\n serversKey: \"servers\",\n },\n { kind: \"generic\", label: \"mcp.json\", path: join(cwd, \"mcp.json\"), serversKey: \"mcpServers\" },\n {\n kind: \"gemini-project\",\n label: \"Gemini CLI (project .gemini/settings.json)\",\n path: join(cwd, \".gemini\", \"settings.json\"),\n serversKey: \"mcpServers\",\n },\n { kind: \"claude-desktop\", label: \"Claude Desktop\", path: desktop, serversKey: \"mcpServers\" },\n {\n kind: \"cursor-user\",\n label: \"Cursor (user)\",\n path: join(home, \".cursor\", \"mcp.json\"),\n serversKey: \"mcpServers\",\n },\n {\n kind: \"windsurf\",\n label: \"Windsurf\",\n path: join(home, \".codeium\", \"windsurf\", \"mcp_config.json\"),\n serversKey: \"mcpServers\",\n },\n {\n kind: \"claude-code-user\",\n label: \"Claude Code (user ~/.claude.json)\",\n path: join(home, \".claude.json\"),\n serversKey: \"mcpServers\",\n },\n {\n kind: \"gemini-user\",\n label: \"Gemini CLI (user ~/.gemini/settings.json)\",\n path: join(home, \".gemini\", \"settings.json\"),\n serversKey: \"mcpServers\",\n },\n ];\n}\n\n/** Gemini CLI reads `httpUrl` for Streamable HTTP and `url` for SSE, unlike every other client. */\nexport function isGeminiConfig(file: ClientConfigFile): boolean {\n return (\n file.kind === \"gemini-project\" ||\n file.kind === \"gemini-user\" ||\n /[/\\\\]\\.gemini[/\\\\]settings\\.json$/.test(file.path)\n );\n}\n\n/** Configs that exist on disk, project-level first. */\nexport function detectClientConfigs(\n cwd?: string,\n home?: string,\n env?: NodeJS.ProcessEnv,\n): ClientConfigFile[] {\n return candidateConfigs(cwd, home, env).filter((c) => existsSync(c.path));\n}\n\n/** Describe an explicit path the user passed with `--client`. */\nexport function describeConfigPath(path: string): ClientConfigFile {\n const abs = resolve(path);\n const known = candidateConfigs().find((c) => c.path === abs);\n if (known) return known;\n let serversKey: \"mcpServers\" | \"servers\" = \"mcpServers\";\n try {\n const parsed = JSON.parse(readFileSync(abs, \"utf8\")) as Record<string, unknown>;\n if (parsed.servers && !parsed.mcpServers) serversKey = \"servers\";\n } catch {\n // unreadable: caller reports\n }\n return {\n kind: abs.includes(\".vscode\") ? \"vscode\" : \"generic\",\n label: abs,\n path: abs,\n serversKey,\n };\n}\n\nexport function readServers(file: ClientConfigFile): Record<string, ServerEntry> {\n const raw = JSON.parse(readFileSync(file.path, \"utf8\")) as Record<string, unknown>;\n const servers = raw[file.serversKey];\n if (!servers || typeof servers !== \"object\") return {};\n return servers as Record<string, ServerEntry>;\n}\n\nexport const PROXY_SERVER_NAME = \"agentguard\";\n\n/** What `npx` is told to fetch. Must be the published package name. */\nexport const PROXY_PACKAGE = \"@agentwares/agentguard\";\n\nexport function isProxyEntry(entry: ServerEntry): boolean {\n return (\n (entry.args ?? []).some((a) => a === \"agentguard\" || /(^|\\/)agentguard(\\.js)?$/.test(a)) &&\n (entry.args ?? []).includes(\"proxy\")\n );\n}\n\n/** Client servers → policy upstreams. Names are sanitized; secrets stay where they were (in the config). */\nexport function serversToUpstreams(servers: Record<string, ServerEntry>): {\n upstreams: Upstream[];\n skipped: { name: string; reason: string }[];\n} {\n const upstreams: Upstream[] = [];\n const skipped: { name: string; reason: string }[] = [];\n for (const [rawName, entry] of Object.entries(servers)) {\n if (isProxyEntry(entry)) {\n skipped.push({ name: rawName, reason: \"already the agentguard proxy\" });\n continue;\n }\n const name =\n rawName.replace(/[^a-zA-Z0-9_-]/g, \"-\").replace(/^[^a-zA-Z0-9]+/, \"\") || \"upstream\";\n // `httpUrl` is Gemini CLI's Streamable HTTP field; agentguard reaches upstreams that way.\n const url = typeof entry.httpUrl === \"string\" ? entry.httpUrl : entry.url;\n if (url) {\n upstreams.push({\n name,\n url,\n headers: entry.headers ?? {},\n args: [],\n env: {},\n prefix: false,\n timeout_ms: 60_000,\n });\n } else if (entry.command) {\n upstreams.push({\n name,\n command: entry.command,\n args: entry.args ?? [],\n env: entry.env ?? {},\n cwd: entry.cwd,\n headers: {},\n prefix: false,\n timeout_ms: 60_000,\n });\n } else {\n skipped.push({ name: rawName, reason: \"no `command` or `url`\" });\n }\n }\n return { upstreams, skipped };\n}\n\nexport function backupPath(file: ClientConfigFile): string {\n return `${file.path}.agentguard-backup`;\n}\n\n/** The entry that replaces every server: one proxy, all upstreams behind it. */\nexport function proxyEntry(\n file: ClientConfigFile,\n policyPath: string,\n opts: { agent?: string } = {},\n): ServerEntry {\n // The published name, scope and all. `npx -y agentguard` 404s — that package does not\n // exist — so every config this wrote failed to start the proxy, and the line printed next\n // to it already said `npx @agentwares/agentguard proxy`. Worse than broken: the unscoped\n // name is unclaimed, so anyone who took it would have their code run by our onboarding.\n const args = [\"-y\", PROXY_PACKAGE, \"proxy\", \"--config\", policyPath];\n if (opts.agent) args.push(\"--agent\", opts.agent);\n const entry: ServerEntry = { command: \"npx\", args };\n if (file.serversKey === \"servers\") entry.type = \"stdio\";\n return entry;\n}\n\n/** Back up the file (once) and replace its servers with the single proxy entry. */\nexport function rewriteClientConfig(\n file: ClientConfigFile,\n policyPath: string,\n opts: { agent?: string } = {},\n): { backup: string; replaced: string[] } {\n const raw = JSON.parse(readFileSync(file.path, \"utf8\")) as Record<string, unknown>;\n const servers = (raw[file.serversKey] as Record<string, ServerEntry> | undefined) ?? {};\n const replaced = Object.keys(servers).filter((n) => !isProxyEntry(servers[n]!));\n const backup = backupPath(file);\n if (!existsSync(backup)) copyFileSync(file.path, backup);\n raw[file.serversKey] = { [PROXY_SERVER_NAME]: proxyEntry(file, policyPath, opts) };\n writeFileSync(file.path, JSON.stringify(raw, null, 2) + \"\\n\");\n return { backup, replaced };\n}\n\n/** `agentguard init --undo`: restore the backup. */\nexport function restoreClientConfig(file: ClientConfigFile): boolean {\n const backup = backupPath(file);\n if (!existsSync(backup)) return false;\n copyFileSync(backup, file.path);\n return true;\n}\n\n/**\n * Add (or replace) one named server in a client config, leaving every other server alone.\n *\n * `rewriteClientConfig` is the `init` path: it replaces the whole server list with the local\n * proxy. `connect` is the opposite shape — the hosted proxy is one more remote server sitting\n * alongside whatever the client already has — so it merges instead of replacing. Both back the\n * file up once before touching it, so `init --undo` still restores either.\n */\nexport function mergeServerIntoConfig(\n file: ClientConfigFile,\n name: string,\n entry: ServerEntry,\n): { backup: string; replaced: boolean } {\n const raw = JSON.parse(readFileSync(file.path, \"utf8\")) as Record<string, unknown>;\n const servers = (raw[file.serversKey] as Record<string, ServerEntry> | undefined) ?? {};\n const replaced = name in servers;\n const backup = backupPath(file);\n if (!existsSync(backup)) copyFileSync(file.path, backup);\n raw[file.serversKey] = { ...servers, [name]: entry };\n writeFileSync(file.path, JSON.stringify(raw, null, 2) + \"\\n\");\n return { backup, replaced };\n}\n","/**\n * `agentguard init` — the 60-second install. Reads the agent's existing MCP config, probes the\n * servers, writes `agentguard.yaml` (dry-run by default) and rewrites the config so everything\n * goes through the proxy. `--undo` restores the backup.\n */\nimport { existsSync, writeFileSync } from \"node:fs\";\nimport { relative, resolve } from \"node:path\";\nimport YAML from \"yaml\";\nimport { type Upstream } from \"@agentwares/agentguard-core\";\nimport { flagBool, flagString, type ParsedArgs } from \"../args.js\";\nimport {\n describeConfigPath,\n detectClientConfigs,\n readServers,\n restoreClientConfig,\n rewriteClientConfig,\n serversToUpstreams,\n type ClientConfigFile,\n} from \"../configs.js\";\nimport { homeFrom, policyPathFrom, type Io } from \"../context.js\";\nimport { probeUpstreams, type ProbedTool } from \"./tools.js\";\n\nexport interface StarterPolicyOptions {\n upstreams: Upstream[];\n tools?: ProbedTool[];\n mode?: \"dry-run\" | \"enforce\";\n generatedAt?: Date;\n probeErrors?: string[];\n}\n\nfunction dump(value: unknown, indent = 0): string {\n const text = YAML.stringify(value, { indent: 2, lineWidth: 100 }).trimEnd();\n const pad = \" \".repeat(indent);\n return text\n .split(\"\\n\")\n .map((l) => pad + l)\n .join(\"\\n\");\n}\n\nfunction flow(list: string[]): string {\n return list.length === 0 ? \"[]\" : `[${list.map((s) => JSON.stringify(s)).join(\", \")}]`;\n}\n\n/** The commented starter policy — the file people read, so every knob explains itself. */\nexport function renderStarterPolicy(opts: StarterPolicyOptions): string {\n const tools = opts.tools ?? [];\n const unknown = tools.filter((t) => t.classification.class === \"unknown\").map((t) => t.name);\n const destructive = tools\n .filter((t) => t.classification.destructive || t.classification.verb === \"delete\")\n .map((t) => t.name);\n const spend = tools.filter((t) => t.classification.class === \"spend\").map((t) => t.name);\n const date = (opts.generatedAt ?? new Date()).toISOString().slice(0, 10);\n const counts = tools.reduce<Record<string, number>>(\n (acc, t) => ({ ...acc, [t.classification.class]: (acc[t.classification.class] ?? 0) + 1 }),\n {},\n );\n const detected =\n tools.length === 0\n ? [\"# (no upstreams probed — run `agentguard tools` after fixing the upstreams above)\"]\n : tools.map(\n (t) =>\n `# ${t.name.padEnd(36)} ${t.classification.class.padEnd(8)} ${t.classification.verb.padEnd(8)} ${t.classification.source}: ${t.classification.reason}`,\n );\n const probeNotes = (opts.probeErrors ?? []).map((e) => `# ! ${e}`);\n const upstreamsYaml = opts.upstreams.length\n ? dump({ upstreams: opts.upstreams.map(cleanUpstream) })\n : 'upstreams: []\\n # - name: crm\\n # url: https://mcp.example.com/mcp\\n # auth: ${CRM_TOKEN}\\n # - name: files\\n # command: npx\\n # args: [-y, \"@modelcontextprotocol/server-filesystem\", \".\"]';\n\n return `# agentguard.yaml — generated by \\`agentguard init\\` on ${date}\n# Every knob is explained inline. Docs: https://github.com/agentwares/agentguard/tree/main/apps/agentguard-cli#policy\nversion: 1\n\n# dry-run: reads pass through; writes and spends are FAKED (plausible success, nothing executes)\n# and recorded. Run your agent once, then \\`agentguard report\\` and \\`agentguard diff\\`.\n# Flip to \\`enforce\\` when the diff looks right. Caps and the loop breaker apply in both modes.\nmode: ${opts.mode ?? \"dry-run\"}\n\n# The servers your agent used to talk to directly. agentguard connects to them and holds their\n# credentials; your agent only talks to agentguard. Use \\${ENV_VAR} for secrets.\n${upstreamsYaml}\n\n# Detected tools (${tools.length}${\n tools.length\n ? `: ${Object.entries(counts)\n .map(([k, v]) => `${v} ${k}`)\n .join(\", \")}`\n : \"\"\n }):\n${[...detected, ...probeNotes].join(\"\\n\")}\n# readOnlyHint annotations and verb heuristics classify most tools. List anything that is wrong here;\n# these patterns win over annotations. \\`*\\` matches anything.\nclassify:\n read: []\n write: ${flow(unknown)}${unknown.length ? \" # could not be classified — treated as writes; move to read: if they only read\" : \"\"}\n spend: ${flow(spend)}\n unknown: write # a tool nobody can classify counts as a write (alternatives: read | block)\n\n# Blast-radius caps. The call that would exceed a cap gets CAP_EXCEEDED with the remaining budget.\n# \\`writes\\` counts every write or spend; \\`deletes\\`/\\`emails\\` count the subsets matched by \\`counters\\`.\ncaps:\n per_run:\n tool_calls: 400\n writes: 50\n deletes: 10\n emails: 5\n spend_usd: 25\n per_day:\n spend_usd: 200\n\n# Dollar amounts. Declare how to read the amount from a spend tool's arguments; results reporting\n# cost_usd / amount_usd are picked up automatically. Unknown spend tools cost \\`default_usd\\`.\nspend:\n tools: {}\n # stripe_create_charge: { amount_arg: amount, divisor: 100, currency_arg: currency }\n # openai_*: { fixed_usd: 0.01 }\n default_usd: 0\n\n# Semantic loop breaker: the same (tool, normalized arguments) ${3} times in the last 30 calls, or a\n# repeating A→B→A→B cycle, returns LOOP_DETECTED. Timestamps, ids and whitespace are ignored.\nloop:\n window: 30\n max_repeats: 3\n max_cycle_len: 4\n max_read_repeats: 10\n\n# Always fake these, even in enforce mode. Remove entries as you gain trust.\ndry_run:\n tools: []\n synthesize: true\n\n# Destructive actions that need a human. The agent gets APPROVAL_REQUIRED with an id; you run\n# \\`agentguard approve <id>\\` (or click the link in Slack); the agent retries the identical call once.\napproval:\n tools: ${flow(destructive)}\n wait_s: 0 # > 0 holds the call open this long waiting for the decision\n ttl_s: 3600\n # notify:\n # slack: \\${SLACK_WEBHOOK_URL}\n\n# Kill switch: \\`agentguard kill\\` creates this file (or POST /kill on the HTTP proxy); every call\n# returns KILLED until \\`agentguard resume\\`. AGENTGUARD_KILL=1 in the environment does the same.\nkill:\n file: .agentguard/KILL\n\n# Scoped agent keys for the HTTP proxy: \\`agentguard key create deployer --allow 'crm_get_*'\\`.\n# Only the key's hash is stored here; the agent sends the key as a Bearer token.\nagents: []\n\n# Alerts on halts (Slack incoming webhook or any HTTPS endpoint; signed with X-Agentwares-Signature).\n# alerts:\n# slack: \\${SLACK_WEBHOOK_URL}\n# on: [LOOP_DETECTED, CAP_EXCEEDED, KILLED, APPROVAL_REQUIRED]\n\n# Hash-chained JSONL of every call; \\`agentguard verify\\` proves it was not edited.\naudit:\n path: .agentguard/audit.jsonl\n redact: true\n include_results: false\n`;\n}\n\nfunction cleanUpstream(u: Upstream): Record<string, unknown> {\n const out: Record<string, unknown> = { name: u.name };\n if (u.url) {\n out.url = u.url;\n if (Object.keys(u.headers).length) out.headers = u.headers;\n } else {\n out.command = u.command;\n if (u.args.length) out.args = u.args;\n if (Object.keys(u.env).length) out.env = u.env;\n if (u.cwd) out.cwd = u.cwd;\n }\n return out;\n}\n\nexport async function initCommand(args: ParsedArgs, io: Io): Promise<number> {\n const policyPath = policyPathFrom(args, io);\n const explicit = flagString(args, \"client\");\n const configs: ClientConfigFile[] = explicit\n ? [describeConfigPath(resolve(io.cwd, explicit))]\n : detectClientConfigs(io.cwd, homeFrom(io), io.env);\n const rel = (p: string): string => {\n const r = relative(io.cwd, p);\n return r.startsWith(\"..\") ? p : r || \".\";\n };\n\n if (flagBool(args, \"undo\")) {\n let restored = 0;\n for (const c of configs) {\n if (restoreClientConfig(c)) {\n io.out(`restored ${rel(c.path)} from backup`);\n restored += 1;\n }\n }\n if (restored === 0)\n io.err(\"nothing to undo (no *.agentguard-backup files next to your MCP configs)\");\n return 0;\n }\n\n // Only project-level configs are rewritten by default. User-level files (Claude Desktop,\n // ~/.cursor, Windsurf, ~/.claude.json) affect every project, so they need an explicit --client.\n const projectLevel = configs.filter((c) => c.path.startsWith(io.cwd + \"/\"));\n const userLevel = configs.filter((c) => !projectLevel.includes(c));\n let chosen: ClientConfigFile[];\n if (explicit) chosen = configs;\n else if (flagBool(args, \"all\")) chosen = configs;\n else chosen = projectLevel.slice(0, 1);\n if (!explicit && !flagBool(args, \"all\")) {\n for (const c of userLevel)\n io.out(\n `found ${c.path} (${c.label}, user-level) — not touched; pass --client ${JSON.stringify(c.path)} to route it through agentguard`,\n );\n }\n if (!chosen.every((c) => existsSync(c.path))) {\n io.err(`no MCP config at ${chosen.map((c) => c.path).join(\", \")}`);\n return 1;\n }\n\n const servers: Record<string, ReturnType<typeof readServers>[string]> = {};\n for (const c of chosen) {\n const found = readServers(c);\n io.out(\n `found ${rel(c.path)} (${c.label}) → ${Object.keys(found).length} server${Object.keys(found).length === 1 ? \"\" : \"s\"}: ${Object.keys(found).join(\", \") || \"none\"}`,\n );\n for (const [name, entry] of Object.entries(found))\n if (!(name in servers)) servers[name] = entry;\n }\n if (chosen.length === 0)\n io.out(\n \"found no MCP config (Claude Code .mcp.json, Cursor, VS Code, Claude Desktop, Windsurf, Gemini CLI) — writing a policy with no upstreams\",\n );\n const { upstreams, skipped } = serversToUpstreams(servers);\n for (const s of skipped) io.err(`skipped ${s.name}: ${s.reason}`);\n if (\n skipped.some((s) => s.reason.includes(\"already\")) &&\n upstreams.length === 0 &&\n existsSync(policyPath)\n ) {\n io.out(\n `already initialized: ${rel(policyPath)} exists and ${chosen.map((c) => rel(c.path)).join(\", \")} already points at agentguard`,\n );\n return 0;\n }\n\n let probed: ProbedTool[] = [];\n const probeErrors: string[] = [];\n if (flagBool(args, \"probe\") !== false && upstreams.length > 0) {\n io.out(`probing ${upstreams.length} upstream${upstreams.length === 1 ? \"\" : \"s\"}…`);\n const result = await probeUpstreams(upstreams, {\n log: () => undefined,\n env: io.env,\n timeoutMs: 20_000,\n });\n probed = result.tools;\n for (const u of result.upstreams) {\n if (u.connected) io.out(` ${u.name}: ${u.tools} tools`);\n else {\n io.err(\n ` ${u.name}: could not connect (${u.error}) — the proxy will keep retrying at start; fix the entry in agentguard.yaml`,\n );\n probeErrors.push(`${u.name}: ${u.error}`);\n }\n }\n }\n\n const mode = (flagString(args, \"mode\") as \"dry-run\" | \"enforce\" | undefined) ?? \"dry-run\";\n if (existsSync(policyPath) && !flagBool(args, \"force\")) {\n io.out(`kept ${rel(policyPath)} (exists; pass --force to regenerate)`);\n } else {\n writeFileSync(policyPath, renderStarterPolicy({ upstreams, tools: probed, mode, probeErrors }));\n const counts = probed.reduce<Record<string, number>>(\n (acc, t) => ({ ...acc, [t.classification.class]: (acc[t.classification.class] ?? 0) + 1 }),\n {},\n );\n io.out(\n `wrote ${rel(policyPath)} (mode: ${mode}, ${upstreams.length} upstream${upstreams.length === 1 ? \"\" : \"s\"}${\n probed.length\n ? `, ${probed.length} tools: ${Object.entries(counts)\n .map(([k, v]) => `${v} ${k}`)\n .join(\", \")}`\n : \"\"\n })`,\n );\n }\n\n if (flagBool(args, \"rewrite\") !== false) {\n for (const c of chosen) {\n // `--config` names the policy file, and `--client` names the client's. Point both at the\n // same file — easy, because an MCP client's file is also called a config — and the\n // rewrite replaces the policy with the proxy entry and then points the proxy at that.\n // The upstreams survive only in the backup, and the proxy starts with nothing to guard.\n if (resolve(c.path) === resolve(policyPath)) {\n throw new Error(\n `refusing: ${rel(c.path)} is both the policy file (--config) and a client config. ` +\n `Rewriting it would replace the policy with the proxy entry and leave the proxy ` +\n `pointing at itself. Use --config for the policy path and --client for the ` +\n `client's config, or let --config default to agentguard.yaml.`,\n );\n }\n const { backup, replaced } = rewriteClientConfig(c, policyPath, {\n agent: flagString(args, \"agent\"),\n });\n io.out(\n `rewrote ${rel(c.path)} → ${replaced.length ? `${replaced.join(\", \")} now go through` : \"points at\"} \\`npx @agentwares/agentguard proxy\\` (backup: ${rel(backup)})`,\n );\n }\n }\n\n io.out(\"\");\n io.out(\"Next:\");\n io.out(\n ` 1. restart your MCP client so it re-reads ${chosen.map((c) => rel(c.path)).join(\", \") || \"its config\"}`,\n );\n io.out(\n ` 2. run your agent once — ${mode === \"dry-run\" ? \"writes are faked; nothing executes upstream\" : \"enforce mode: caps, loop breaker and approvals are live\"}`,\n );\n io.out(\" 3. agentguard report # what this run would have destroyed / spent\");\n io.out(\" agentguard diff # the record-by-record mutation diff\");\n if (mode === \"dry-run\")\n io.out(` 4. set \\`mode: enforce\\` in ${rel(policyPath)} when it looks right`);\n io.out(\" undo any time: agentguard init --undo\");\n return 0;\n}\n","/**\n * `agentguard tools` — connect to every upstream and print the tools the agent will see,\n * with their class and why. Also the probe `init` uses to seed the policy.\n */\nimport {\n Guard,\n classifyTool,\n parsePolicy,\n type Classification,\n type Policy,\n type Upstream,\n} from \"@agentwares/agentguard-core\";\nimport type { LoadedPolicy } from \"@agentwares/agentguard-core/node\";\nimport type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport { ProxyRuntime } from \"../proxy/runtime.js\";\nimport { loadPolicyFor, type Io } from \"../context.js\";\nimport type { ParsedArgs } from \"../args.js\";\nimport { flagBool } from \"../args.js\";\n\nexport interface ProbedTool {\n upstream: string;\n name: string;\n tool: Tool;\n classification: Classification;\n}\n\nexport interface ProbeResult {\n tools: ProbedTool[];\n upstreams: { name: string; connected: boolean; tools: number; error?: string }[];\n}\n\n/** Connect to the upstreams (with a policy for classification), list tools, disconnect. */\nexport async function probeUpstreams(\n upstreams: Upstream[],\n opts: {\n policy?: Policy;\n timeoutMs?: number;\n log?: (l: string) => void;\n env?: NodeJS.ProcessEnv;\n } = {},\n): Promise<ProbeResult> {\n const policy = opts.policy ?? parsePolicy({ upstreams });\n const loaded: LoadedPolicy = {\n policy: { ...policy, upstreams },\n path: \"\",\n baseDir: process.cwd(),\n stateDir: \"\",\n auditPath: \"\",\n killPath: \"\",\n };\n const guard = new Guard({ policy: loaded.policy, env: opts.env ?? {} });\n const runtime = new ProxyRuntime({\n loaded,\n guard,\n defaultRunId: \"probe\",\n log: opts.log ?? (() => undefined),\n connectTimeoutMs: opts.timeoutMs ?? 15_000,\n });\n try {\n await runtime.start();\n return {\n tools: runtime.listTools().map((t) => ({\n upstream: t.upstream,\n name: t.name,\n tool: t.tool,\n classification: classifyTool(\n { name: t.name, annotations: t.tool.annotations },\n loaded.policy,\n ),\n })),\n upstreams: runtime.upstreamStatus(),\n };\n } finally {\n await runtime.close();\n }\n}\n\nexport function formatToolTable(tools: ProbedTool[]): string[] {\n const width = Math.min(48, Math.max(12, ...tools.map((t) => t.name.length)));\n const lines = [\n `${\"tool\".padEnd(width)} ${\"class\".padEnd(8)}${\"verb\".padEnd(9)}${\"upstream\".padEnd(14)}why`,\n ];\n for (const t of tools) {\n const c = t.classification;\n lines.push(\n `${t.name.padEnd(width)} ${c.class.padEnd(8)}${c.verb.padEnd(9)}${t.upstream.padEnd(14)}${c.source}: ${c.reason}`,\n );\n }\n return lines;\n}\n\nexport async function toolsCommand(args: ParsedArgs, io: Io): Promise<number> {\n const loaded = loadPolicyFor(args, io);\n const result = await probeUpstreams(loaded.policy.upstreams, {\n policy: loaded.policy,\n log: io.err,\n env: io.env,\n });\n if (flagBool(args, \"json\")) {\n io.out(\n JSON.stringify(\n {\n upstreams: result.upstreams,\n tools: result.tools.map((t) => ({\n name: t.name,\n upstream: t.upstream,\n ...t.classification,\n })),\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n for (const u of result.upstreams)\n io.err(\n `${u.connected ? \"ok \" : \"down\"} ${u.name}: ${u.connected ? `${u.tools} tools` : u.error}`,\n );\n if (result.upstreams.length === 0)\n io.err(\n \"no upstreams in the policy: an MCP client sees agentguard's own read-only tools instead (agentguard_get_status, agentguard_get_report, agentguard_verify_audit_log)\",\n );\n for (const line of formatToolTable(result.tools)) io.out(line);\n const counts = result.tools.reduce<Record<string, number>>(\n (acc, t) => ({ ...acc, [t.classification.class]: (acc[t.classification.class] ?? 0) + 1 }),\n {},\n );\n io.err(\n `\\n${result.tools.length} tools: ${Object.entries(counts)\n .map(([k, v]) => `${v} ${k}`)\n .join(\", \")} · mode ${loaded.policy.mode}`,\n );\n return result.upstreams.every((u) => u.connected) ? 0 : 2;\n}\n","/**\n * `agentguard permission-diff` — which changes between two git refs widen what an agent may do\n * (agentguard.yaml, .claude/settings.json, mcp.json). The GitHub Action posts the markdown.\n */\nimport { execFileSync } from \"node:child_process\";\nimport {\n diffPermissionFile,\n renderPermissionDiffMarkdown,\n type Finding,\n} from \"@agentwares/agentguard-core\";\nimport { flagBool, flagList, flagString, type ParsedArgs } from \"../args.js\";\nimport type { Io } from \"../context.js\";\n\nexport const DEFAULT_PERMISSION_PATHS = [\n \"agentguard.yaml\",\n \"agentguard.yml\",\n \".claude/settings.json\",\n \".claude/settings.local.json\",\n \".mcp.json\",\n \"mcp.json\",\n \".cursor/mcp.json\",\n \".vscode/mcp.json\",\n];\n\nconst PERMISSION_FILE =\n /(^|\\/)(agentguard[^/]*\\.ya?ml|\\.claude\\/settings(\\.local)?\\.json|[^/]*mcp[^/]*\\.json|claude_desktop_config\\.json)$/;\n\nfunction git(cwd: string, argv: string[]): string | undefined {\n try {\n return execFileSync(\"git\", argv, {\n cwd,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n } catch {\n return undefined;\n }\n}\n\nexport function showAt(cwd: string, ref: string, path: string): string | undefined {\n return git(cwd, [\"show\", `${ref}:${path}`]);\n}\n\nexport function changedPermissionFiles(cwd: string, base: string, head: string): string[] {\n const out = git(cwd, [\"diff\", \"--name-only\", base, head]) ?? \"\";\n return out\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l && PERMISSION_FILE.test(l));\n}\n\nexport function resolveBase(cwd: string, explicit: string | undefined): string {\n if (explicit) return explicit;\n for (const candidate of [\"origin/main\", \"main\", \"origin/master\", \"master\"]) {\n if (git(cwd, [\"rev-parse\", \"--verify\", \"--quiet\", candidate]) !== undefined) return candidate;\n }\n return \"HEAD~1\";\n}\n\nexport interface PermissionDiffResult {\n base: string;\n head: string;\n files: string[];\n findings: Finding[];\n markdown: string;\n}\n\nexport function runPermissionDiff(\n cwd: string,\n opts: { base?: string; head?: string; paths?: string[]; title?: string },\n): PermissionDiffResult {\n const base = resolveBase(cwd, opts.base);\n const head = opts.head ?? \"HEAD\";\n const files = [\n ...new Set([\n ...(opts.paths ?? DEFAULT_PERMISSION_PATHS),\n ...changedPermissionFiles(cwd, base, head),\n ]),\n ];\n const findings: Finding[] = [];\n const touched: string[] = [];\n for (const file of files) {\n const before = showAt(cwd, base, file);\n const after = showAt(cwd, head, file);\n if (before === undefined && after === undefined) continue;\n if (before === after) continue;\n touched.push(file);\n findings.push(...diffPermissionFile(file, before, after));\n }\n return {\n base,\n head,\n files: touched,\n findings,\n markdown: renderPermissionDiffMarkdown(findings, { title: opts.title }),\n };\n}\n\nexport async function permissionDiffCommand(args: ParsedArgs, io: Io): Promise<number> {\n const paths = flagList(args, \"paths\");\n const result = runPermissionDiff(io.cwd, {\n base: flagString(args, \"base\"),\n head: flagString(args, \"head\"),\n paths: paths.length ? paths : undefined,\n });\n const format = flagString(args, \"format\") ?? (flagBool(args, \"json\") ? \"json\" : \"markdown\");\n if (format === \"json\") io.out(JSON.stringify(result, null, 2));\n else io.out(result.markdown);\n const widen = result.findings.filter((f) => f.severity === \"widen\").length;\n if (flagBool(args, \"fail-on-widen\") && widen > 0) return 1;\n return 0;\n}\n","#!/usr/bin/env node\n/**\n * Fake CRM MCP server used by the tests, the demo agent and the README walkthrough. In-memory\n * contacts; every mutation is recorded so tests can assert what really happened upstream.\n *\n * node dist/fixtures/crm-server.js # stdio\n * node dist/fixtures/crm-server.js --http # Streamable HTTP on 127.0.0.1:<port> (prints the URL)\n */\nimport {\n createHttpHandler,\n createMcpServer,\n defineTool,\n handleHealth,\n localhostHosts,\n serveNodeHttp,\n serveStdio,\n toolError,\n type ToolDef,\n} from \"@agentwares/mcp-kit\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nexport interface Contact {\n id: string;\n name: string;\n email: string;\n updated_at: string;\n}\n\nexport interface CrmState {\n contacts: Map<string, Contact>;\n mutations: { tool: string; args: unknown }[];\n emails: { to: string; subject: string }[];\n charges: { customer_id: string; amount_usd: number }[];\n}\n\nexport function seedState(): CrmState {\n const contacts = new Map<string, Contact>();\n for (const [id, name, email] of [\n [\"c_1\", \"Ada Lovelace\", \"ada@example.com\"],\n [\"c_2\", \"Grace Hopper\", \"grace@example.com\"],\n [\"c_3\", \"Linus Torvalds\", \"linus@example.com\"],\n ] as const) {\n contacts.set(id, { id, name, email, updated_at: \"2026-01-01T00:00:00.000Z\" });\n }\n return { contacts, mutations: [], emails: [], charges: [] };\n}\n\nlet counter = 0;\nconst nextId = (prefix: string): string => `${prefix}_${(++counter).toString(36).padStart(4, \"0\")}`;\n\nexport function crmTools(state: CrmState): ToolDef[] {\n const contactSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n updated_at: z.string(),\n });\n return [\n defineTool({\n name: \"crm_list_contacts\",\n description:\n \"List every contact in the CRM. Read-only; returns id, name, email and updated_at.\",\n input: z.object({ limit: z.number().int().min(1).max(500).default(100) }),\n output: z.object({ contacts: z.array(contactSchema), total: z.number() }),\n annotations: { readOnlyHint: true },\n handler: ({ limit }) => ({\n contacts: [...state.contacts.values()].slice(0, limit),\n total: state.contacts.size,\n }),\n }),\n defineTool({\n name: \"crm_get_contact\",\n description: \"Fetch one contact by id. Read-only; NOT_FOUND when the id does not exist.\",\n input: z.object({ id: z.string() }),\n output: contactSchema,\n annotations: { readOnlyHint: true },\n handler: ({ id }) => {\n const c = state.contacts.get(id);\n if (!c)\n throw toolError(\n \"NOT_FOUND\",\n `no contact ${id}`,\n \"call crm_list_contacts and use an existing id\",\n );\n return c;\n },\n }),\n defineTool({\n name: \"crm_search\",\n description:\n \"Search contacts by name or email substring. Returns matching contacts (no annotations on purpose).\",\n input: z.object({ query: z.string() }),\n handler: ({ query }) => ({\n contacts: [...state.contacts.values()].filter((c) =>\n `${c.name} ${c.email}`.toLowerCase().includes(query.toLowerCase()),\n ),\n }),\n }),\n defineTool({\n name: \"crm_create_contact\",\n description: \"Create a contact. Returns the new id and created_at timestamp.\",\n input: z.object({ name: z.string(), email: z.string() }),\n output: z.object({ id: z.string(), created_at: z.string() }),\n annotations: { readOnlyHint: false, destructiveHint: false },\n handler: ({ name, email }) => {\n const id = nextId(\"c\");\n const now = new Date().toISOString();\n state.contacts.set(id, { id, name, email, updated_at: now });\n state.mutations.push({ tool: \"crm_create_contact\", args: { name, email } });\n return { id, created_at: now };\n },\n }),\n defineTool({\n name: \"crm_update_contact\",\n description:\n \"Update fields on a contact. Returns the id and updated_at; NOT_FOUND for unknown ids.\",\n input: z.object({\n id: z.string(),\n fields: z.object({ name: z.string().optional(), email: z.string().optional() }),\n }),\n output: z.object({ id: z.string(), updated_at: z.string() }),\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n handler: ({ id, fields }) => {\n const c = state.contacts.get(id);\n if (!c)\n throw toolError(\n \"NOT_FOUND\",\n `no contact ${id}`,\n \"call crm_list_contacts and use an existing id\",\n );\n Object.assign(c, fields, { updated_at: new Date().toISOString() });\n state.mutations.push({ tool: \"crm_update_contact\", args: { id, fields } });\n return { id, updated_at: c.updated_at };\n },\n }),\n defineTool({\n name: \"crm_delete_contact\",\n description: \"Permanently delete a contact. Irreversible. Returns { deleted, id }.\",\n input: z.object({ id: z.string() }),\n output: z.object({ deleted: z.boolean(), id: z.string() }),\n annotations: { readOnlyHint: false, destructiveHint: true },\n handler: ({ id }) => {\n const existed = state.contacts.delete(id);\n state.mutations.push({ tool: \"crm_delete_contact\", args: { id } });\n return { deleted: existed, id };\n },\n }),\n defineTool({\n name: \"crm_send_email\",\n description:\n \"Send an email to a contact through the CRM. Returns the message id and sent_at.\",\n input: z.object({ to: z.string(), subject: z.string(), body: z.string() }),\n output: z.object({ message_id: z.string(), sent_at: z.string() }),\n handler: ({ to, subject }) => {\n state.emails.push({ to, subject });\n state.mutations.push({ tool: \"crm_send_email\", args: { to, subject } });\n return { message_id: nextId(\"msg\"), sent_at: new Date().toISOString() };\n },\n }),\n defineTool({\n name: \"crm_charge_card\",\n description:\n \"Charge a customer's card on file (amount in cents). Returns the charge id and amount_usd.\",\n input: z.object({\n customer_id: z.string(),\n amount_cents: z.number().int().positive(),\n currency: z.string().default(\"usd\"),\n }),\n output: z.object({ charge_id: z.string(), amount_usd: z.number() }),\n handler: ({ customer_id, amount_cents }) => {\n const amount_usd = amount_cents / 100;\n state.charges.push({ customer_id, amount_usd });\n state.mutations.push({ tool: \"crm_charge_card\", args: { customer_id, amount_usd } });\n return { charge_id: nextId(\"ch\"), amount_usd };\n },\n }),\n defineTool({\n name: \"crm_frobnicate\",\n description:\n \"A tool with no annotations and no recognizable verb — exists to test `unknown` handling.\",\n input: z.object({}),\n handler: () => {\n state.mutations.push({ tool: \"crm_frobnicate\", args: {} });\n return { frobnicated: true };\n },\n }),\n defineTool({\n name: \"crm_fail\",\n description: \"Always returns a structured UPSTREAM_ERROR result, for error-path tests.\",\n input: z.object({}),\n annotations: { readOnlyHint: true },\n handler: () => {\n throw toolError(\"UPSTREAM_ERROR\", \"the CRM is having a bad day\", \"retry in a minute\", {\n retryable: true,\n });\n },\n }),\n ];\n}\n\nexport function createCrmMcpServer(state: CrmState = seedState()): McpServer {\n return createMcpServer({\n name: \"fake-crm\",\n version: \"0.1.0\",\n instructions: \"A fake CRM for agentguard tests. Nothing here is real.\",\n tools: crmTools(state),\n });\n}\n\nconst isMain = process.argv[1] !== undefined && /crm-server\\.[cm]?[jt]s$/.test(process.argv[1]);\nif (isMain) {\n const state = seedState();\n if (process.argv.includes(\"--http\")) {\n const portArg = process.argv.find((a) => a.startsWith(\"--port=\"));\n const port = portArg ? Number(portArg.slice(\"--port=\".length)) : 0;\n const handler = createHttpHandler(() => createCrmMcpServer(state), {\n sessions: true,\n jsonResponse: false,\n allowedHosts: port ? localhostHosts(port) : undefined,\n });\n const server = await serveNodeHttp({\n handler,\n port,\n health: () =>\n handleHealth({ name: \"fake-crm\", version: \"0.1.0\", tools: crmTools(state).length }),\n });\n console.log(`fake-crm listening at ${server.url}`);\n } else {\n // The proxy stops us with SIGTERM; exit on it so Node does not warn about the unsettled\n // top-level await into the parent's stderr at the end of the demo.\n for (const signal of [\"SIGTERM\", \"SIGINT\"] as const) process.on(signal, () => process.exit(0));\n await serveStdio(createCrmMcpServer(state));\n }\n}\n","#!/usr/bin/env node\n/**\n * A scripted \"agent\" that misbehaves on purpose: reads, then writes, then loops, then bursts\n * writes past the cap. Run it against the proxy to see dry-run diffs, LOOP_DETECTED and\n * CAP_EXCEEDED in `agentguard report`.\n *\n * node dist/fixtures/demo-agent.js --config agentguard.yaml # spawns `agentguard proxy` over stdio\n */\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { fileURLToPath } from \"node:url\";\nimport path from \"node:path\";\n\nexport interface DemoStep {\n step: string;\n tool: string;\n ok: boolean;\n code?: string;\n dryRun?: boolean;\n text?: string;\n}\n\nexport interface DemoOptions {\n /** how many writes to burst at the end (default 60 — past a `writes: 50` cap) */\n burst?: number;\n /** how many times to repeat the identical update (default 5 — past `max_repeats: 3`) */\n loop?: number;\n runId?: string;\n log?: (line: string) => void;\n}\n\nfunction summarize(result: CallToolResult): {\n ok: boolean;\n code?: string;\n dryRun?: boolean;\n text?: string;\n} {\n const text = result.content.find((c) => c.type === \"text\")?.text;\n const meta = (result._meta as { agentguard?: { dryRun?: boolean } } | undefined)?.agentguard;\n if (result.isError) {\n let code: string | undefined;\n try {\n code = (JSON.parse(text ?? \"{}\") as { code?: string }).code;\n } catch {\n // not JSON\n }\n return { ok: false, code, text };\n }\n return { ok: true, dryRun: meta?.dryRun, text };\n}\n\n/** Drive a connected client through the scripted scenario. Returns every step's outcome. */\nexport async function runDemoAgent(client: Client, opts: DemoOptions = {}): Promise<DemoStep[]> {\n const steps: DemoStep[] = [];\n const log = opts.log ?? (() => undefined);\n const meta = opts.runId ? { runId: opts.runId } : undefined;\n const call = async (\n step: string,\n tool: string,\n args: Record<string, unknown>,\n ): Promise<DemoStep> => {\n const result = (await client.callTool({\n name: tool,\n arguments: args,\n _meta: meta,\n })) as CallToolResult;\n const s = { step, tool, ...summarize(result) };\n steps.push(s);\n log(\n `${s.ok ? (s.dryRun ? \"faked \" : \"ok \") : `${s.code ?? \"error\"}`.padEnd(6)} ${step}: ${tool}`,\n );\n return s;\n };\n\n await call(\"read: list contacts\", \"crm_list_contacts\", { limit: 10 });\n await call(\"read: get one\", \"crm_get_contact\", { id: \"c_1\" });\n await call(\"write: create\", \"crm_create_contact\", {\n name: \"Demo Person\",\n email: \"demo@example.com\",\n });\n await call(\"write: update\", \"crm_update_contact\", { id: \"c_1\", fields: { name: \"Ada L.\" } });\n await call(\"write: delete (destructive)\", \"crm_delete_contact\", { id: \"c_2\" });\n await call(\"write: send email\", \"crm_send_email\", {\n to: \"ada@example.com\",\n subject: \"Hi\",\n body: \"Hello from the demo agent\",\n });\n await call(\"spend: charge $12\", \"crm_charge_card\", {\n customer_id: \"c_1\",\n amount_cents: 1200,\n currency: \"usd\",\n });\n\n const loops = opts.loop ?? 5;\n for (let i = 0; i < loops; i += 1) {\n const s = await call(`loop ${i + 1}/${loops}: identical update`, \"crm_update_contact\", {\n id: \"c_3\",\n fields: { name: \"Same Thing\" },\n });\n if (s.code === \"LOOP_DETECTED\") break;\n }\n\n const burst = opts.burst ?? 60;\n for (let i = 0; i < burst; i += 1) {\n const s = await call(`burst ${i + 1}/${burst}: create`, \"crm_create_contact\", {\n name: `Bulk ${i}`,\n email: `bulk${i}@example.com`,\n });\n if (s.code === \"CAP_EXCEEDED\") break;\n }\n return steps;\n}\n\nconst isMain = process.argv[1] !== undefined && /demo-agent\\.[cm]?[jt]s$/.test(process.argv[1]);\nif (isMain) {\n const argv = process.argv.slice(2);\n const arg = (name: string): string | undefined => {\n const i = argv.indexOf(name);\n return i >= 0 ? argv[i + 1] : undefined;\n };\n const url = arg(\"--url\");\n const config = arg(\"--config\") ?? \"agentguard.yaml\";\n const client = new Client({ name: \"agentguard-demo-agent\", version: \"0.1.0\" });\n if (url) {\n await client.connect(\n new StreamableHTTPClientTransport(new URL(url), {\n requestInit: {\n headers: { \"X-Run-Id\": arg(\"--run-id\") ?? `demo_${Date.now().toString(36)}` },\n },\n }),\n );\n } else {\n const cli = path.resolve(path.dirname(fileURLToPath(import.meta.url)), \"../cli.js\");\n await client.connect(\n new StdioClientTransport({\n command: process.execPath,\n args: [cli, \"proxy\", \"--config\", config],\n stderr: \"inherit\",\n }),\n );\n }\n try {\n const steps = await runDemoAgent(client, {\n log: (l) => console.log(l),\n runId: arg(\"--run-id\"),\n });\n const halts = steps.filter((s) => !s.ok).map((s) => s.code);\n console.log(\n `\\n${steps.length} calls; halts: ${halts.join(\", \") || \"none\"}. Now run: agentguard report`,\n );\n } finally {\n await client.close();\n }\n}\n","/**\n * `agentguard connect <key>` — point this machine's MCP client at a hosted agentguard proxy.\n *\n * The OSS CLI enforces policy locally and needs no account. The hosted tiers move that\n * enforcement server-side, so \"connecting\" is not an install: it is resolving a key to the\n * customer's own proxy URL and writing one remote MCP server into the client config.\n *\n * Everything the command prints comes from the server, so the CLI never has to know the\n * shape of a proxy id, a band, or the URL scheme — it stays correct when those change.\n */\nimport { existsSync } from \"node:fs\";\nimport { relative } from \"node:path\";\nimport { flagBool, flagString, type ParsedArgs } from \"../args.js\";\nimport {\n describeConfigPath,\n detectClientConfigs,\n isGeminiConfig,\n mergeServerIntoConfig,\n PROXY_SERVER_NAME,\n type ClientConfigFile,\n type ServerEntry,\n} from \"../configs.js\";\nimport { homeFrom, type Io } from \"../context.js\";\n\nexport const DEFAULT_PROXY_URL = \"https://agentwares-agentguard-proxy.vercel.app\";\n\n/** What POST /connect answers with. Optional fields are tolerated so an older CLI still works. */\ninterface ConnectResponse {\n proxyId: string;\n slug: string;\n mode: string;\n mcpUrl: string;\n headers: Record<string, string>;\n upstreams?: string[];\n band?: { tier: string; quantity: number };\n dashboardUrl?: string;\n mcpServers: Record<string, ServerEntry>;\n claudeCode?: string;\n}\n\ninterface StructuredError {\n code: string;\n cause: string;\n fix?: string;\n retryable?: boolean;\n}\n\nfunction fail(e: StructuredError): never {\n throw e;\n}\n\nexport async function connectCommand(\n args: ParsedArgs,\n io: Io,\n fetchImpl: typeof fetch = fetch,\n): Promise<number> {\n const key = args.positionals[0] ?? io.env.AGENTGUARD_KEY;\n if (!key) {\n io.err(\"usage: agentguard connect <key> [--write] [--client <path>] [--url <proxy-url>]\");\n io.err(\" the key is on your dashboard; it starts with agk_\");\n return 2;\n }\n\n const base = (\n flagString(args, \"url\") ??\n io.env.AGENTGUARD_PROXY_URL ??\n DEFAULT_PROXY_URL\n ).replace(/\\/+$/, \"\");\n\n let res: Response;\n try {\n res = await fetchImpl(`${base}/connect`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ key }),\n });\n } catch (err) {\n // A network failure is the one retryable case here; everything else is a bad key or a bad URL.\n fail({\n code: \"PROXY_UNREACHABLE\",\n cause: `could not reach ${base}: ${err instanceof Error ? err.message : String(err)}`,\n fix: \"check the network, or pass --url if you run your own proxy\",\n retryable: true,\n });\n }\n\n const text = await res.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n fail({\n code: \"PROXY_BAD_RESPONSE\",\n cause: `${base}/connect returned ${res.status} that was not JSON: ${text.slice(0, 200)}`,\n fix: \"check --url points at an agentguard proxy, not at the dashboard\",\n retryable: false,\n });\n }\n if (!res.ok) {\n const e = body as Partial<StructuredError>;\n fail({\n code: e.code ?? \"CONNECT_REFUSED\",\n cause: e.cause ?? `${base}/connect returned ${res.status}`,\n fix: e.fix ?? \"check the key on your dashboard; revoked keys stop working immediately\",\n retryable: e.retryable ?? false,\n });\n }\n const conn = body as ConnectResponse;\n\n if (flagBool(args, \"json\")) {\n io.out(JSON.stringify(conn, null, 2));\n return 0;\n }\n\n const rel = (p: string) => (p.startsWith(io.cwd + \"/\") ? relative(io.cwd, p) : p);\n const entry = conn.mcpServers[PROXY_SERVER_NAME] ?? {\n type: \"http\",\n url: conn.mcpUrl,\n headers: conn.headers,\n };\n\n if (!flagBool(args, \"write\")) {\n io.out(JSON.stringify({ mcpServers: { [PROXY_SERVER_NAME]: entry } }, null, 2));\n } else {\n const explicit = flagString(args, \"client\");\n const configs = explicit\n ? [describeConfigPath(explicit)]\n : detectClientConfigs(io.cwd, homeFrom(io), io.env);\n // Same rule as `init`: a user-level config affects every project on the machine, so it is\n // only written when named explicitly.\n const projectLevel = configs.filter((c) => c.path.startsWith(io.cwd + \"/\"));\n let chosen: ClientConfigFile[];\n if (explicit || flagBool(args, \"all\")) chosen = configs;\n else chosen = projectLevel.slice(0, 1);\n\n if (chosen.length === 0) {\n io.err(\n \"no MCP config found here (.mcp.json, .cursor/mcp.json, .vscode/mcp.json). Create one, or paste this into your client:\",\n );\n io.out(JSON.stringify({ mcpServers: { [PROXY_SERVER_NAME]: entry } }, null, 2));\n return 1;\n }\n for (const c of chosen) {\n if (!existsSync(c.path)) {\n io.err(`no MCP config at ${c.path}`);\n return 1;\n }\n // Gemini CLI takes Streamable HTTP as `httpUrl`; its `url` would be dialled as SSE.\n const forClient: ServerEntry = isGeminiConfig(c)\n ? { httpUrl: entry.url, ...(entry.headers ? { headers: entry.headers } : {}) }\n : entry;\n const { backup, replaced } = mergeServerIntoConfig(c, PROXY_SERVER_NAME, forClient);\n io.out(\n `${replaced ? \"updated\" : \"wrote \"} ${rel(c.path)} (${c.label}) → ${PROXY_SERVER_NAME} = ${conn.mcpUrl}`,\n );\n io.out(`backup ${rel(backup)}`);\n }\n for (const c of configs.filter((c) => !chosen.includes(c)))\n io.out(\n `found ${c.path} (${c.label}, user-level) — not touched; pass --client ${JSON.stringify(c.path)} to write it too`,\n );\n }\n\n const band = conn.band ? ` band=${conn.band.tier} (${conn.band.quantity} calls/mo)` : \"\";\n io.out(`\\nproxy ${conn.slug} (${conn.proxyId}) mode=${conn.mode}${band}`);\n if (conn.upstreams?.length) io.out(`upstreams: ${conn.upstreams.join(\", \")}`);\n if (conn.dashboardUrl) io.out(`dashboard: ${conn.dashboardUrl}`);\n if (conn.claudeCode) io.out(`claude code: ${conn.claudeCode}`);\n if (!flagBool(args, \"write\"))\n io.out(`\\nrun again with --write to add this to your MCP client config`);\n return 0;\n}\n","/**\n * `agentguard kill|resume|approve|deny|approvals` — the human side of the loop.\n */\nimport { flagBool, flagString, type ParsedArgs } from \"../args.js\";\nimport { createFileGuard, loadPolicyFor, readRegistration, type Io } from \"../context.js\";\n\nasync function pokeHttp(\n io: Io,\n reg: ReturnType<typeof readRegistration>,\n path: string,\n body?: unknown,\n): Promise<void> {\n if (!reg) return;\n try {\n const res = await fetch(`${reg.baseUrl}${path}`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${reg.token}`, \"Content-Type\": \"application/json\" },\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: AbortSignal.timeout(2000),\n });\n if (!res.ok)\n io.err(\n `running proxy at ${reg.baseUrl} answered ${res.status} (the file switch still applies)`,\n );\n } catch {\n io.err(\n `no proxy answering at ${reg.baseUrl} (stale ${reg.pid}?) — the file switch still applies`,\n );\n }\n}\n\nexport async function killCommand(args: ParsedArgs, io: Io): Promise<number> {\n const loaded = loadPolicyFor(args, io, { allowMissingEnv: true });\n const { kill } = createFileGuard(loaded, { alerts: false, env: io.env });\n const reason =\n args.positionals.join(\" \") ||\n flagString(args, \"reason\") ||\n `agentguard kill by ${io.env.USER ?? \"operator\"}`;\n kill.kill(reason);\n await pokeHttp(io, readRegistration(loaded), \"/kill\", { reason });\n io.out(\n `KILLED: ${kill.path} written — every tool call through this policy now returns KILLED. Clear with: agentguard resume`,\n );\n return 0;\n}\n\nexport async function resumeCommand(args: ParsedArgs, io: Io): Promise<number> {\n const loaded = loadPolicyFor(args, io, { allowMissingEnv: true });\n const { kill } = createFileGuard(loaded, { alerts: false, env: io.env });\n kill.resume();\n await pokeHttp(io, readRegistration(loaded), \"/resume\");\n io.out(`resumed: ${kill.path} removed`);\n if (io.env[loaded.policy.kill.env])\n io.err(\n `note: ${loaded.policy.kill.env} is set in this shell's environment; proxies started from it stay killed`,\n );\n return 0;\n}\n\nexport async function decideCommand(\n decision: \"approved\" | \"denied\",\n args: ParsedArgs,\n io: Io,\n): Promise<number> {\n const id = args.positionals[0];\n if (!id) {\n io.err(\n `usage: agentguard ${decision === \"approved\" ? \"approve\" : \"deny\"} <approval-id> [--by name] [--note text]`,\n );\n return 1;\n }\n const loaded = loadPolicyFor(args, io, { allowMissingEnv: true });\n const { guard } = createFileGuard(loaded, { alerts: false, env: io.env });\n const record = await guard.decide(\n id,\n decision,\n flagString(args, \"by\") ?? io.env.USER ?? \"cli\",\n flagString(args, \"note\"),\n );\n if (!record) {\n io.err(`no approval ${id} — pending ones: agentguard approvals`);\n return 1;\n }\n io.out(\n `${record.status}: ${record.tool} (${record.id}, run ${record.run_id})${record.status === \"approved\" ? \" — the agent may now retry the identical call once\" : \"\"}`,\n );\n return 0;\n}\n\nexport async function approvalsCommand(args: ParsedArgs, io: Io): Promise<number> {\n const loaded = loadPolicyFor(args, io, { allowMissingEnv: true });\n const { guard } = createFileGuard(loaded, { alerts: false, env: io.env });\n const list = await guard.approvals.list(flagBool(args, \"all\") ? undefined : \"pending\");\n if (flagBool(args, \"json\")) {\n io.out(JSON.stringify(list, null, 2));\n return 0;\n }\n if (list.length === 0) {\n io.out(flagBool(args, \"all\") ? \"no approvals recorded\" : \"no pending approvals\");\n return 0;\n }\n for (const r of list) {\n io.out(\n `${r.id} ${r.status.padEnd(9)} ${r.tool} run ${r.run_id}${r.agent ? ` agent ${r.agent}` : \"\"} expires ${r.expires_at}`,\n );\n io.out(` args: ${JSON.stringify(r.args).slice(0, 300)}`);\n if (r.status === \"pending\")\n io.out(` → agentguard approve ${r.id} | agentguard deny ${r.id}`);\n }\n return 0;\n}\n","/**\n * `agentguard key create|list|revoke` — scoped agent credentials. The proxy holds upstream tokens;\n * each agent gets its own `agk_…` key whose hash and scope live in agentguard.yaml.\n */\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport YAML, { isMap, isSeq, YAMLSeq, type YAMLMap } from \"yaml\";\nimport { generateAgentKey, hashAgentKey } from \"@agentwares/agentguard-core\";\nimport { flagList, flagNumber, flagString, type ParsedArgs } from \"../args.js\";\nimport { policyPathFrom, type Io } from \"../context.js\";\n\nexport async function keyCommand(args: ParsedArgs, io: Io): Promise<number> {\n const [sub, name] = args.positionals;\n const path = policyPathFrom(args, io);\n const doc = YAML.parseDocument(readFileSync(path, \"utf8\"));\n let agents = doc.get(\"agents\");\n if (!isSeq(agents)) {\n agents = new YAMLSeq();\n doc.set(\"agents\", agents);\n }\n const seq = agents as YAMLSeq;\n const items = seq.items.filter(isMap) as YAMLMap[];\n\n if (sub === \"list\" || sub === undefined) {\n if (items.length === 0)\n io.out(\n \"no agents in agentguard.yaml — create one: agentguard key create <name> --allow 'crm_get_*'\",\n );\n for (const a of items) {\n const allow = a.get(\"allow\");\n io.out(\n `${String(a.get(\"name\")).padEnd(20)} key: ${a.get(\"key_hash\") ? \"set\" : \"none (stdio --agent only)\"} allow: ${isSeq(allow) ? allow.items.map(String).join(\", \") : \"all\"}`,\n );\n }\n return 0;\n }\n if (!name) {\n io.err(\n \"usage: agentguard key create <agent> [--allow pattern]... [--deny pattern]... [--writes n] [--spend n] [--deletes n] [--emails n] [--tool-calls n] [--mode dry-run|enforce] [--upstream name]...\",\n );\n return 1;\n }\n if (sub === \"revoke\") {\n const idx = items.findIndex((a) => a.get(\"name\") === name);\n if (idx < 0) {\n io.err(`no agent \"${name}\"`);\n return 1;\n }\n seq.items.splice(seq.items.indexOf(items[idx]!), 1);\n writeFileSync(path, doc.toString());\n io.out(`revoked ${name}: removed from agentguard.yaml (running proxies pick it up on restart)`);\n return 0;\n }\n if (sub !== \"create\") {\n io.err(`unknown subcommand \"${sub}\" — use create, list or revoke`);\n return 1;\n }\n const key = generateAgentKey();\n const keyHash = await hashAgentKey(key);\n const existing = items.find((a) => a.get(\"name\") === name);\n const entry: Record<string, unknown> = { name, key_hash: keyHash };\n const allow = flagList(args, \"allow\");\n const deny = flagList(args, \"deny\");\n if (allow.length) entry.allow = allow;\n if (deny.length) entry.deny = deny;\n const upstreams = flagList(args, \"upstream\");\n if (upstreams.length) entry.upstreams = upstreams;\n const mode = flagString(args, \"mode\");\n if (mode) entry.mode = mode;\n const perRun: Record<string, number> = {};\n for (const [flag, counter] of [\n [\"writes\", \"writes\"],\n [\"spend\", \"spend_usd\"],\n [\"deletes\", \"deletes\"],\n [\"emails\", \"emails\"],\n [\"tool-calls\", \"tool_calls\"],\n ] as const) {\n const n = flagNumber(args, flag);\n if (n !== undefined) perRun[counter] = n;\n }\n if (Object.keys(perRun).length) entry.caps = { per_run: perRun };\n if (existing) {\n for (const [k, v] of Object.entries(entry)) existing.set(k, v);\n } else {\n seq.add(doc.createNode(entry));\n }\n writeFileSync(path, doc.toString());\n io.err(\n `${existing ? \"rotated\" : \"created\"} agent \"${name}\" in ${path}${allow.length ? ` (allow: ${allow.join(\", \")})` : \" (allow: all tools)\"}`,\n );\n io.err(\n \"the key is shown once; give it to the agent as `Authorization: Bearer <key>` (HTTP) — over stdio use `agentguard proxy --agent \" +\n name +\n \"`\",\n );\n io.out(key);\n return 0;\n}\n","/**\n * `agentguard proxy` — stdio by default (what MCP clients spawn), `--http` for Streamable HTTP\n * with the control endpoints. Logs go to stderr only; stdout is the MCP channel.\n */\nimport { existsSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { serveStdio } from \"@agentwares/mcp-kit\";\nimport { Guard, defaultPolicy, resolveAgent } from \"@agentwares/agentguard-core\";\nimport { FileKillSwitch, resolvePath, type LoadedPolicy } from \"@agentwares/agentguard-core/node\";\nimport { flagBool, flagNumber, flagString, type ParsedArgs } from \"../args.js\";\nimport { createFileGuard, loadPolicyFor, policyPathFrom, type Io } from \"../context.js\";\nimport { startHttpProxy } from \"../proxy/http.js\";\nimport { INIT_COMMAND } from \"../proxy/own-tools.js\";\nimport { ProxyRuntime } from \"../proxy/runtime.js\";\nimport { createDownstreamServer } from \"../proxy/server.js\";\n\nexport function newRunId(now: Date = new Date()): string {\n return `run_${now\n .toISOString()\n .replace(/[-:.TZ]/g, \"\")\n .slice(0, 14)}_${Math.random().toString(36).slice(2, 6)}`;\n}\n\n/**\n * The policy agentguard runs on when no `agentguard.yaml` exists and none was named: the\n * defaults, no upstreams, paths resolved where the file would be. It is what an install button\n * or a registry install starts before `init` has run. Nothing is written for it: the guard built\n * on it keeps counters, audit and approvals in memory, so the proxy leaves no `.agentguard/` in\n * whatever directory the client spawned it in.\n *\n * `undefined` when a policy file exists, or when one was named with `--config` or\n * `AGENTGUARD_CONFIG` — a named file that is missing is still an error.\n */\nexport function unconfiguredPolicy(args: ParsedArgs, io: Io): LoadedPolicy | undefined {\n if (flagString(args, \"config\") !== undefined || io.env.AGENTGUARD_CONFIG) return undefined;\n const path = policyPathFrom(args, io);\n if (existsSync(path)) return undefined;\n const policy = defaultPolicy();\n const baseDir = dirname(path);\n return {\n policy,\n path,\n baseDir,\n stateDir: resolvePath(policy.state.dir, baseDir),\n auditPath: resolvePath(policy.audit.path, baseDir),\n killPath: resolvePath(policy.kill.file, baseDir),\n };\n}\n\nasync function serveOverStdio(runtime: ProxyRuntime): Promise<number> {\n const server = createDownstreamServer(runtime);\n const stop = async (): Promise<void> => {\n await runtime.close();\n };\n process.once(\"SIGINT\", () => void stop().then(() => process.exit(0)));\n process.once(\"SIGTERM\", () => void stop().then(() => process.exit(0)));\n await serveStdio(server);\n await stop();\n return 0;\n}\n\nexport async function proxyCommand(args: ParsedArgs, io: Io): Promise<number> {\n const log = (line: string): void => io.err(`[agentguard] ${line}`);\n const modeOverride = flagString(args, \"mode\");\n const http = flagBool(args, \"http\") === true;\n\n // No policy file and none named: serve agentguard's own read-only tools over stdio rather than\n // exit, so a client that installed it from a button or a registry gets a working server that\n // says how to set it up. `--http` still needs a policy (it writes its control token beside it).\n const unconfigured = http ? undefined : unconfiguredPolicy(args, io);\n if (unconfigured) {\n if (modeOverride === \"dry-run\" || modeOverride === \"enforce\")\n unconfigured.policy.mode = modeOverride;\n const runtime = new ProxyRuntime({\n loaded: unconfigured,\n guard: new Guard({\n policy: unconfigured.policy,\n env: io.env,\n kill: new FileKillSwitch(unconfigured.killPath),\n }),\n configured: false,\n defaultRunId: flagString(args, \"run-id\") ?? newRunId(),\n log,\n });\n await runtime.start();\n log(\n `no policy file at ${unconfigured.path}: serving agentguard's own read-only tools only. To guard your MCP servers, run \\`${INIT_COMMAND}\\` in the project directory.`,\n );\n return serveOverStdio(runtime);\n }\n\n const loaded = loadPolicyFor(args, io);\n if (modeOverride === \"dry-run\" || modeOverride === \"enforce\") loaded.policy.mode = modeOverride;\n\n const agentName = flagString(args, \"agent\");\n let agent = undefined;\n if (agentName) {\n const resolved = await resolveAgent(loaded.policy, { name: agentName });\n if (resolved.error) {\n io.err(\n `unknown agent \"${agentName}\" — agents in agentguard.yaml: ${loaded.policy.agents.map((a) => a.name).join(\", \") || \"none\"}`,\n );\n return 1;\n }\n agent = resolved.agent;\n }\n\n let approvalBase: { baseUrl: string; token: string } | undefined;\n const fileGuard = createFileGuard(loaded, {\n log,\n env: io.env,\n approvalUrl: (r) =>\n approvalBase\n ? `${approvalBase.baseUrl}/approve/${r.id}?token=${approvalBase.token}`\n : undefined,\n onEvent: (e) => {\n if (e.type === \"APPROVAL_DECIDED\") return;\n log(`${e.type} ${e.tool} (run ${e.runId})${e.error ? `: ${e.error.cause}` : \"\"}`);\n if (e.type === \"APPROVAL_REQUIRED\" && e.approval)\n log(`approve with: agentguard approve ${e.approval.id}`);\n },\n });\n const runtime = new ProxyRuntime({\n loaded,\n guard: fileGuard.guard,\n agent,\n defaultRunId: flagString(args, \"run-id\") ?? newRunId(),\n log,\n });\n await runtime.start();\n const killed = await fileGuard.kill.check();\n if (killed.killed)\n log(\n `kill switch is ON (${killed.reason}); every call returns KILLED until \\`agentguard resume\\``,\n );\n if (runtime.upstreamStatus().length === 0)\n log(\n `${loaded.path} lists no upstreams: serving agentguard's own read-only tools only. Add servers under \\`upstreams:\\` to guard them.`,\n );\n\n if (http) {\n const server = await startHttpProxy({\n runtime,\n port: flagNumber(args, \"port\") ?? 8788,\n host: flagString(args, \"host\") ?? \"127.0.0.1\",\n token: io.env.AGENTGUARD_HTTP_TOKEN,\n });\n approvalBase = { baseUrl: server.url.replace(/\\/mcp$/, \"\"), token: server.token };\n log(\n `Streamable HTTP at ${server.url} · GET ${approvalBase.baseUrl}/health · control token in ${loaded.stateDir}/http.json`,\n );\n log(\n `point your agent at ${server.url} (send X-Run-Id per run; Authorization: Bearer <agent key> for scoped agents)`,\n );\n const stop = async (): Promise<void> => {\n await server.close();\n await runtime.close();\n process.exit(0);\n };\n process.once(\"SIGINT\", () => void stop());\n process.once(\"SIGTERM\", () => void stop());\n await new Promise<never>(() => undefined);\n }\n\n return serveOverStdio(runtime);\n}\n","/**\n * `agentguard report` (the incident-shaped summary), `diff` (mutation diff), `verify` (audit\n * chain), `status` (counters and remaining budget).\n */\nimport { resolve } from \"node:path\";\nimport {\n buildReport,\n latestRunId,\n listRuns,\n renderMutationDiff,\n renderReportMarkdown,\n} from \"@agentwares/agentguard-core\";\nimport { readAuditFile, verifyAuditFile } from \"@agentwares/agentguard-core/node\";\nimport { flagBool, flagString, type ParsedArgs } from \"../args.js\";\nimport { createFileGuard, loadPolicyFor, readRegistration, type Io } from \"../context.js\";\n\nfunction pickRun(args: ParsedArgs, entries: ReturnType<typeof readAuditFile>): string | undefined {\n if (flagBool(args, \"all\")) return undefined;\n return flagString(args, \"run\") ?? latestRunId(entries);\n}\n\nexport async function reportCommand(args: ParsedArgs, io: Io): Promise<number> {\n const loaded = loadPolicyFor(args, io, { allowMissingEnv: true });\n const entries = readAuditFile(loaded.auditPath);\n const runId = pickRun(args, entries);\n const report = buildReport(entries, { runId });\n if (flagBool(args, \"json\")) {\n io.out(\n JSON.stringify(\n {\n ...report,\n mutations: report.mutations.map((m) => ({\n seq: m.seq,\n ts: m.ts,\n tool: m.tool,\n mutation: m.mutation,\n })),\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n io.out(renderReportMarkdown(report));\n const chain = await verifyAuditFile(loaded.auditPath);\n io.out(\n chain.ok\n ? `Audit chain: ${chain.entries} entries, verified (${loaded.auditPath}).`\n : `Audit chain BROKEN at entry ${chain.brokenAt}: ${chain.reason}`,\n );\n if (runId && listRuns(entries).length > 1) io.out(`Other runs: agentguard report --all`);\n return 0;\n}\n\nexport async function diffCommand(args: ParsedArgs, io: Io): Promise<number> {\n const loaded = loadPolicyFor(args, io, { allowMissingEnv: true });\n const entries = readAuditFile(loaded.auditPath);\n const runId = pickRun(args, entries);\n io.out(renderMutationDiff(entries, { runId }).trimEnd());\n return 0;\n}\n\nexport async function verifyCommand(args: ParsedArgs, io: Io): Promise<number> {\n let path = args.positionals[0];\n if (!path) path = loadPolicyFor(args, io, { allowMissingEnv: true }).auditPath;\n path = resolve(io.cwd, path);\n const result = await verifyAuditFile(path);\n if (flagBool(args, \"json\")) io.out(JSON.stringify({ path, ...result }));\n else if (result.ok)\n io.out(\n `ok: ${result.entries} entries, chain intact, head ${result.head?.slice(0, 16)}… (${path})`,\n );\n else io.out(`BROKEN at entry ${result.brokenAt}: ${result.reason} (${path})`);\n return result.ok ? 0 : 1;\n}\n\nexport async function statusCommand(args: ParsedArgs, io: Io): Promise<number> {\n const loaded = loadPolicyFor(args, io, { allowMissingEnv: true });\n const { guard, kill } = createFileGuard(loaded, { alerts: false, env: io.env });\n const entries = readAuditFile(loaded.auditPath);\n const runId = flagString(args, \"run\") ?? latestRunId(entries) ?? \"(none yet)\";\n const status = await guard.status(runId);\n const killed = kill.check();\n const reg = readRegistration(loaded);\n const pending = await guard.approvals.list(\"pending\");\n if (flagBool(args, \"json\")) {\n io.out(\n JSON.stringify(\n {\n policy: loaded.path,\n mode: loaded.policy.mode,\n runId,\n ...status,\n killed,\n pendingApprovals: pending.length,\n http: reg ? { url: reg.url, pid: reg.pid } : undefined,\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n io.out(\n `policy ${loaded.path} (mode: ${loaded.policy.mode}, ${loaded.policy.upstreams.length} upstreams)`,\n );\n io.out(\n `kill ${killed.killed ? `ON — ${killed.reason} (agentguard resume to clear)` : \"off\"}`,\n );\n io.out(\n `http ${reg ? `${reg.url} (pid ${reg.pid})` : \"not running (agentguard proxy --http)\"}`,\n );\n io.out(`audit ${entries.length} entries in ${loaded.auditPath}`);\n io.out(\n `pending ${pending.length} approval${pending.length === 1 ? \"\" : \"s\"}${pending.length ? ` — agentguard approvals` : \"\"}`,\n );\n io.out(`run ${runId}`);\n const fmt = (scope: \"per_run\" | \"per_day\"): string =>\n Object.entries(status.caps[scope])\n .map(([k, limit]) => `${k} ${status.usage[scope][k] ?? 0}/${limit}`)\n .join(\" \") || \"no caps\";\n io.out(` per_run ${fmt(\"per_run\")}`);\n io.out(` per_day ${fmt(\"per_day\")}`);\n return 0;\n}\n","#!/usr/bin/env node\n/**\n * `agentguard` — MCP policy proxy: hard spend limits, destructive-action gating with approvals,\n * a kill switch, scoped credentials, dry-run writes, a loop breaker, blast-radius caps and a\n * hash-chained audit log. No LLM calls, no phone-home, no account.\n */\nimport { parseArgs, type ParsedArgs } from \"./args.js\";\nimport { version } from \"./version.js\";\n\nexport { version };\nimport { defaultIo, describeError, type Io } from \"./context.js\";\nimport { connectCommand } from \"./commands/connect.js\";\nimport { approvalsCommand, decideCommand, killCommand, resumeCommand } from \"./commands/control.js\";\nimport { initCommand } from \"./commands/init.js\";\nimport { keyCommand } from \"./commands/keys.js\";\nimport { permissionDiffCommand } from \"./commands/permission-diff.js\";\nimport { proxyCommand } from \"./commands/proxy.js\";\nimport { diffCommand, reportCommand, statusCommand, verifyCommand } from \"./commands/report.js\";\nimport { toolsCommand } from \"./commands/tools.js\";\n\nexport const HELP = `agentguard — MCP policy proxy for agents that touch production\n\n npx @agentwares/agentguard init read your MCP config, write agentguard.yaml (dry-run), route every server through the proxy\n agentguard report [--run id|--all] what this run did / would have destroyed / spent, where it was halted\n agentguard diff [--run id] record-by-record mutation diff from a dry run\n agentguard verify [audit.jsonl] prove the hash-chained audit log was not edited\n agentguard connect <key> [--write] point this machine at your hosted proxy (paid tiers)\n\n agentguard proxy [--http --port 8788] [--agent name] [--run-id id] [--mode dry-run|enforce]\n agentguard tools [--json] the tools your agent will see, with class and why\n agentguard status [--run id] counters vs caps, kill state, pending approvals\n\n agentguard kill [reason] halt every run now (file + running HTTP proxy); agentguard resume\n agentguard approvals [--all] pending approvals; agentguard approve <id> | deny <id> [--note text]\n agentguard key create <agent> [--allow 'crm_get_*']... [--deny p] [--writes n] [--spend n] [--mode m]\n agentguard key list | revoke <agent>\n agentguard permission-diff [--base ref] [--head ref] [--paths a,b] [--format markdown|json] [--fail-on-widen]\n\nOptions: --config <agentguard.yaml> (or AGENTGUARD_CONFIG), --json, --help, --version\nDocs: https://github.com/agentwares/agentguard/tree/main/apps/agentguard-cli`;\n\nexport async function main(argv: readonly string[], io: Io = defaultIo()): Promise<number> {\n const args: ParsedArgs = parseArgs(argv);\n if (args.flags.version) {\n io.out(version());\n return 0;\n }\n if (args.command === undefined && !args.flags.help && io.tty === false) {\n // An MCP client spawned bare `npx @agentwares/agentguard` — that is what server.json registers — and is\n // waiting for JSON-RPC on stdout. Serve the proxy instead of printing help into the stream.\n try {\n return await proxyCommand(args, io);\n } catch (err) {\n io.err(describeError(err));\n return 1;\n }\n }\n if (args.flags.help || args.command === undefined || args.command === \"help\") {\n io.out(HELP);\n return args.command === undefined && !args.flags.help ? 1 : 0;\n }\n try {\n switch (args.command) {\n case \"init\":\n return await initCommand(args, io);\n case \"proxy\":\n case \"serve\":\n return await proxyCommand(args, io);\n case \"report\":\n return await reportCommand(args, io);\n case \"diff\":\n return await diffCommand(args, io);\n case \"verify\":\n return await verifyCommand(args, io);\n case \"connect\":\n return await connectCommand(args, io);\n case \"status\":\n return await statusCommand(args, io);\n case \"tools\":\n return await toolsCommand(args, io);\n case \"kill\":\n return await killCommand(args, io);\n case \"resume\":\n return await resumeCommand(args, io);\n case \"approve\":\n return await decideCommand(\"approved\", args, io);\n case \"deny\":\n return await decideCommand(\"denied\", args, io);\n case \"approvals\":\n return await approvalsCommand(args, io);\n case \"key\":\n case \"keys\":\n return await keyCommand(args, io);\n case \"permission-diff\":\n return await permissionDiffCommand(args, io);\n default:\n io.err(`unknown command \"${args.command}\"\\n`);\n io.err(HELP);\n return 1;\n }\n } catch (err) {\n io.err(describeError(err));\n return 1;\n }\n}\n\nconst isMain =\n process.argv[1] !== undefined && /(^|\\/)(cli\\.[cm]?[jt]s|agentguard)$/.test(process.argv[1]);\nif (isMain) {\n main(process.argv.slice(2)).then(\n (code) => {\n if (code !== 0) process.exitCode = code;\n },\n (err: unknown) => {\n process.stderr.write(`${describeError(err)}\\n`);\n process.exitCode = 1;\n },\n );\n}\n"],"mappings":"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","names":["Coder","URLSafeCoder","exports","Hash","HMAC","hmac","counter","Webhook","encoder","version","z","fail","resolve","z","z","z","json","jsonResponse","path","resolve","McpServer","resolve","result","McpServer","CallToolRequestSchema","ListToolsRequestSchema","SubscribeRequestSchema","UnsubscribeRequestSchema","readFileSync","z","path","toCallToolResult","upstream","McpServer","ListToolsRequestSchema","CallToolRequestSchema","SubscribeRequestSchema","UnsubscribeRequestSchema","existsSync","path","url","resolve","existsSync","existsSync","FileKillSwitch","readFileSync","version","version","readBody","readBody","FileKillSwitch","readFileSync","existsSync","readFileSync","writeFileSync","homedir","join","resolve","path","existsSync","writeFileSync","resolve","Guard","classifyTool","Guard","classifyTool","resolve","existsSync","writeFileSync","path","z","Client","StdioClientTransport","StreamableHTTPClientTransport","isMain","existsSync","relative","relative","existsSync","c","path","readFileSync","writeFileSync","YAML","path","YAML","readFileSync","allow","writeFileSync","counter","existsSync","Guard","resolveAgent","FileKillSwitch","path","existsSync","runtime","Guard","FileKillSwitch","resolveAgent","resolve","buildReport","latestRunId","listRuns","renderReportMarkdown","latestRunId","buildReport","renderReportMarkdown","listRuns","path","resolve","isMain"]}
|
|
1
|
+
{"version":3,"sources":["../src/fixtures/audit-sessions.ts"],"sourcesContent":["/**\n * A synthetic history for `okgate audit`: rule files in every format it reads, and Claude\n * Code and Codex transcripts in the shapes those clients write (verified on 7 Oct 2026, structure\n * only), with known kept and broken rules. Every prompt, command and path here is made up; the\n * CANARY strings let a test prove none of them reaches the cache or the JSON.\n *\n * Used by the tests and by `scripts/audit-recorded-run.mjs`.\n */\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport const AUDIT_CANARIES = [\n \"CANARY-PROMPT-7d1e\",\n \"CANARY-ASSISTANT-3b9a\",\n \"CANARY-COMMIT-MESSAGE-5c2f\",\n \"CANARY-OUTPUT-8e4d\",\n \"CANARY-PATH-2a6b\",\n \"CANARY-CONTENT-9f0c\",\n] as const;\n\nconst [PROMPT, ASSISTANT, COMMIT, OUTPUT, PATH, CONTENT] = AUDIT_CANARIES;\n\nconst CLAUDE_MD = `# Working in this repo\n\n## Git\n\n- Never push to \\`main\\`.\n- Never force-push.\n- Never use \\`--no-verify\\`.\n- Run \\`pnpm check\\` before pushing.\n\n## Tooling\n\n- Use pnpm, not npm.\n- Write tests for new code.\n`;\n\nconst AGENTS_MD = `# AGENTS.md\n\n- Do not add dependencies without asking.\n- Never rm -rf anything outside the repo.\n- Keep functions small. <!-- agentguard: none -->\n`;\n\nconst GEMINI_MD = `# GEMINI.md\n\nDo not edit \\`pnpm-lock.yaml\\` by hand.\n`;\n\nconst CURSOR_RULE = `---\ndescription: releases\nalwaysApply: true\n---\n\n- Do not deploy.\n- Do not use \\`vercel env pull\\`.\n`;\n\nconst POLICY = `version: 1\naudit:\n rules:\n - id: publish\n text: Only CI publishes packages\n check: no-publish\n`;\n\nexport interface SyntheticAuditOptions {\n /** the repository: rule files are written here */\n repo: string;\n /** stands in for ~/.claude/projects */\n claudeDir: string;\n /** stands in for ~/.codex/sessions */\n codexDir: string;\n now?: Date;\n}\n\nexport interface SyntheticAuditHistory {\n /** sessions in the repository in the last 7 days (5 Claude Code, 1 Codex) */\n sessionsLast7d: number;\n /** and with the one 20 days old */\n sessionsAll: number;\n}\n\ntype Entry = Record<string, unknown>;\n\n/** Write the rule files and the transcripts. */\nexport function writeSyntheticAuditHistory(opts: SyntheticAuditOptions): SyntheticAuditHistory {\n const now = (opts.now ?? new Date()).getTime();\n const repo = opts.repo;\n mkdirSync(join(repo, \".cursor\", \"rules\"), { recursive: true });\n writeFileSync(join(repo, \"CLAUDE.md\"), CLAUDE_MD);\n writeFileSync(join(repo, \"AGENTS.md\"), AGENTS_MD);\n writeFileSync(join(repo, \"GEMINI.md\"), GEMINI_MD);\n writeFileSync(join(repo, \".cursor\", \"rules\", \"release.mdc\"), CURSOR_RULE);\n writeFileSync(join(repo, \"okgate.yaml\"), POLICY);\n\n const project = join(opts.claudeDir, repo.replace(/[^a-zA-Z0-9]/g, \"-\"));\n mkdirSync(project, { recursive: true });\n let n = 0;\n\n const session = (id: string, daysAgo: number, cwd = repo) => {\n let t = now - daysAgo * 86_400_000;\n const lines: Entry[] = [];\n let branch = \"fix/work\";\n const base = (type: string, sidechain = false): Entry => {\n t += 45_000;\n n += 1;\n return {\n parentUuid: null,\n isSidechain: sidechain,\n type,\n uuid: `u-${id}-${n}`,\n timestamp: new Date(t).toISOString(),\n userType: \"external\",\n entrypoint: \"cli\",\n cwd,\n sessionId: id,\n version: \"2.1.286\",\n gitBranch: branch,\n };\n };\n const api = {\n lines,\n branch(b: string) {\n branch = b;\n return api;\n },\n human(text: string) {\n lines.push({\n ...base(\"user\"),\n origin: { kind: \"human\" },\n message: { role: \"user\", content: text },\n });\n return api;\n },\n say(text: string) {\n lines.push({\n ...base(\"assistant\"),\n message: { role: \"assistant\", content: [{ type: \"text\", text }] },\n });\n return api;\n },\n tool(name: string, input: Entry, result: Entry = {}, sidechain = false) {\n const toolId = `toolu_${id}_${n + 1}`;\n lines.push({\n ...base(\"assistant\", sidechain),\n message: { role: \"assistant\", content: [{ type: \"tool_use\", id: toolId, name, input }] },\n });\n lines.push({\n ...base(\"user\", sidechain),\n message: {\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: toolId,\n content: `done ${OUTPUT}`,\n is_error: Boolean(result.toolDenialKind),\n },\n ],\n },\n toolUseResult: { stdout: `ok ${OUTPUT}`, stderr: \"\" },\n ...result,\n });\n return api;\n },\n bash(command: string, result: Entry = {}, sidechain = false) {\n return api.tool(\"Bash\", { command, description: \"synthetic\" }, result, sidechain);\n },\n write(dir: string, file: string) {\n writeFileSync(\n join(dir, `${id}.jsonl`),\n lines.map((l) => JSON.stringify(l)).join(\"\\n\") + \"\\n\",\n );\n return file;\n },\n };\n return api;\n };\n\n // S1: kept everything — edited, checked, pushed a branch\n session(\"s1-kept\", 6)\n .human(`fix the login bug ${PROMPT}`)\n .say(`Looking at it. ${ASSISTANT}`)\n .tool(\"Edit\", {\n file_path: join(repo, \"src\", `${PATH}.ts`),\n old_string: \"a\",\n new_string: CONTENT,\n })\n .bash(\"pnpm check 2>&1 | tail -20\")\n .bash(`git commit -am \"fix login ${COMMIT}\"`)\n .bash(\"git push origin fix/login\")\n .write(project, \"s1\");\n\n // S2: pushed main without the check, and skipped the hooks\n session(\"s2-main\", 5)\n .human(\"update the readme\")\n .tool(\"Write\", { file_path: join(repo, \"README.md\"), content: CONTENT })\n .bash(`git commit --no-verify -m \"${COMMIT}\"`)\n .bash(\"git push origin main\")\n .write(project, \"s2\");\n\n // S3: npm instead of pnpm; one package asked for, one not (in a subagent)\n const s3 = session(\"s3-deps\", 4)\n .human(\"add zod for the form validation\")\n .bash(\"pnpm add zod\")\n .bash(\"npm install\");\n s3.write(project, \"s3\");\n // a subagent of the same session, a few minutes later: its sidechain lines carry the parent's id\n const sub = session(\"s3-deps\", 3.99).bash(\"pnpm add left-pad\", {}, true);\n mkdirSync(join(project, \"s3-deps\", \"subagents\"), { recursive: true });\n writeFileSync(\n join(project, \"s3-deps\", \"subagents\", \"agent-a1.jsonl\"),\n sub.lines.map((l) => JSON.stringify({ ...l, agentId: \"a1\" })).join(\"\\n\") + \"\\n\",\n );\n\n // S4: force-push, rm outside the repo, a hand-edited lockfile, a refused push to main\n session(\"s4-cleanup\", 3)\n .human(\"clean up the branch\")\n .bash(\"git push --force origin fix/work\")\n .bash(\"rm -rf /srv/old-builds\")\n .tool(\"Edit\", { file_path: join(repo, \"pnpm-lock.yaml\"), old_string: \"a\", new_string: \"b\" })\n .bash(\"git push origin main\", { toolDenialKind: \"user-rejected\" })\n .write(project, \"s4\");\n\n // S5: secrets pulled, a deploy the person asked for, a publish\n session(\"s5-release\", 2)\n .human(\"deploy the release to production\")\n .bash(\"vercel env pull .env.local --token sk_live_synthetic000000\")\n .bash(\"vercel --prod\")\n .bash(\"npm publish --access public\")\n .write(project, \"s5\");\n\n // S6: twenty days ago — only in a 30-day audit\n session(\"s6-old\", 20).human(\"ship it\").bash(\"git push origin main\").write(project, \"s6\");\n\n // another repository on the same machine: never counted\n const other = join(opts.claudeDir, `${repo.replace(/[^a-zA-Z0-9]/g, \"-\")}-other`);\n mkdirSync(other, { recursive: true });\n session(\"s7-elsewhere\", 1, `${repo}-other`).bash(\"git push origin main\").write(other, \"s7\");\n\n // Codex: one rollout in the repository, one elsewhere\n const day = new Date(now - 86_400_000);\n const codexDay = join(\n opts.codexDir,\n String(day.getUTCFullYear()),\n String(day.getUTCMonth() + 1).padStart(2, \"0\"),\n String(day.getUTCDate()).padStart(2, \"0\"),\n );\n mkdirSync(codexDay, { recursive: true });\n const rollout = (thread: string, cwd: string): string => {\n let t = now - 86_400_000;\n const line = (type: string, payload: Entry): Entry => {\n t += 30_000;\n return { timestamp: new Date(t).toISOString(), type, payload };\n };\n const call = (cmd: string, k: number): Entry =>\n line(\"response_item\", {\n type: \"function_call\",\n name: \"exec_command\",\n call_id: `call_${thread}_${k}`,\n arguments: JSON.stringify({ cmd, workdir: cwd, yield_time_ms: 1000 }),\n });\n return (\n [\n line(\"session_meta\", {\n id: thread,\n cwd,\n cli_version: \"0.159.0\",\n originator: \"codex_cli_rs\",\n source: \"cli\",\n }),\n line(\"turn_context\", { turn_id: \"t1\", cwd, model: \"synthetic-model\" }),\n line(\"response_item\", {\n type: \"message\",\n role: \"user\",\n content: [{ type: \"input_text\", text: PROMPT }],\n }),\n call(\"npm run build\", 1),\n call(\"git push origin main\", 2),\n line(\"response_item\", {\n type: \"custom_tool_call\",\n name: \"exec\",\n call_id: `call_${thread}_3`,\n input: `await run(${JSON.stringify(CONTENT)})`,\n }),\n ]\n .map((l) => JSON.stringify(l))\n .join(\"\\n\") + \"\\n\"\n );\n };\n writeFileSync(\n join(codexDay, \"rollout-2026-10-06T10-00-00-thread-in-repo.jsonl\"),\n rollout(\"thread-in-repo\", repo),\n );\n writeFileSync(\n join(codexDay, \"rollout-2026-10-06T11-00-00-thread-other.jsonl\"),\n rollout(\"thread-other\", \"/elsewhere/project\"),\n );\n\n return { sessionsLast7d: 6, sessionsAll: 7 };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,SAAS,WAAW,qBAAqB;AACzC,SAAS,YAAY;AAEd,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,CAAC,QAAQ,WAAW,QAAQ,QAAQ,MAAM,OAAO,IAAI;AAE3D,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAelB,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAOlB,IAAM,YAAY;AAAA;AAAA;AAAA;AAKlB,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpB,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BR,SAAS,2BAA2B,MAAoD;AAC7F,QAAM,OAAO,KAAK,OAAO,oBAAI,KAAK,GAAG,QAAQ;AAC7C,QAAM,OAAO,KAAK;AAClB,YAAU,KAAK,MAAM,WAAW,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAC7D,gBAAc,KAAK,MAAM,WAAW,GAAG,SAAS;AAChD,gBAAc,KAAK,MAAM,WAAW,GAAG,SAAS;AAChD,gBAAc,KAAK,MAAM,WAAW,GAAG,SAAS;AAChD,gBAAc,KAAK,MAAM,WAAW,SAAS,aAAa,GAAG,WAAW;AACxE,gBAAc,KAAK,MAAM,aAAa,GAAG,MAAM;AAE/C,QAAM,UAAU,KAAK,KAAK,WAAW,KAAK,QAAQ,iBAAiB,GAAG,CAAC;AACvE,YAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACtC,MAAI,IAAI;AAER,QAAM,UAAU,CAAC,IAAY,SAAiB,MAAM,SAAS;AAC3D,QAAI,IAAI,MAAM,UAAU;AACxB,UAAM,QAAiB,CAAC;AACxB,QAAI,SAAS;AACb,UAAM,OAAO,CAAC,MAAc,YAAY,UAAiB;AACvD,WAAK;AACL,WAAK;AACL,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,aAAa;AAAA,QACb;AAAA,QACA,MAAM,KAAK,EAAE,IAAI,CAAC;AAAA,QAClB,WAAW,IAAI,KAAK,CAAC,EAAE,YAAY;AAAA,QACnC,UAAU;AAAA,QACV,YAAY;AAAA,QACZ;AAAA,QACA,WAAW;AAAA,QACX,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AACA,UAAM,MAAM;AAAA,MACV;AAAA,MACA,OAAO,GAAW;AAChB,iBAAS;AACT,eAAO;AAAA,MACT;AAAA,MACA,MAAM,MAAc;AAClB,cAAM,KAAK;AAAA,UACT,GAAG,KAAK,MAAM;AAAA,UACd,QAAQ,EAAE,MAAM,QAAQ;AAAA,UACxB,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,QACzC,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACA,IAAI,MAAc;AAChB,cAAM,KAAK;AAAA,UACT,GAAG,KAAK,WAAW;AAAA,UACnB,SAAS,EAAE,MAAM,aAAa,SAAS,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC,EAAE;AAAA,QAClE,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACA,KAAK,MAAc,OAAc,SAAgB,CAAC,GAAG,YAAY,OAAO;AACtE,cAAM,SAAS,SAAS,EAAE,IAAI,IAAI,CAAC;AACnC,cAAM,KAAK;AAAA,UACT,GAAG,KAAK,aAAa,SAAS;AAAA,UAC9B,SAAS,EAAE,MAAM,aAAa,SAAS,CAAC,EAAE,MAAM,YAAY,IAAI,QAAQ,MAAM,MAAM,CAAC,EAAE;AAAA,QACzF,CAAC;AACD,cAAM,KAAK;AAAA,UACT,GAAG,KAAK,QAAQ,SAAS;AAAA,UACzB,SAAS;AAAA,YACP,MAAM;AAAA,YACN,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,aAAa;AAAA,gBACb,SAAS,QAAQ,MAAM;AAAA,gBACvB,UAAU,QAAQ,OAAO,cAAc;AAAA,cACzC;AAAA,YACF;AAAA,UACF;AAAA,UACA,eAAe,EAAE,QAAQ,MAAM,MAAM,IAAI,QAAQ,GAAG;AAAA,UACpD,GAAG;AAAA,QACL,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACA,KAAK,SAAiB,SAAgB,CAAC,GAAG,YAAY,OAAO;AAC3D,eAAO,IAAI,KAAK,QAAQ,EAAE,SAAS,aAAa,YAAY,GAAG,QAAQ,SAAS;AAAA,MAClF;AAAA,MACA,MAAM,KAAa,MAAc;AAC/B;AAAA,UACE,KAAK,KAAK,GAAG,EAAE,QAAQ;AAAA,UACvB,MAAM,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AAAA,QACnD;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,UAAQ,WAAW,CAAC,EACjB,MAAM,qBAAqB,MAAM,EAAE,EACnC,IAAI,kBAAkB,SAAS,EAAE,EACjC,KAAK,QAAQ;AAAA,IACZ,WAAW,KAAK,MAAM,OAAO,GAAG,IAAI,KAAK;AAAA,IACzC,YAAY;AAAA,IACZ,YAAY;AAAA,EACd,CAAC,EACA,KAAK,4BAA4B,EACjC,KAAK,6BAA6B,MAAM,GAAG,EAC3C,KAAK,2BAA2B,EAChC,MAAM,SAAS,IAAI;AAGtB,UAAQ,WAAW,CAAC,EACjB,MAAM,mBAAmB,EACzB,KAAK,SAAS,EAAE,WAAW,KAAK,MAAM,WAAW,GAAG,SAAS,QAAQ,CAAC,EACtE,KAAK,8BAA8B,MAAM,GAAG,EAC5C,KAAK,sBAAsB,EAC3B,MAAM,SAAS,IAAI;AAGtB,QAAM,KAAK,QAAQ,WAAW,CAAC,EAC5B,MAAM,iCAAiC,EACvC,KAAK,cAAc,EACnB,KAAK,aAAa;AACrB,KAAG,MAAM,SAAS,IAAI;AAEtB,QAAM,MAAM,QAAQ,WAAW,IAAI,EAAE,KAAK,qBAAqB,CAAC,GAAG,IAAI;AACvE,YAAU,KAAK,SAAS,WAAW,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;AACpE;AAAA,IACE,KAAK,SAAS,WAAW,aAAa,gBAAgB;AAAA,IACtD,IAAI,MAAM,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,GAAG,GAAG,SAAS,KAAK,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AAAA,EAC7E;AAGA,UAAQ,cAAc,CAAC,EACpB,MAAM,qBAAqB,EAC3B,KAAK,kCAAkC,EACvC,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EAAE,WAAW,KAAK,MAAM,gBAAgB,GAAG,YAAY,KAAK,YAAY,IAAI,CAAC,EAC1F,KAAK,wBAAwB,EAAE,gBAAgB,gBAAgB,CAAC,EAChE,MAAM,SAAS,IAAI;AAGtB,UAAQ,cAAc,CAAC,EACpB,MAAM,kCAAkC,EACxC,KAAK,4DAA4D,EACjE,KAAK,eAAe,EACpB,KAAK,6BAA6B,EAClC,MAAM,SAAS,IAAI;AAGtB,UAAQ,UAAU,EAAE,EAAE,MAAM,SAAS,EAAE,KAAK,sBAAsB,EAAE,MAAM,SAAS,IAAI;AAGvF,QAAM,QAAQ,KAAK,KAAK,WAAW,GAAG,KAAK,QAAQ,iBAAiB,GAAG,CAAC,QAAQ;AAChF,YAAU,OAAO,EAAE,WAAW,KAAK,CAAC;AACpC,UAAQ,gBAAgB,GAAG,GAAG,IAAI,QAAQ,EAAE,KAAK,sBAAsB,EAAE,MAAM,OAAO,IAAI;AAG1F,QAAM,MAAM,IAAI,KAAK,MAAM,KAAU;AACrC,QAAM,WAAW;AAAA,IACf,KAAK;AAAA,IACL,OAAO,IAAI,eAAe,CAAC;AAAA,IAC3B,OAAO,IAAI,YAAY,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AAAA,IAC7C,OAAO,IAAI,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AAAA,EAC1C;AACA,YAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AACvC,QAAM,UAAU,CAAC,QAAgB,QAAwB;AACvD,QAAI,IAAI,MAAM;AACd,UAAM,OAAO,CAAC,MAAc,YAA0B;AACpD,WAAK;AACL,aAAO,EAAE,WAAW,IAAI,KAAK,CAAC,EAAE,YAAY,GAAG,MAAM,QAAQ;AAAA,IAC/D;AACA,UAAM,OAAO,CAAC,KAAa,MACzB,KAAK,iBAAiB;AAAA,MACpB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,QAAQ,MAAM,IAAI,CAAC;AAAA,MAC5B,WAAW,KAAK,UAAU,EAAE,KAAK,SAAS,KAAK,eAAe,IAAK,CAAC;AAAA,IACtE,CAAC;AACH,WACE;AAAA,MACE,KAAK,gBAAgB;AAAA,QACnB,IAAI;AAAA,QACJ;AAAA,QACA,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV,CAAC;AAAA,MACD,KAAK,gBAAgB,EAAE,SAAS,MAAM,KAAK,OAAO,kBAAkB,CAAC;AAAA,MACrE,KAAK,iBAAiB;AAAA,QACpB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,CAAC,EAAE,MAAM,cAAc,MAAM,OAAO,CAAC;AAAA,MAChD,CAAC;AAAA,MACD,KAAK,iBAAiB,CAAC;AAAA,MACvB,KAAK,wBAAwB,CAAC;AAAA,MAC9B,KAAK,iBAAiB;AAAA,QACpB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,QAAQ,MAAM;AAAA,QACvB,OAAO,aAAa,KAAK,UAAU,OAAO,CAAC;AAAA,MAC7C,CAAC;AAAA,IACH,EACG,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAC5B,KAAK,IAAI,IAAI;AAAA,EAEpB;AACA;AAAA,IACE,KAAK,UAAU,kDAAkD;AAAA,IACjE,QAAQ,kBAAkB,IAAI;AAAA,EAChC;AACA;AAAA,IACE,KAAK,UAAU,gDAAgD;AAAA,IAC/D,QAAQ,gBAAgB,oBAAoB;AAAA,EAC9C;AAEA,SAAO,EAAE,gBAAgB,GAAG,aAAa,EAAE;AAC7C;","names":[]}
|