agentlock-shared 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/dist/__tests__/billing.test.d.ts +2 -0
  2. package/dist/__tests__/billing.test.d.ts.map +1 -0
  3. package/dist/__tests__/billing.test.js +31 -0
  4. package/dist/__tests__/billing.test.js.map +1 -0
  5. package/dist/__tests__/crypto.test.js +137 -47
  6. package/dist/__tests__/crypto.test.js.map +1 -1
  7. package/dist/__tests__/dns-pinning.test.d.ts +2 -0
  8. package/dist/__tests__/dns-pinning.test.d.ts.map +1 -0
  9. package/dist/__tests__/dns-pinning.test.js +33 -0
  10. package/dist/__tests__/dns-pinning.test.js.map +1 -0
  11. package/dist/__tests__/llm-classifier-cache-store.test.d.ts +2 -0
  12. package/dist/__tests__/llm-classifier-cache-store.test.d.ts.map +1 -0
  13. package/dist/__tests__/llm-classifier-cache-store.test.js +65 -0
  14. package/dist/__tests__/llm-classifier-cache-store.test.js.map +1 -0
  15. package/dist/__tests__/llm-classifier-cache.test.d.ts +2 -0
  16. package/dist/__tests__/llm-classifier-cache.test.d.ts.map +1 -0
  17. package/dist/__tests__/llm-classifier-cache.test.js +44 -0
  18. package/dist/__tests__/llm-classifier-cache.test.js.map +1 -0
  19. package/dist/__tests__/llm-classifier.test.d.ts +2 -0
  20. package/dist/__tests__/llm-classifier.test.d.ts.map +1 -0
  21. package/dist/__tests__/llm-classifier.test.js +167 -0
  22. package/dist/__tests__/llm-classifier.test.js.map +1 -0
  23. package/dist/__tests__/messaging.test.d.ts +2 -0
  24. package/dist/__tests__/messaging.test.d.ts.map +1 -0
  25. package/dist/__tests__/messaging.test.js +75 -0
  26. package/dist/__tests__/messaging.test.js.map +1 -0
  27. package/dist/__tests__/plans-classifier-limits.test.d.ts +2 -0
  28. package/dist/__tests__/plans-classifier-limits.test.d.ts.map +1 -0
  29. package/dist/__tests__/plans-classifier-limits.test.js +22 -0
  30. package/dist/__tests__/plans-classifier-limits.test.js.map +1 -0
  31. package/dist/__tests__/policy-category-floor.test.d.ts +2 -0
  32. package/dist/__tests__/policy-category-floor.test.d.ts.map +1 -0
  33. package/dist/__tests__/policy-category-floor.test.js +46 -0
  34. package/dist/__tests__/policy-category-floor.test.js.map +1 -0
  35. package/dist/__tests__/policy-claude-bash.test.d.ts +2 -0
  36. package/dist/__tests__/policy-claude-bash.test.d.ts.map +1 -0
  37. package/dist/__tests__/policy-claude-bash.test.js +401 -0
  38. package/dist/__tests__/policy-claude-bash.test.js.map +1 -0
  39. package/dist/__tests__/policy-llm-floor.test.d.ts +2 -0
  40. package/dist/__tests__/policy-llm-floor.test.d.ts.map +1 -0
  41. package/dist/__tests__/policy-llm-floor.test.js +107 -0
  42. package/dist/__tests__/policy-llm-floor.test.js.map +1 -0
  43. package/dist/__tests__/policy-ssh-e2e.test.d.ts +2 -0
  44. package/dist/__tests__/policy-ssh-e2e.test.d.ts.map +1 -0
  45. package/dist/__tests__/policy-ssh-e2e.test.js +89 -0
  46. package/dist/__tests__/policy-ssh-e2e.test.js.map +1 -0
  47. package/dist/__tests__/policy-ssh-sessions.test.d.ts +2 -0
  48. package/dist/__tests__/policy-ssh-sessions.test.d.ts.map +1 -0
  49. package/dist/__tests__/policy-ssh-sessions.test.js +139 -0
  50. package/dist/__tests__/policy-ssh-sessions.test.js.map +1 -0
  51. package/dist/__tests__/policy-ssh.test.d.ts +2 -0
  52. package/dist/__tests__/policy-ssh.test.d.ts.map +1 -0
  53. package/dist/__tests__/policy-ssh.test.js +180 -0
  54. package/dist/__tests__/policy-ssh.test.js.map +1 -0
  55. package/dist/__tests__/policy.test.js +522 -7
  56. package/dist/__tests__/policy.test.js.map +1 -1
  57. package/dist/__tests__/redact.test.js +76 -0
  58. package/dist/__tests__/redact.test.js.map +1 -1
  59. package/dist/__tests__/signing.test.js +89 -0
  60. package/dist/__tests__/signing.test.js.map +1 -1
  61. package/dist/__tests__/ssh-fingerprint.test.d.ts +2 -0
  62. package/dist/__tests__/ssh-fingerprint.test.d.ts.map +1 -0
  63. package/dist/__tests__/ssh-fingerprint.test.js +19 -0
  64. package/dist/__tests__/ssh-fingerprint.test.js.map +1 -0
  65. package/dist/__tests__/vpn-route.test.d.ts +2 -0
  66. package/dist/__tests__/vpn-route.test.d.ts.map +1 -0
  67. package/dist/__tests__/vpn-route.test.js +72 -0
  68. package/dist/__tests__/vpn-route.test.js.map +1 -0
  69. package/dist/__tests__/wireguard.test.d.ts +2 -0
  70. package/dist/__tests__/wireguard.test.d.ts.map +1 -0
  71. package/dist/__tests__/wireguard.test.js +114 -0
  72. package/dist/__tests__/wireguard.test.js.map +1 -0
  73. package/dist/billing.d.ts +12 -0
  74. package/dist/billing.d.ts.map +1 -0
  75. package/dist/billing.js +41 -0
  76. package/dist/billing.js.map +1 -0
  77. package/dist/crypto.d.ts +41 -0
  78. package/dist/crypto.d.ts.map +1 -1
  79. package/dist/crypto.js +208 -6
  80. package/dist/crypto.js.map +1 -1
  81. package/dist/dns-pinning.d.ts +28 -0
  82. package/dist/dns-pinning.d.ts.map +1 -0
  83. package/dist/dns-pinning.js +113 -0
  84. package/dist/dns-pinning.js.map +1 -0
  85. package/dist/index.d.ts +6 -0
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +9 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/llm-classifier-cache-store.d.ts +49 -0
  90. package/dist/llm-classifier-cache-store.d.ts.map +1 -0
  91. package/dist/llm-classifier-cache-store.js +63 -0
  92. package/dist/llm-classifier-cache-store.js.map +1 -0
  93. package/dist/llm-classifier-cache.d.ts +6 -0
  94. package/dist/llm-classifier-cache.d.ts.map +1 -0
  95. package/dist/llm-classifier-cache.js +52 -0
  96. package/dist/llm-classifier-cache.js.map +1 -0
  97. package/dist/llm-classifier.d.ts +29 -0
  98. package/dist/llm-classifier.d.ts.map +1 -0
  99. package/dist/llm-classifier.js +191 -0
  100. package/dist/llm-classifier.js.map +1 -0
  101. package/dist/observability.d.ts +36 -0
  102. package/dist/observability.d.ts.map +1 -0
  103. package/dist/observability.js +75 -0
  104. package/dist/observability.js.map +1 -0
  105. package/dist/plans.d.ts +21 -0
  106. package/dist/plans.d.ts.map +1 -1
  107. package/dist/plans.js +52 -14
  108. package/dist/plans.js.map +1 -1
  109. package/dist/policy.d.ts +173 -3
  110. package/dist/policy.d.ts.map +1 -1
  111. package/dist/policy.js +951 -58
  112. package/dist/policy.js.map +1 -1
  113. package/dist/redact.d.ts.map +1 -1
  114. package/dist/redact.js +104 -7
  115. package/dist/redact.js.map +1 -1
  116. package/dist/regex-safety.d.ts +21 -0
  117. package/dist/regex-safety.d.ts.map +1 -0
  118. package/dist/regex-safety.js +49 -0
  119. package/dist/regex-safety.js.map +1 -0
  120. package/dist/sanitize.d.ts +31 -0
  121. package/dist/sanitize.d.ts.map +1 -0
  122. package/dist/sanitize.js +54 -0
  123. package/dist/sanitize.js.map +1 -0
  124. package/dist/schemas.d.ts +267 -14
  125. package/dist/schemas.d.ts.map +1 -1
  126. package/dist/schemas.js +152 -10
  127. package/dist/schemas.js.map +1 -1
  128. package/dist/signing.d.ts +15 -0
  129. package/dist/signing.d.ts.map +1 -1
  130. package/dist/signing.js +53 -4
  131. package/dist/signing.js.map +1 -1
  132. package/dist/ssh-fingerprint.d.ts +10 -0
  133. package/dist/ssh-fingerprint.d.ts.map +1 -0
  134. package/dist/ssh-fingerprint.js +52 -0
  135. package/dist/ssh-fingerprint.js.map +1 -0
  136. package/dist/ssrf.d.ts +36 -0
  137. package/dist/ssrf.d.ts.map +1 -0
  138. package/dist/ssrf.js +140 -0
  139. package/dist/ssrf.js.map +1 -0
  140. package/dist/types.d.ts +131 -0
  141. package/dist/types.d.ts.map +1 -1
  142. package/dist/wireguard.d.ts +63 -0
  143. package/dist/wireguard.d.ts.map +1 -0
  144. package/dist/wireguard.js +226 -0
  145. package/dist/wireguard.js.map +1 -0
  146. package/package.json +42 -29
  147. package/.turbo/turbo-build.log +0 -4
  148. package/.turbo/turbo-test.log +0 -34
  149. package/dist/__tests__/content-crypto.test.d.ts +0 -2
  150. package/dist/__tests__/content-crypto.test.d.ts.map +0 -1
  151. package/dist/__tests__/content-crypto.test.js +0 -117
  152. package/dist/__tests__/content-crypto.test.js.map +0 -1
  153. package/dist/content-crypto.d.ts +0 -24
  154. package/dist/content-crypto.d.ts.map +0 -1
  155. package/dist/content-crypto.js +0 -58
  156. package/dist/content-crypto.js.map +0 -1
  157. package/src/__tests__/policy.test.ts +0 -88
  158. package/src/__tests__/redact.test.ts +0 -41
  159. package/src/__tests__/signing.test.ts +0 -55
  160. package/src/crypto.ts +0 -87
  161. package/src/index.ts +0 -8
  162. package/src/mcp-catalog.ts +0 -181
  163. package/src/plans.ts +0 -96
  164. package/src/policy.ts +0 -186
  165. package/src/redact.ts +0 -114
  166. package/src/schemas.ts +0 -53
  167. package/src/signing.ts +0 -120
  168. package/src/types.ts +0 -212
  169. package/test-gateway.mjs +0 -47
  170. package/tsconfig.json +0 -10
  171. package/vitest.config.ts +0 -8
package/dist/crypto.js CHANGED
@@ -6,17 +6,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generateKey = generateKey;
7
7
  exports.encrypt = encrypt;
8
8
  exports.decrypt = decrypt;
9
+ exports.envelopeEncrypt = envelopeEncrypt;
10
+ exports.envelopeDecrypt = envelopeDecrypt;
9
11
  exports.encryptDEK = encryptDEK;
10
12
  exports.decryptDEK = decryptDEK;
11
13
  exports.getMasterKey = getMasterKey;
14
+ exports.getPreviousMasterKeys = getPreviousMasterKeys;
15
+ exports.getPreviousMasterKey = getPreviousMasterKey;
16
+ exports.clearCachedKeys = clearCachedKeys;
12
17
  exports.generateMasterKey = generateMasterKey;
13
18
  exports.encryptCredential = encryptCredential;
14
19
  exports.decryptCredential = decryptCredential;
15
20
  const tweetnacl_1 = __importDefault(require("tweetnacl"));
16
21
  const tweetnacl_util_1 = require("tweetnacl-util");
22
+ /**
23
+ * Envelope encryption prefix. Data encrypted with envelopeEncrypt() is
24
+ * stored as a single string: "env1:<base64-wrappedDEK>:<base64-payload>".
25
+ * The decrypt() function detects this prefix and automatically unwraps
26
+ * using the DEK, maintaining backward compatibility with legacy data
27
+ * encrypted directly with MASTER_KEY.
28
+ */
29
+ const ENVELOPE_PREFIX = 'env1:';
17
30
  function generateKey() {
18
31
  return tweetnacl_1.default.randomBytes(32);
19
32
  }
33
+ /**
34
+ * Low-level symmetric encryption using a provided key.
35
+ * Callers that need envelope encryption (per-data DEK) should use
36
+ * envelopeEncrypt() instead.
37
+ */
20
38
  function encrypt(data, key) {
21
39
  const nonce = tweetnacl_1.default.randomBytes(tweetnacl_1.default.secretbox.nonceLength);
22
40
  const message = new TextEncoder().encode(data);
@@ -26,15 +44,117 @@ function encrypt(data, key) {
26
44
  combined.set(box, nonce.length);
27
45
  return (0, tweetnacl_util_1.encodeBase64)(combined);
28
46
  }
47
+ /**
48
+ * Low-level symmetric decryption. Handles both envelope-encrypted data
49
+ * (prefixed with "env1:") and legacy direct-key encrypted data.
50
+ *
51
+ * For envelope data: unwraps the per-data DEK using the master key,
52
+ * then decrypts the payload with the DEK.
53
+ *
54
+ * For legacy data: decrypts directly with the provided key, falling
55
+ * back to MASTER_KEY_PREVIOUS for key rotation support.
56
+ */
29
57
  function decrypt(encryptedData, key) {
58
+ // Detect envelope-encrypted format and handle transparently
59
+ if (encryptedData.startsWith(ENVELOPE_PREFIX)) {
60
+ return envelopeDecryptInternal(encryptedData, key);
61
+ }
62
+ // Legacy format: data encrypted directly with MASTER_KEY
30
63
  const combined = (0, tweetnacl_util_1.decodeBase64)(encryptedData);
31
64
  const nonce = combined.slice(0, tweetnacl_1.default.secretbox.nonceLength);
32
65
  const box = combined.slice(tweetnacl_1.default.secretbox.nonceLength);
33
66
  const message = tweetnacl_1.default.secretbox.open(box, nonce, key);
34
- if (!message) {
35
- throw new Error('Decryption failed: invalid key or corrupted data');
67
+ if (message) {
68
+ return new TextDecoder().decode(message);
69
+ }
70
+ // Try every retired master key (most-recent first). See
71
+ // `getPreviousMasterKeys()` for the rotation model.
72
+ for (const prevKey of getPreviousMasterKeys()) {
73
+ const attempt = tweetnacl_1.default.secretbox.open(box, nonce, prevKey);
74
+ if (attempt)
75
+ return new TextDecoder().decode(attempt);
76
+ }
77
+ throw new Error('Decryption failed: invalid key or corrupted data');
78
+ }
79
+ /**
80
+ * Encrypt arbitrary data using a per-data DEK (envelope encryption).
81
+ * Generates a fresh 256-bit DEK, encrypts the data with it, then wraps
82
+ * the DEK with the provided master key. Returns a single string in the
83
+ * format "env1:<wrappedDEK>:<encryptedPayload>" so it fits in a single
84
+ * database column and is backward-compatible with decrypt().
85
+ *
86
+ * Use this instead of encrypt() for all data at rest. Each encrypted
87
+ * value gets its own DEK, so compromising one ciphertext does not
88
+ * expose other data -- the attacker still needs the master key to
89
+ * unwrap any individual DEK.
90
+ */
91
+ function envelopeEncrypt(data, masterKey) {
92
+ const dek = generateKey();
93
+ try {
94
+ const wrappedDEK = encrypt((0, tweetnacl_util_1.encodeBase64)(dek), masterKey);
95
+ const encryptedPayload = encrypt(data, dek);
96
+ return `${ENVELOPE_PREFIX}${wrappedDEK}:${encryptedPayload}`;
97
+ }
98
+ finally {
99
+ // Zero DEK from memory after use (defense-in-depth against heap dumps)
100
+ dek.fill(0);
101
+ }
102
+ }
103
+ /**
104
+ * Decrypt data produced by envelopeEncrypt(). Expects the "env1:" prefixed
105
+ * format. For general use, call decrypt() which auto-detects the format.
106
+ */
107
+ function envelopeDecrypt(encryptedData, masterKey) {
108
+ if (!encryptedData.startsWith(ENVELOPE_PREFIX)) {
109
+ throw new Error('Not an envelope-encrypted value (missing env1: prefix)');
110
+ }
111
+ return envelopeDecryptInternal(encryptedData, masterKey);
112
+ }
113
+ /**
114
+ * Internal envelope decryption. Parses the "env1:wrappedDEK:payload" format,
115
+ * unwraps the DEK, and decrypts the payload.
116
+ */
117
+ function envelopeDecryptInternal(encryptedData, masterKey) {
118
+ // Format: "env1:<base64-wrappedDEK>:<base64-encryptedPayload>"
119
+ // The wrapped DEK itself is a base64 string produced by encrypt(), which
120
+ // can contain '+', '/', '=' but never ':'. So we split on ':' after the prefix.
121
+ const withoutPrefix = encryptedData.slice(ENVELOPE_PREFIX.length);
122
+ const separatorIndex = withoutPrefix.lastIndexOf(':');
123
+ if (separatorIndex <= 0) {
124
+ throw new Error('Invalid envelope format: missing DEK/payload separator');
125
+ }
126
+ const wrappedDEK = withoutPrefix.slice(0, separatorIndex);
127
+ const encryptedPayload = withoutPrefix.slice(separatorIndex + 1);
128
+ if (!wrappedDEK || !encryptedPayload) {
129
+ throw new Error('Invalid envelope format: empty DEK or payload');
130
+ }
131
+ // Unwrap the DEK using the master key (with key-rotation fallback)
132
+ let dekBase64;
133
+ try {
134
+ dekBase64 = decrypt(wrappedDEK, masterKey);
135
+ }
136
+ catch {
137
+ throw new Error('Envelope decryption failed: could not unwrap DEK');
138
+ }
139
+ const dek = (0, tweetnacl_util_1.decodeBase64)(dekBase64);
140
+ try {
141
+ // Decrypt the payload using the per-data DEK
142
+ // Use low-level decryption here (not decrypt()) to avoid infinite
143
+ // recursion on the envelope prefix check -- the inner payload is
144
+ // always in legacy format.
145
+ const combined = (0, tweetnacl_util_1.decodeBase64)(encryptedPayload);
146
+ const nonce = combined.slice(0, tweetnacl_1.default.secretbox.nonceLength);
147
+ const box = combined.slice(tweetnacl_1.default.secretbox.nonceLength);
148
+ const message = tweetnacl_1.default.secretbox.open(box, nonce, dek);
149
+ if (!message) {
150
+ throw new Error('Envelope decryption failed: payload decryption failed');
151
+ }
152
+ return new TextDecoder().decode(message);
153
+ }
154
+ finally {
155
+ // Zero DEK from memory after use
156
+ dek.fill(0);
36
157
  }
37
- return new TextDecoder().decode(message);
38
158
  }
39
159
  function encryptDEK(dek, masterKey) {
40
160
  return encrypt((0, tweetnacl_util_1.encodeBase64)(dek), masterKey);
@@ -46,14 +166,96 @@ function decryptDEK(encryptedDEK, masterKey) {
46
166
  // Cache the decoded master key to avoid creating multiple copies in memory.
47
167
  // A single copy is preferable to many short-lived copies scattered on the heap.
48
168
  let _cachedMasterKey = null;
169
+ /** nacl.secretbox requires a 32-byte key. A shorter key silently breaks
170
+ * crypto with a confusing error deep in the stack; a longer key indicates
171
+ * misconfiguration. Fail loudly at first access instead. */
172
+ const SECRETBOX_KEY_LENGTH = 32;
173
+ function validateMasterKey(raw, name) {
174
+ let decoded;
175
+ try {
176
+ decoded = (0, tweetnacl_util_1.decodeBase64)(raw);
177
+ }
178
+ catch {
179
+ throw new Error(`${name} is not valid base64`);
180
+ }
181
+ if (decoded.length !== SECRETBOX_KEY_LENGTH) {
182
+ throw new Error(`${name} must decode to exactly ${SECRETBOX_KEY_LENGTH} bytes (got ${decoded.length})`);
183
+ }
184
+ return decoded;
185
+ }
49
186
  function getMasterKey() {
50
187
  if (_cachedMasterKey)
51
- return _cachedMasterKey;
188
+ return _cachedMasterKey.slice();
52
189
  const key = process.env.MASTER_KEY;
53
190
  if (!key)
54
191
  throw new Error('MASTER_KEY environment variable not set');
55
- _cachedMasterKey = (0, tweetnacl_util_1.decodeBase64)(key);
56
- return _cachedMasterKey;
192
+ _cachedMasterKey = validateMasterKey(key, 'MASTER_KEY');
193
+ return _cachedMasterKey.slice();
194
+ }
195
+ // Support MASTER_KEY rotation with up to 5 previous keys. Operator sets
196
+ // MASTER_KEY = current key
197
+ // MASTER_KEY_PREVIOUS = most recent retired key (used during rotation #1)
198
+ // MASTER_KEY_PREVIOUS_2 = one-before-that (rotation #2)
199
+ // ...
200
+ // MASTER_KEY_PREVIOUS_5 = oldest retained key (rotation #5)
201
+ //
202
+ // Decryption walks the list top-down until one key succeeds; that lets an
203
+ // operator roll the key repeatedly (e.g. quarterly) without a big-bang
204
+ // re-encryption job in between. After all rows are re-encrypted with the
205
+ // new current key, unset the oldest MASTER_KEY_PREVIOUS_* env var.
206
+ //
207
+ // Each env var is validated + cached at first-use. The cache is cleared on
208
+ // shutdown so keys don't linger in the heap post-SIGTERM.
209
+ const MAX_PREVIOUS_KEYS = 5;
210
+ const _prevKeyCache = new Array(MAX_PREVIOUS_KEYS).fill(null);
211
+ function previousKeyEnvName(slot) {
212
+ // slot 0 → MASTER_KEY_PREVIOUS, slot 1 → MASTER_KEY_PREVIOUS_2, etc.
213
+ return slot === 0 ? 'MASTER_KEY_PREVIOUS' : `MASTER_KEY_PREVIOUS_${slot + 1}`;
214
+ }
215
+ function loadPreviousKeySlot(slot) {
216
+ const cached = _prevKeyCache[slot];
217
+ if (cached === 'unset')
218
+ return null;
219
+ if (cached instanceof Uint8Array)
220
+ return cached.slice();
221
+ const name = previousKeyEnvName(slot);
222
+ const raw = process.env[name];
223
+ if (!raw) {
224
+ _prevKeyCache[slot] = 'unset';
225
+ return null;
226
+ }
227
+ const key = validateMasterKey(raw, name);
228
+ _prevKeyCache[slot] = key;
229
+ return key.slice();
230
+ }
231
+ /** Return every retired key in rotation order (most-recent first). Used by
232
+ * the credential-decryption fallback path to try each until one succeeds.
233
+ */
234
+ function getPreviousMasterKeys() {
235
+ const out = [];
236
+ for (let i = 0; i < MAX_PREVIOUS_KEYS; i++) {
237
+ const k = loadPreviousKeySlot(i);
238
+ if (k)
239
+ out.push(k);
240
+ }
241
+ return out;
242
+ }
243
+ /** Back-compat: first previous key only. Prefer `getPreviousMasterKeys()`. */
244
+ function getPreviousMasterKey() {
245
+ return loadPreviousKeySlot(0);
246
+ }
247
+ /** Zero and release cached master keys. Call on graceful shutdown. */
248
+ function clearCachedKeys() {
249
+ if (_cachedMasterKey) {
250
+ _cachedMasterKey.fill(0);
251
+ _cachedMasterKey = null;
252
+ }
253
+ for (let i = 0; i < MAX_PREVIOUS_KEYS; i++) {
254
+ const k = _prevKeyCache[i];
255
+ if (k instanceof Uint8Array)
256
+ k.fill(0);
257
+ _prevKeyCache[i] = null;
258
+ }
57
259
  }
58
260
  function generateMasterKey() {
59
261
  return (0, tweetnacl_util_1.encodeBase64)(generateKey());
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type LookupOptions } from 'dns';
2
+ import type { SsrfResolver } from './ssrf.js';
3
+ /**
4
+ * DNS pinning for SSRF-safe server-side fetches. Canonical home for both the
5
+ * Runner connectors and the Web inline executor — previously this lived only
6
+ * in apps/runner and the inline path used unpinned global fetch, leaving a
7
+ * DNS-rebinding/TOCTOU window. Shared so there is one implementation.
8
+ *
9
+ * NOTE: this module imports Node's `dns` / `dns/promises` and is therefore
10
+ * server-only. Like `./ssrf.ts` it is NOT re-exported from `index.ts`; import
11
+ * it from the `agentlock-shared/dns-pinning` subpath in server-only code so
12
+ * Next.js client bundles never try to resolve the Node DNS imports.
13
+ */
14
+ type DnsLookupCb = (err: NodeJS.ErrnoException | null, address: string, family: number) => void;
15
+ export type PinnedLookup = ((hostname: string, options: LookupOptions, callback: DnsLookupCb) => void) & {
16
+ resolver: SsrfResolver;
17
+ };
18
+ export interface CreatePinnedLookupOptions {
19
+ servers?: string[];
20
+ preferFamily?: 4 | 6;
21
+ }
22
+ /**
23
+ * Cache the first resolved IP per hostname for the lifetime of the returned
24
+ * lookup function so validation and connect use the exact same DNS answer.
25
+ */
26
+ export declare function createPinnedLookup(opts?: CreatePinnedLookupOptions): PinnedLookup;
27
+ export {};
28
+ //# sourceMappingURL=dns-pinning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dns-pinning.d.ts","sourceRoot":"","sources":["../src/dns-pinning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,KAAK,CAAC;AAG9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C;;;;;;;;;;GAUG;AAEH,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAChG,MAAM,MAAM,YAAY,GAAG,CAAC,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,WAAW,KAClB,IAAI,CAAC,GAAG;IACX,QAAQ,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CACtB;AAiCD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,yBAA8B,GAAG,YAAY,CA6FrF"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPinnedLookup = createPinnedLookup;
4
+ const dns_1 = require("dns");
5
+ const promises_1 = require("dns/promises");
6
+ const net_1 = require("net");
7
+ const DNS_TIMEOUT_MS = 2_000;
8
+ function withTimeout(promise, ms) {
9
+ return Promise.race([
10
+ promise,
11
+ new Promise((_, reject) => {
12
+ setTimeout(() => reject(new Error(`DNS lookup timed out after ${ms}ms`)), ms);
13
+ }),
14
+ ]);
15
+ }
16
+ function createLookupError(hostname) {
17
+ const err = new Error(`DNS resolution failed for ${hostname}`);
18
+ err.code = 'ENOTFOUND';
19
+ return err;
20
+ }
21
+ function normalizeRequestedFamily(family) {
22
+ if (family === 'IPv4')
23
+ return 4;
24
+ if (family === 'IPv6')
25
+ return 6;
26
+ return typeof family === 'number' ? family : 0;
27
+ }
28
+ function familyOrder(preferred, requestedFamily = 0) {
29
+ if (requestedFamily === 4 || requestedFamily === 6) {
30
+ return [requestedFamily];
31
+ }
32
+ if (preferred === 6)
33
+ return [6, 4];
34
+ return [4, 6];
35
+ }
36
+ /**
37
+ * Cache the first resolved IP per hostname for the lifetime of the returned
38
+ * lookup function so validation and connect use the exact same DNS answer.
39
+ */
40
+ function createPinnedLookup(opts = {}) {
41
+ const cache = new Map();
42
+ const resolver = opts.servers && opts.servers.length > 0 ? new promises_1.Resolver() : null;
43
+ if (resolver && opts.servers) {
44
+ resolver.setServers(opts.servers);
45
+ }
46
+ const resolveOne = async (hostname, requestedFamily = 0) => {
47
+ const hit = cache.get(hostname);
48
+ if (hit)
49
+ return hit;
50
+ const literalFamily = (0, net_1.isIP)(hostname);
51
+ if (literalFamily) {
52
+ const literal = { address: hostname, family: literalFamily };
53
+ cache.set(hostname, literal);
54
+ return literal;
55
+ }
56
+ if (!resolver) {
57
+ for (const family of familyOrder(opts.preferFamily, requestedFamily)) {
58
+ try {
59
+ const resolved = await withTimeout(new Promise((resolve, reject) => {
60
+ (0, dns_1.lookup)(hostname, { family, all: false }, (err, address, resolvedFamily) => {
61
+ if (err)
62
+ return reject(err);
63
+ resolve({ address, family: resolvedFamily });
64
+ });
65
+ }), DNS_TIMEOUT_MS);
66
+ cache.set(hostname, resolved);
67
+ return resolved;
68
+ }
69
+ catch {
70
+ // Try the next family below.
71
+ }
72
+ }
73
+ throw createLookupError(hostname);
74
+ }
75
+ for (const family of familyOrder(opts.preferFamily, requestedFamily)) {
76
+ const answers = await withTimeout(family === 4
77
+ ? resolver.resolve4(hostname).catch(() => [])
78
+ : resolver.resolve6(hostname).catch(() => []), DNS_TIMEOUT_MS);
79
+ const address = answers[0];
80
+ if (address) {
81
+ const resolved = { address, family };
82
+ cache.set(hostname, resolved);
83
+ return resolved;
84
+ }
85
+ }
86
+ throw createLookupError(hostname);
87
+ };
88
+ const lookup = ((hostname, options, callback) => {
89
+ // Node >=20 / undici call a custom lookup with `{ all: true }` (Happy-Eyeballs
90
+ // auto-select-family) and then expect `callback(null, [{ address, family }])`.
91
+ // The legacy 3-arg `callback(null, address, family)` form silently fails there
92
+ // (undici throws "Invalid IP address: undefined"), which BOTH breaks name-based
93
+ // requests AND voids the DNS pin (the connect re-resolves). Honor both shapes.
94
+ const wantAll = options.all === true;
95
+ resolveOne(hostname, normalizeRequestedFamily(options.family))
96
+ .then(({ address, family }) => {
97
+ if (wantAll) {
98
+ callback(null, [{ address, family }]);
99
+ }
100
+ else {
101
+ callback(null, address, family);
102
+ }
103
+ })
104
+ .catch((err) => {
105
+ callback(err, '', 0);
106
+ });
107
+ });
108
+ lookup.resolver = (hostname) => resolveOne(hostname)
109
+ .then(({ address }) => [address])
110
+ .catch(() => []);
111
+ return lookup;
112
+ }
113
+ //# sourceMappingURL=dns-pinning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dns-pinning.js","sourceRoot":"","sources":["../src/dns-pinning.ts"],"names":[],"mappings":";;AAkEA,gDA6FC;AA/JD,6BAA8D;AAC9D,2CAAwC;AACxC,6BAA2B;AA6B3B,MAAM,cAAc,GAAG,KAAK,CAAC;AAE7B,SAAS,WAAW,CAAI,OAAmB,EAAE,EAAU;IACrD,OAAO,OAAO,CAAC,IAAI,CAAC;QAClB,OAAO;QACP,IAAI,OAAO,CAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;YAC3B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA8B,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChF,CAAC,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB;IACzC,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAA0B,CAAC;IACxF,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC;IACvB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,wBAAwB,CAAC,MAA2C;IAC3E,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,CAAC,CAAC;IAChC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,CAAC,CAAC;IAChC,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,WAAW,CAAC,SAAiB,EAAE,eAAe,GAAG,CAAC;IACzD,IAAI,eAAe,KAAK,CAAC,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,eAAwB,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB,CAAC,OAAkC,EAAE;IACrE,MAAM,KAAK,GAAG,IAAI,GAAG,EAA+C,CAAC;IACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,mBAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,IAAI,QAAQ,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7B,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,EACtB,QAAgB,EAChB,eAAe,GAAG,CAAC,EAC2B,EAAE;QAChD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;QAEpB,MAAM,aAAa,GAAG,IAAA,UAAI,EAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;YAC7D,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC7B,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,EAAE,CAAC;gBACrE,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,IAAI,OAAO,CAAsC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBACnE,IAAA,YAAS,EACP,QAAQ,EACR,EAAE,MAAM,EAAE,GAAG,EAAE,KAAc,EAAE,EAC/B,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE;4BAC/B,IAAI,GAAG;gCAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;4BAC5B,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;wBAC/C,CAAC,CACF,CAAC;oBACJ,CAAC,CAAC,EACF,cAAc,CACf,CAAC;oBACF,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;oBAC9B,OAAO,QAAQ,CAAC;gBAClB,CAAC;gBAAC,MAAM,CAAC;oBACP,6BAA6B;gBAC/B,CAAC;YACH,CAAC;YACD,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,EAAE,CAAC;YACrE,MAAM,OAAO,GAAG,MAAM,WAAW,CAC/B,MAAM,KAAK,CAAC;gBACV,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAc,CAAC;gBACzD,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAc,CAAC,EAC3D,cAAc,CACf,CAAC;YACF,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,QAAQ,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBACrC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBAC9B,OAAO,QAAQ,CAAC;YAClB,CAAC;QACH,CAAC;QAED,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,CAAC,QAAgB,EAAE,OAAsB,EAAE,QAAqB,EAAE,EAAE;QAClF,+EAA+E;QAC/E,+EAA+E;QAC/E,+EAA+E;QAC/E,gFAAgF;QAChF,+EAA+E;QAC/E,MAAM,OAAO,GAAI,OAA6C,CAAC,GAAG,KAAK,IAAI,CAAC;QAC5E,UAAU,CAAC,QAAQ,EAAE,wBAAwB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;aAC3D,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;YAC5B,IAAI,OAAO,EAAE,CAAC;gBACX,QAAwF,CACvF,IAAI,EACJ,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CACtB,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAClC,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,QAAQ,CAAC,GAA4B,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACP,CAAC,CAAiB,CAAC;IAEnB,MAAM,CAAC,QAAQ,GAAG,CAAC,QAAgB,EAAE,EAAE,CACrC,UAAU,CAAC,QAAQ,CAAC;SACjB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;SAChC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAErB,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -5,5 +5,11 @@ export * from './policy.js';
5
5
  export * from './redact.js';
6
6
  export * from './schemas.js';
7
7
  export * from './plans.js';
8
+ export * from './billing.js';
8
9
  export * from './mcp-catalog.js';
10
+ export * from './wireguard.js';
11
+ export * from './regex-safety.js';
12
+ export * from './sanitize.js';
13
+ export * from './observability.js';
14
+ export * from './ssh-fingerprint.js';
9
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAIlC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -21,5 +21,14 @@ __exportStar(require("./policy.js"), exports);
21
21
  __exportStar(require("./redact.js"), exports);
22
22
  __exportStar(require("./schemas.js"), exports);
23
23
  __exportStar(require("./plans.js"), exports);
24
+ __exportStar(require("./billing.js"), exports);
24
25
  __exportStar(require("./mcp-catalog.js"), exports);
26
+ __exportStar(require("./wireguard.js"), exports);
27
+ __exportStar(require("./regex-safety.js"), exports);
28
+ // ssrf.ts is intentionally NOT re-exported here — it imports Node's
29
+ // `dns/promises`, which Next.js client bundles can't resolve. Server-only
30
+ // callers should import from the `agentlock-shared/ssrf` subpath directly.
31
+ __exportStar(require("./sanitize.js"), exports);
32
+ __exportStar(require("./observability.js"), exports);
33
+ __exportStar(require("./ssh-fingerprint.js"), exports);
25
34
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,8CAA4B;AAC5B,+CAA6B;AAC7B,8CAA4B;AAC5B,8CAA4B;AAC5B,+CAA6B;AAC7B,6CAA2B;AAC3B,mDAAiC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,8CAA4B;AAC5B,+CAA6B;AAC7B,8CAA4B;AAC5B,8CAA4B;AAC5B,+CAA6B;AAC7B,6CAA2B;AAC3B,+CAA6B;AAC7B,mDAAiC;AACjC,iDAA+B;AAC/B,oDAAkC;AAClC,oEAAoE;AACpE,0EAA0E;AAC1E,2EAA2E;AAC3E,gDAA8B;AAC9B,qDAAmC;AACnC,uDAAqC"}
@@ -0,0 +1,49 @@
1
+ import type { LLMClassification } from './types.js';
2
+ /**
3
+ * Storage abstraction for cached LLM classifications. Two implementations
4
+ * exist:
5
+ *
6
+ * 1. {@link InMemoryCacheStore} — the default, used in tests and as a
7
+ * fallback when no durable store has been injected. Survives as long
8
+ * as the process is alive, but not across cold starts or scale-out.
9
+ * 2. A Supabase-backed adapter (see `apps/web/src/lib/classifier-cache-store.ts`)
10
+ * that is wired in at module load time by the gateway handler.
11
+ *
12
+ * Privacy guarantee (see `buildCacheKey` in llm-classifier-cache.ts): the
13
+ * cache key is a SHA-256 hash of (tool_name + payload shape). Neither the
14
+ * key nor the stored classification contains actual payload values.
15
+ *
16
+ * All methods MUST swallow infrastructure errors and return null (for
17
+ * `get`) or resolve silently (for `set`). The classifier treats a cache
18
+ * error identically to a cache miss, and the LLM will be called again —
19
+ * this is the same graceful-degradation pattern used by `classifyWithLLM`
20
+ * when the LLM itself errors or times out.
21
+ */
22
+ export interface CacheStore {
23
+ get(key: string): Promise<(Omit<LLMClassification, 'cached'> & {
24
+ cached: true;
25
+ }) | null>;
26
+ set(key: string, classification: Omit<LLMClassification, 'cached'>): Promise<void>;
27
+ }
28
+ export interface InMemoryCacheStoreOptions {
29
+ /** Time-to-live for cache entries. Defaults to 24 hours. */
30
+ ttlMs?: number;
31
+ }
32
+ export declare class InMemoryCacheStore implements CacheStore {
33
+ private readonly map;
34
+ private readonly ttlMs;
35
+ constructor(options?: InMemoryCacheStoreOptions);
36
+ get(key: string): Promise<(Omit<LLMClassification, 'cached'> & {
37
+ cached: true;
38
+ }) | null>;
39
+ set(key: string, classification: Omit<LLMClassification, 'cached'>): Promise<void>;
40
+ /** Current entry count. Intended for tests and metrics. */
41
+ size(): number;
42
+ /** Empty the cache. Intended for tests and manual ops. */
43
+ clear(): void;
44
+ }
45
+ export declare function setClassifierCacheStore(store: CacheStore): void;
46
+ export declare function getClassifierCacheStore(): CacheStore;
47
+ /** Test-only: drop any injected store and clear the default in-memory store. */
48
+ export declare function resetClassifierCacheStoreForTest(): void;
49
+ //# sourceMappingURL=llm-classifier-cache-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-classifier-cache-store.d.ts","sourceRoot":"","sources":["../src/llm-classifier-cache-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,GAAG;QAAE,MAAM,EAAE,IAAI,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACzF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpF;AAWD,MAAM,WAAW,yBAAyB;IACxC,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,qBAAa,kBAAmB,YAAW,UAAU;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoC;IACxD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,OAAO,GAAE,yBAA8B;IAI7C,GAAG,CACP,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,GAAG;QAAE,MAAM,EAAE,IAAI,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IAUnE,GAAG,CACP,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,GAChD,OAAO,CAAC,IAAI,CAAC;IAIhB,2DAA2D;IAC3D,IAAI,IAAI,MAAM;IAId,0DAA0D;IAC1D,KAAK,IAAI,IAAI;CAGd;AAaD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAE/D;AAED,wBAAgB,uBAAuB,IAAI,UAAU,CAIpD;AAED,gFAAgF;AAChF,wBAAgB,gCAAgC,IAAI,IAAI,CAIvD"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemoryCacheStore = void 0;
4
+ exports.setClassifierCacheStore = setClassifierCacheStore;
5
+ exports.getClassifierCacheStore = getClassifierCacheStore;
6
+ exports.resetClassifierCacheStoreForTest = resetClassifierCacheStoreForTest;
7
+ const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
8
+ class InMemoryCacheStore {
9
+ map = new Map();
10
+ ttlMs;
11
+ constructor(options = {}) {
12
+ this.ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
13
+ }
14
+ async get(key) {
15
+ const entry = this.map.get(key);
16
+ if (!entry)
17
+ return null;
18
+ if (Date.now() - entry.cachedAt >= this.ttlMs) {
19
+ this.map.delete(key);
20
+ return null;
21
+ }
22
+ return { ...entry.classification, cached: true };
23
+ }
24
+ async set(key, classification) {
25
+ this.map.set(key, { classification, cachedAt: Date.now() });
26
+ }
27
+ /** Current entry count. Intended for tests and metrics. */
28
+ size() {
29
+ return this.map.size;
30
+ }
31
+ /** Empty the cache. Intended for tests and manual ops. */
32
+ clear() {
33
+ this.map.clear();
34
+ }
35
+ }
36
+ exports.InMemoryCacheStore = InMemoryCacheStore;
37
+ // ---------------------------------------------------------------------------
38
+ // Module-level singleton
39
+ // ---------------------------------------------------------------------------
40
+ // The gateway handler calls `setClassifierCacheStore(new SupabaseCacheStore())`
41
+ // at module load. Tests use `resetClassifierCacheStoreForTest()` to go back
42
+ // to a fresh InMemoryCacheStore. Anything that does not inject a store gets
43
+ // the default in-memory implementation.
44
+ let injected = null;
45
+ let defaultStore = null;
46
+ function setClassifierCacheStore(store) {
47
+ injected = store;
48
+ }
49
+ function getClassifierCacheStore() {
50
+ if (injected)
51
+ return injected;
52
+ if (!defaultStore)
53
+ defaultStore = new InMemoryCacheStore();
54
+ return defaultStore;
55
+ }
56
+ /** Test-only: drop any injected store and clear the default in-memory store. */
57
+ function resetClassifierCacheStoreForTest() {
58
+ injected = null;
59
+ if (defaultStore)
60
+ defaultStore.clear();
61
+ defaultStore = null;
62
+ }
63
+ //# sourceMappingURL=llm-classifier-cache-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-classifier-cache-store.js","sourceRoot":"","sources":["../src/llm-classifier-cache-store.ts"],"names":[],"mappings":";;;AA4FA,0DAEC;AAED,0DAIC;AAGD,4EAIC;AAlED,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE3C,MAAa,kBAAkB;IACZ,GAAG,GAAG,IAAI,GAAG,EAAyB,CAAC;IACvC,KAAK,CAAS;IAE/B,YAAY,UAAqC,EAAE;QACjD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAW;QAEX,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9C,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,GAAG,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAW,EACX,cAAiD;QAEjD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,2DAA2D;IAC3D,IAAI;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,0DAA0D;IAC1D,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;CACF;AApCD,gDAoCC;AAED,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAC9E,gFAAgF;AAChF,4EAA4E;AAC5E,4EAA4E;AAC5E,wCAAwC;AAExC,IAAI,QAAQ,GAAsB,IAAI,CAAC;AACvC,IAAI,YAAY,GAA8B,IAAI,CAAC;AAEnD,SAAgB,uBAAuB,CAAC,KAAiB;IACvD,QAAQ,GAAG,KAAK,CAAC;AACnB,CAAC;AAED,SAAgB,uBAAuB;IACrC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,CAAC,YAAY;QAAE,YAAY,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAC3D,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,gFAAgF;AAChF,SAAgB,gCAAgC;IAC9C,QAAQ,GAAG,IAAI,CAAC;IAChB,IAAI,YAAY;QAAE,YAAY,CAAC,KAAK,EAAE,CAAC;IACvC,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Compute a stable cache key from the (lowercased) tool name and the
3
+ * payload shape. Output is a 32-char hex digest.
4
+ */
5
+ export declare function buildCacheKey(tool: string, payload: Record<string, unknown>): string;
6
+ //# sourceMappingURL=llm-classifier-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-classifier-cache.d.ts","sourceRoot":"","sources":["../src/llm-classifier-cache.ts"],"names":[],"mappings":"AAwCA;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAGR"}