agentlock-shared 0.2.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 (169) 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__/dns-pinning.test.d.ts +2 -0
  6. package/dist/__tests__/dns-pinning.test.d.ts.map +1 -0
  7. package/dist/__tests__/dns-pinning.test.js +33 -0
  8. package/dist/__tests__/dns-pinning.test.js.map +1 -0
  9. package/dist/__tests__/llm-classifier-cache-store.test.d.ts +2 -0
  10. package/dist/__tests__/llm-classifier-cache-store.test.d.ts.map +1 -0
  11. package/dist/__tests__/llm-classifier-cache-store.test.js +65 -0
  12. package/dist/__tests__/llm-classifier-cache-store.test.js.map +1 -0
  13. package/dist/__tests__/llm-classifier-cache.test.d.ts +2 -0
  14. package/dist/__tests__/llm-classifier-cache.test.d.ts.map +1 -0
  15. package/dist/__tests__/llm-classifier-cache.test.js +44 -0
  16. package/dist/__tests__/llm-classifier-cache.test.js.map +1 -0
  17. package/dist/__tests__/llm-classifier.test.d.ts +2 -0
  18. package/dist/__tests__/llm-classifier.test.d.ts.map +1 -0
  19. package/dist/__tests__/llm-classifier.test.js +167 -0
  20. package/dist/__tests__/llm-classifier.test.js.map +1 -0
  21. package/dist/__tests__/plans-classifier-limits.test.d.ts +2 -0
  22. package/dist/__tests__/plans-classifier-limits.test.d.ts.map +1 -0
  23. package/dist/__tests__/plans-classifier-limits.test.js +22 -0
  24. package/dist/__tests__/plans-classifier-limits.test.js.map +1 -0
  25. package/dist/__tests__/policy-category-floor.test.d.ts +2 -0
  26. package/dist/__tests__/policy-category-floor.test.d.ts.map +1 -0
  27. package/dist/__tests__/policy-category-floor.test.js +46 -0
  28. package/dist/__tests__/policy-category-floor.test.js.map +1 -0
  29. package/dist/__tests__/policy-claude-bash.test.d.ts +2 -0
  30. package/dist/__tests__/policy-claude-bash.test.d.ts.map +1 -0
  31. package/dist/__tests__/policy-claude-bash.test.js +401 -0
  32. package/dist/__tests__/policy-claude-bash.test.js.map +1 -0
  33. package/dist/__tests__/policy-llm-floor.test.d.ts +2 -0
  34. package/dist/__tests__/policy-llm-floor.test.d.ts.map +1 -0
  35. package/dist/__tests__/policy-llm-floor.test.js +107 -0
  36. package/dist/__tests__/policy-llm-floor.test.js.map +1 -0
  37. package/dist/__tests__/policy-ssh-e2e.test.d.ts +2 -0
  38. package/dist/__tests__/policy-ssh-e2e.test.d.ts.map +1 -0
  39. package/dist/__tests__/policy-ssh-e2e.test.js +89 -0
  40. package/dist/__tests__/policy-ssh-e2e.test.js.map +1 -0
  41. package/dist/__tests__/policy-ssh-sessions.test.d.ts +2 -0
  42. package/dist/__tests__/policy-ssh-sessions.test.d.ts.map +1 -0
  43. package/dist/__tests__/policy-ssh-sessions.test.js +139 -0
  44. package/dist/__tests__/policy-ssh-sessions.test.js.map +1 -0
  45. package/dist/__tests__/policy-ssh.test.d.ts +2 -0
  46. package/dist/__tests__/policy-ssh.test.d.ts.map +1 -0
  47. package/dist/__tests__/policy-ssh.test.js +180 -0
  48. package/dist/__tests__/policy-ssh.test.js.map +1 -0
  49. package/dist/__tests__/policy.test.js +400 -2
  50. package/dist/__tests__/policy.test.js.map +1 -1
  51. package/dist/__tests__/redact.test.js +76 -0
  52. package/dist/__tests__/redact.test.js.map +1 -1
  53. package/dist/__tests__/signing.test.js +89 -0
  54. package/dist/__tests__/signing.test.js.map +1 -1
  55. package/dist/__tests__/ssh-fingerprint.test.d.ts +2 -0
  56. package/dist/__tests__/ssh-fingerprint.test.d.ts.map +1 -0
  57. package/dist/__tests__/ssh-fingerprint.test.js +19 -0
  58. package/dist/__tests__/ssh-fingerprint.test.js.map +1 -0
  59. package/dist/__tests__/vpn-route.test.d.ts +2 -0
  60. package/dist/__tests__/vpn-route.test.d.ts.map +1 -0
  61. package/dist/__tests__/vpn-route.test.js +72 -0
  62. package/dist/__tests__/vpn-route.test.js.map +1 -0
  63. package/dist/__tests__/wireguard.test.d.ts +2 -0
  64. package/dist/__tests__/wireguard.test.d.ts.map +1 -0
  65. package/dist/__tests__/wireguard.test.js +114 -0
  66. package/dist/__tests__/wireguard.test.js.map +1 -0
  67. package/dist/billing.d.ts +12 -0
  68. package/dist/billing.d.ts.map +1 -0
  69. package/dist/billing.js +41 -0
  70. package/dist/billing.js.map +1 -0
  71. package/dist/crypto.d.ts +5 -0
  72. package/dist/crypto.d.ts.map +1 -1
  73. package/dist/crypto.js +80 -23
  74. package/dist/crypto.js.map +1 -1
  75. package/dist/dns-pinning.d.ts +28 -0
  76. package/dist/dns-pinning.d.ts.map +1 -0
  77. package/dist/dns-pinning.js +113 -0
  78. package/dist/dns-pinning.js.map +1 -0
  79. package/dist/index.d.ts +6 -0
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +9 -0
  82. package/dist/index.js.map +1 -1
  83. package/dist/llm-classifier-cache-store.d.ts +49 -0
  84. package/dist/llm-classifier-cache-store.d.ts.map +1 -0
  85. package/dist/llm-classifier-cache-store.js +63 -0
  86. package/dist/llm-classifier-cache-store.js.map +1 -0
  87. package/dist/llm-classifier-cache.d.ts +6 -0
  88. package/dist/llm-classifier-cache.d.ts.map +1 -0
  89. package/dist/llm-classifier-cache.js +52 -0
  90. package/dist/llm-classifier-cache.js.map +1 -0
  91. package/dist/llm-classifier.d.ts +29 -0
  92. package/dist/llm-classifier.d.ts.map +1 -0
  93. package/dist/llm-classifier.js +191 -0
  94. package/dist/llm-classifier.js.map +1 -0
  95. package/dist/observability.d.ts +36 -0
  96. package/dist/observability.d.ts.map +1 -0
  97. package/dist/observability.js +75 -0
  98. package/dist/observability.js.map +1 -0
  99. package/dist/plans.d.ts +17 -0
  100. package/dist/plans.d.ts.map +1 -1
  101. package/dist/plans.js +36 -14
  102. package/dist/plans.js.map +1 -1
  103. package/dist/policy.d.ts +173 -3
  104. package/dist/policy.d.ts.map +1 -1
  105. package/dist/policy.js +910 -42
  106. package/dist/policy.js.map +1 -1
  107. package/dist/redact.d.ts.map +1 -1
  108. package/dist/redact.js +83 -3
  109. package/dist/redact.js.map +1 -1
  110. package/dist/regex-safety.d.ts +21 -0
  111. package/dist/regex-safety.d.ts.map +1 -0
  112. package/dist/regex-safety.js +49 -0
  113. package/dist/regex-safety.js.map +1 -0
  114. package/dist/sanitize.d.ts +31 -0
  115. package/dist/sanitize.d.ts.map +1 -0
  116. package/dist/sanitize.js +54 -0
  117. package/dist/sanitize.js.map +1 -0
  118. package/dist/schemas.d.ts +202 -10
  119. package/dist/schemas.d.ts.map +1 -1
  120. package/dist/schemas.js +91 -1
  121. package/dist/schemas.js.map +1 -1
  122. package/dist/signing.d.ts +15 -0
  123. package/dist/signing.d.ts.map +1 -1
  124. package/dist/signing.js +53 -4
  125. package/dist/signing.js.map +1 -1
  126. package/dist/ssh-fingerprint.d.ts +10 -0
  127. package/dist/ssh-fingerprint.d.ts.map +1 -0
  128. package/dist/ssh-fingerprint.js +52 -0
  129. package/dist/ssh-fingerprint.js.map +1 -0
  130. package/dist/ssrf.d.ts +36 -0
  131. package/dist/ssrf.d.ts.map +1 -0
  132. package/dist/ssrf.js +140 -0
  133. package/dist/ssrf.js.map +1 -0
  134. package/dist/types.d.ts +130 -0
  135. package/dist/types.d.ts.map +1 -1
  136. package/dist/wireguard.d.ts +63 -0
  137. package/dist/wireguard.d.ts.map +1 -0
  138. package/dist/wireguard.js +226 -0
  139. package/dist/wireguard.js.map +1 -0
  140. package/package.json +42 -29
  141. package/.turbo/turbo-build.log +0 -4
  142. package/.turbo/turbo-test.log +0 -76
  143. package/dist/__tests__/content-crypto.test.d.ts +0 -2
  144. package/dist/__tests__/content-crypto.test.d.ts.map +0 -1
  145. package/dist/__tests__/content-crypto.test.js +0 -117
  146. package/dist/__tests__/content-crypto.test.js.map +0 -1
  147. package/dist/__tests__/signing.test (# Edit conflict 2026-04-01 z3etfmC #).js +0 -51
  148. package/dist/__tests__/signing.test.js (# Edit conflict 2026-04-01 4rndy9C #).map +0 -1
  149. package/dist/content-crypto.d.ts +0 -24
  150. package/dist/content-crypto.d.ts.map +0 -1
  151. package/dist/content-crypto.js +0 -58
  152. package/dist/content-crypto.js.map +0 -1
  153. package/src/__tests__/crypto.test.ts +0 -169
  154. package/src/__tests__/messaging.test.ts +0 -83
  155. package/src/__tests__/policy.test.ts +0 -222
  156. package/src/__tests__/redact.test.ts +0 -41
  157. package/src/__tests__/signing.test.ts +0 -55
  158. package/src/crypto.ts +0 -235
  159. package/src/index.ts +0 -8
  160. package/src/mcp-catalog.ts +0 -181
  161. package/src/plans.ts +0 -116
  162. package/src/policy.ts +0 -216
  163. package/src/redact.ts +0 -131
  164. package/src/schemas.ts +0 -121
  165. package/src/signing.ts +0 -120
  166. package/src/types.ts +0 -213
  167. package/test-gateway.mjs +0 -47
  168. package/tsconfig.json +0 -10
  169. package/vitest.config.ts +0 -8
package/src/crypto.ts DELETED
@@ -1,235 +0,0 @@
1
- import nacl from 'tweetnacl';
2
- import { encodeBase64, decodeBase64 } from 'tweetnacl-util';
3
-
4
- /**
5
- * Envelope encryption prefix. Data encrypted with envelopeEncrypt() is
6
- * stored as a single string: "env1:<base64-wrappedDEK>:<base64-payload>".
7
- * The decrypt() function detects this prefix and automatically unwraps
8
- * using the DEK, maintaining backward compatibility with legacy data
9
- * encrypted directly with MASTER_KEY.
10
- */
11
- const ENVELOPE_PREFIX = 'env1:';
12
-
13
- export function generateKey(): Uint8Array {
14
- return nacl.randomBytes(32);
15
- }
16
-
17
- /**
18
- * Low-level symmetric encryption using a provided key.
19
- * Callers that need envelope encryption (per-data DEK) should use
20
- * envelopeEncrypt() instead.
21
- */
22
- export function encrypt(data: string, key: Uint8Array): string {
23
- const nonce = nacl.randomBytes(nacl.secretbox.nonceLength);
24
- const message = new TextEncoder().encode(data);
25
- const box = nacl.secretbox(message, nonce, key);
26
-
27
- const combined = new Uint8Array(nonce.length + box.length);
28
- combined.set(nonce);
29
- combined.set(box, nonce.length);
30
-
31
- return encodeBase64(combined);
32
- }
33
-
34
- /**
35
- * Low-level symmetric decryption. Handles both envelope-encrypted data
36
- * (prefixed with "env1:") and legacy direct-key encrypted data.
37
- *
38
- * For envelope data: unwraps the per-data DEK using the master key,
39
- * then decrypts the payload with the DEK.
40
- *
41
- * For legacy data: decrypts directly with the provided key, falling
42
- * back to MASTER_KEY_PREVIOUS for key rotation support.
43
- */
44
- export function decrypt(encryptedData: string, key: Uint8Array): string {
45
- // Detect envelope-encrypted format and handle transparently
46
- if (encryptedData.startsWith(ENVELOPE_PREFIX)) {
47
- return envelopeDecryptInternal(encryptedData, key);
48
- }
49
-
50
- // Legacy format: data encrypted directly with MASTER_KEY
51
- const combined = decodeBase64(encryptedData);
52
- const nonce = combined.slice(0, nacl.secretbox.nonceLength);
53
- const box = combined.slice(nacl.secretbox.nonceLength);
54
-
55
- const message = nacl.secretbox.open(box, nonce, key);
56
- if (message) {
57
- return new TextDecoder().decode(message);
58
- }
59
-
60
- // Try previous master key for rotation support
61
- const prevKey = getPreviousMasterKey();
62
- if (prevKey) {
63
- const message2 = nacl.secretbox.open(box, nonce, prevKey);
64
- if (message2) {
65
- return new TextDecoder().decode(message2);
66
- }
67
- }
68
-
69
- throw new Error('Decryption failed: invalid key or corrupted data');
70
- }
71
-
72
- /**
73
- * Encrypt arbitrary data using a per-data DEK (envelope encryption).
74
- * Generates a fresh 256-bit DEK, encrypts the data with it, then wraps
75
- * the DEK with the provided master key. Returns a single string in the
76
- * format "env1:<wrappedDEK>:<encryptedPayload>" so it fits in a single
77
- * database column and is backward-compatible with decrypt().
78
- *
79
- * Use this instead of encrypt() for all data at rest. Each encrypted
80
- * value gets its own DEK, so compromising one ciphertext does not
81
- * expose other data -- the attacker still needs the master key to
82
- * unwrap any individual DEK.
83
- */
84
- export function envelopeEncrypt(data: string, masterKey: Uint8Array): string {
85
- const dek = generateKey();
86
- try {
87
- const wrappedDEK = encrypt(encodeBase64(dek), masterKey);
88
- const encryptedPayload = encrypt(data, dek);
89
- return `${ENVELOPE_PREFIX}${wrappedDEK}:${encryptedPayload}`;
90
- } finally {
91
- // Zero DEK from memory after use (defense-in-depth against heap dumps)
92
- dek.fill(0);
93
- }
94
- }
95
-
96
- /**
97
- * Decrypt data produced by envelopeEncrypt(). Expects the "env1:" prefixed
98
- * format. For general use, call decrypt() which auto-detects the format.
99
- */
100
- export function envelopeDecrypt(encryptedData: string, masterKey: Uint8Array): string {
101
- if (!encryptedData.startsWith(ENVELOPE_PREFIX)) {
102
- throw new Error('Not an envelope-encrypted value (missing env1: prefix)');
103
- }
104
- return envelopeDecryptInternal(encryptedData, masterKey);
105
- }
106
-
107
- /**
108
- * Internal envelope decryption. Parses the "env1:wrappedDEK:payload" format,
109
- * unwraps the DEK, and decrypts the payload.
110
- */
111
- function envelopeDecryptInternal(encryptedData: string, masterKey: Uint8Array): string {
112
- // Format: "env1:<base64-wrappedDEK>:<base64-encryptedPayload>"
113
- // The wrapped DEK itself is a base64 string produced by encrypt(), which
114
- // can contain '+', '/', '=' but never ':'. So we split on ':' after the prefix.
115
- const withoutPrefix = encryptedData.slice(ENVELOPE_PREFIX.length);
116
- const separatorIndex = withoutPrefix.lastIndexOf(':');
117
- if (separatorIndex <= 0) {
118
- throw new Error('Invalid envelope format: missing DEK/payload separator');
119
- }
120
- const wrappedDEK = withoutPrefix.slice(0, separatorIndex);
121
- const encryptedPayload = withoutPrefix.slice(separatorIndex + 1);
122
-
123
- if (!wrappedDEK || !encryptedPayload) {
124
- throw new Error('Invalid envelope format: empty DEK or payload');
125
- }
126
-
127
- // Unwrap the DEK using the master key (with key-rotation fallback)
128
- let dekBase64: string;
129
- try {
130
- dekBase64 = decrypt(wrappedDEK, masterKey);
131
- } catch {
132
- throw new Error('Envelope decryption failed: could not unwrap DEK');
133
- }
134
-
135
- const dek = decodeBase64(dekBase64);
136
- try {
137
- // Decrypt the payload using the per-data DEK
138
- // Use low-level decryption here (not decrypt()) to avoid infinite
139
- // recursion on the envelope prefix check -- the inner payload is
140
- // always in legacy format.
141
- const combined = decodeBase64(encryptedPayload);
142
- const nonce = combined.slice(0, nacl.secretbox.nonceLength);
143
- const box = combined.slice(nacl.secretbox.nonceLength);
144
- const message = nacl.secretbox.open(box, nonce, dek);
145
- if (!message) {
146
- throw new Error('Envelope decryption failed: payload decryption failed');
147
- }
148
- return new TextDecoder().decode(message);
149
- } finally {
150
- // Zero DEK from memory after use
151
- dek.fill(0);
152
- }
153
- }
154
-
155
- export function encryptDEK(dek: Uint8Array, masterKey: Uint8Array): string {
156
- return encrypt(encodeBase64(dek), masterKey);
157
- }
158
-
159
- export function decryptDEK(encryptedDEK: string, masterKey: Uint8Array): Uint8Array {
160
- const dekBase64 = decrypt(encryptedDEK, masterKey);
161
- return decodeBase64(dekBase64);
162
- }
163
-
164
- // Cache the decoded master key to avoid creating multiple copies in memory.
165
- // A single copy is preferable to many short-lived copies scattered on the heap.
166
- let _cachedMasterKey: Uint8Array | null = null;
167
-
168
- export function getMasterKey(): Uint8Array {
169
- if (_cachedMasterKey) return _cachedMasterKey.slice();
170
- const key = process.env.MASTER_KEY;
171
- if (!key) throw new Error('MASTER_KEY environment variable not set');
172
- _cachedMasterKey = decodeBase64(key);
173
- return _cachedMasterKey.slice();
174
- }
175
-
176
- // Support MASTER_KEY rotation: try previous key when current key fails
177
- let _cachedPrevKey: Uint8Array | null = null;
178
- let _prevKeyChecked = false;
179
-
180
- export function getPreviousMasterKey(): Uint8Array | null {
181
- if (_prevKeyChecked) return _cachedPrevKey ? _cachedPrevKey.slice() : null;
182
- _prevKeyChecked = true;
183
- const key = process.env.MASTER_KEY_PREVIOUS;
184
- if (!key) return null;
185
- _cachedPrevKey = decodeBase64(key);
186
- return _cachedPrevKey.slice();
187
- }
188
-
189
- /** Zero and release cached master keys. Call on graceful shutdown. */
190
- export function clearCachedKeys(): void {
191
- if (_cachedMasterKey) {
192
- _cachedMasterKey.fill(0);
193
- _cachedMasterKey = null;
194
- }
195
- if (_cachedPrevKey) {
196
- _cachedPrevKey.fill(0);
197
- _cachedPrevKey = null;
198
- }
199
- _prevKeyChecked = false;
200
- }
201
-
202
- export function generateMasterKey(): string {
203
- return encodeBase64(generateKey());
204
- }
205
-
206
- export function encryptCredential(
207
- payload: Record<string, unknown>,
208
- masterKey: Uint8Array
209
- ): { encryptedDEK: string; encryptedPayload: string } {
210
- const dek = generateKey();
211
- try {
212
- const encryptedDEK = encryptDEK(dek, masterKey);
213
- const encryptedPayload = encrypt(JSON.stringify(payload), dek);
214
- return { encryptedDEK, encryptedPayload };
215
- } finally {
216
- // Zero DEK from memory after use (defense-in-depth against heap dumps)
217
- dek.fill(0);
218
- }
219
- }
220
-
221
- export function decryptCredential(
222
- encryptedDEK: string,
223
- encryptedPayload: string,
224
- masterKey: Uint8Array
225
- ): Record<string, unknown> {
226
- const dek = decryptDEK(encryptedDEK, masterKey);
227
- try {
228
- const json = decrypt(encryptedPayload, dek);
229
- return JSON.parse(json);
230
- } finally {
231
- // Best-effort: zero DEK from memory to minimize exposure window.
232
- // Not guaranteed by JS runtime, but reduces risk of heap-dump leaks.
233
- dek.fill(0);
234
- }
235
- }
package/src/index.ts DELETED
@@ -1,8 +0,0 @@
1
- export * from './types.js';
2
- export * from './crypto.js';
3
- export * from './signing.js';
4
- export * from './policy.js';
5
- export * from './redact.js';
6
- export * from './schemas.js';
7
- export * from './plans.js';
8
- export * from './mcp-catalog.js';
@@ -1,181 +0,0 @@
1
- export interface McpServerTemplate {
2
- id: string;
3
- name: string;
4
- description: string;
5
- serverUrl: string;
6
- authType: 'bearer' | 'none';
7
- authLabel?: string;
8
- authPlaceholder?: string;
9
- authHelpUrl?: string;
10
- category: string;
11
- }
12
-
13
- export const MCP_CATALOG: McpServerTemplate[] = [
14
- // --- Developer Tools ---
15
- {
16
- id: 'github',
17
- name: 'GitHub',
18
- description: 'Manage repos, issues, PRs, and code search',
19
-
20
- serverUrl: 'https://api.githubcopilot.com/mcp/',
21
- authType: 'bearer',
22
- authLabel: 'Personal Access Token',
23
- authPlaceholder: 'ghp_...',
24
- authHelpUrl: 'https://github.com/settings/tokens',
25
- category: 'Developer Tools',
26
- },
27
- {
28
- id: 'gitlab',
29
- name: 'GitLab',
30
- description: 'Projects, merge requests, pipelines, and issues',
31
-
32
- serverUrl: 'https://gitlab.com/-/mcp',
33
- authType: 'bearer',
34
- authLabel: 'Personal Access Token',
35
- authPlaceholder: 'glpat-...',
36
- authHelpUrl: 'https://gitlab.com/-/user_settings/personal_access_tokens',
37
- category: 'Developer Tools',
38
- },
39
- {
40
- id: 'linear',
41
- name: 'Linear',
42
- description: 'Issue tracking, projects, and team workflows',
43
-
44
- serverUrl: 'https://mcp.linear.app/sse',
45
- authType: 'bearer',
46
- authLabel: 'API Key',
47
- authPlaceholder: 'lin_api_...',
48
- authHelpUrl: 'https://linear.app/settings/api',
49
- category: 'Developer Tools',
50
- },
51
- {
52
- id: 'sentry',
53
- name: 'Sentry',
54
- description: 'Error tracking, performance monitoring, and alerts',
55
-
56
- serverUrl: 'https://mcp.sentry.dev/sse',
57
- authType: 'bearer',
58
- authLabel: 'Auth Token',
59
- authPlaceholder: 'sntrys_...',
60
- authHelpUrl: 'https://sentry.io/settings/account/api/auth-tokens/',
61
- category: 'Developer Tools',
62
- },
63
-
64
- // --- Cloud & Infrastructure ---
65
- {
66
- id: 'cloudflare',
67
- name: 'Cloudflare',
68
- description: 'Workers, KV, D1, R2, and DNS management',
69
- serverUrl: 'https://workers-mcp.cloudflare.com/mcp',
70
- authType: 'bearer',
71
- authLabel: 'API Token',
72
- authPlaceholder: '',
73
- authHelpUrl: 'https://dash.cloudflare.com/profile/api-tokens',
74
- category: 'Cloud & Infrastructure',
75
- },
76
-
77
- // --- Communication ---
78
- {
79
- id: 'slack',
80
- name: 'Slack',
81
- description: 'Send messages, manage channels, and search conversations',
82
- serverUrl: 'https://slack.com/api/mcp',
83
- authType: 'bearer',
84
- authLabel: 'Bot Token',
85
- authPlaceholder: 'xoxb-...',
86
- authHelpUrl: 'https://api.slack.com/apps',
87
- category: 'Communication',
88
- },
89
-
90
- // --- Search & Data ---
91
- {
92
- id: 'brave-search',
93
- name: 'Brave Search',
94
- description: 'Web search, news, and local results',
95
- serverUrl: 'https://mcp.brave.com/sse',
96
- authType: 'bearer',
97
- authLabel: 'API Key',
98
- authPlaceholder: 'BSA...',
99
- authHelpUrl: 'https://brave.com/search/api/',
100
- category: 'Search & Data',
101
- },
102
-
103
- // --- Productivity ---
104
- {
105
- id: 'notion',
106
- name: 'Notion',
107
- description: 'Pages, databases, and workspace content',
108
- serverUrl: 'https://mcp.notion.so/sse',
109
- authType: 'bearer',
110
- authLabel: 'Integration Token',
111
- authPlaceholder: 'ntn_...',
112
- authHelpUrl: 'https://www.notion.so/my-integrations',
113
- category: 'Productivity',
114
- },
115
-
116
- // --- AI & LLMs ---
117
- {
118
- id: 'context7',
119
- name: 'Context7',
120
- description: 'Up-to-date documentation and code examples for any library',
121
- serverUrl: 'https://mcp.context7.com/sse',
122
- authType: 'none',
123
- category: 'AI & LLMs',
124
- },
125
-
126
- // --- Databases ---
127
- {
128
- id: 'supabase',
129
- name: 'Supabase',
130
- description: 'Database queries, auth, storage, and edge functions',
131
- serverUrl: 'https://mcp.supabase.com/sse',
132
- authType: 'bearer',
133
- authLabel: 'Access Token',
134
- authPlaceholder: 'sbp_...',
135
- authHelpUrl: 'https://supabase.com/dashboard/account/tokens',
136
- category: 'Databases',
137
- },
138
- {
139
- id: 'neon',
140
- name: 'Neon',
141
- description: 'Serverless Postgres — branches, queries, and management',
142
- serverUrl: 'https://mcp.neon.tech/sse',
143
- authType: 'bearer',
144
- authLabel: 'API Key',
145
- authPlaceholder: '',
146
- authHelpUrl: 'https://console.neon.tech/app/settings/api-keys',
147
- category: 'Databases',
148
- },
149
-
150
- // --- Payments ---
151
- {
152
- id: 'stripe',
153
- name: 'Stripe',
154
- description: 'Payments, subscriptions, customers, and invoices',
155
- serverUrl: 'https://mcp.stripe.com/sse',
156
- authType: 'bearer',
157
- authLabel: 'Secret Key',
158
- authPlaceholder: 'sk_...',
159
- authHelpUrl: 'https://dashboard.stripe.com/apikeys',
160
- category: 'Payments',
161
- },
162
-
163
- // --- Monitoring ---
164
- {
165
- id: 'grafana',
166
- name: 'Grafana',
167
- description: 'Dashboards, alerts, and observability data',
168
- serverUrl: 'https://mcp.grafana.com/sse',
169
- authType: 'bearer',
170
- authLabel: 'Service Account Token',
171
- authPlaceholder: 'glsa_...',
172
- authHelpUrl: 'https://grafana.com/docs/grafana/latest/administration/service-accounts/',
173
- category: 'Monitoring',
174
- },
175
- ];
176
-
177
- export const MCP_CATEGORIES = [...new Set(MCP_CATALOG.map((s) => s.category))];
178
-
179
- export function getMcpTemplate(id: string): McpServerTemplate | undefined {
180
- return MCP_CATALOG.find((s) => s.id === id);
181
- }
package/src/plans.ts DELETED
@@ -1,116 +0,0 @@
1
- export type PlanId = 'free' | 'pro' | 'team';
2
-
3
- export interface PlanLimits {
4
- actionsPerMonth: number;
5
- agents: number;
6
- credentials: number;
7
- members: number;
8
- policies: number;
9
- timelineHistoryDays: number;
10
- undoEnabled: boolean;
11
- browserSessions: number;
12
- messagesPerMonth: number;
13
- messageHistoryDays: number;
14
- threadsPerAgent: number;
15
- }
16
-
17
- export interface PlanDefinition extends PlanLimits {
18
- id: PlanId;
19
- name: string;
20
- monthlyPrice: number; // USD cents
21
- yearlyPrice: number; // USD cents (total per year)
22
- stripePriceMonthly: string;
23
- stripePriceYearly: string;
24
- }
25
-
26
- export const PLANS: Record<PlanId, PlanDefinition> = {
27
- free: {
28
- id: 'free',
29
- name: 'Free',
30
- monthlyPrice: 0,
31
- yearlyPrice: 0,
32
- stripePriceMonthly: '',
33
- stripePriceYearly: '',
34
- actionsPerMonth: 1000,
35
- agents: 3,
36
- credentials: 2,
37
- members: 1,
38
- policies: 3,
39
- timelineHistoryDays: 14,
40
- undoEnabled: false,
41
- browserSessions: 0,
42
- messagesPerMonth: 100,
43
- messageHistoryDays: 7,
44
- threadsPerAgent: 5,
45
- },
46
- pro: {
47
- id: 'pro',
48
- name: 'Pro',
49
- monthlyPrice: 900,
50
- yearlyPrice: 7900,
51
- stripePriceMonthly: 'price_1T6b3m2NRlIkxMrBZ9bmEDYE',
52
- stripePriceYearly: 'price_1T6b3m2NRlIkxMrBo2yx01sJ',
53
- actionsPerMonth: Infinity,
54
- agents: 10,
55
- credentials: 25,
56
- members: 5,
57
- policies: 10,
58
- timelineHistoryDays: 90,
59
- undoEnabled: true,
60
- browserSessions: 2,
61
- messagesPerMonth: 5000,
62
- messageHistoryDays: 30,
63
- threadsPerAgent: 50,
64
- },
65
- team: {
66
- id: 'team',
67
- name: 'Team',
68
- monthlyPrice: 4900,
69
- yearlyPrice: 41000,
70
- stripePriceMonthly: 'price_1T6b3n2NRlIkxMrBstkfVECC',
71
- stripePriceYearly: 'price_1T6b3o2NRlIkxMrBzHoQKPjz',
72
- actionsPerMonth: Infinity,
73
- agents: 50,
74
- credentials: Infinity,
75
- members: 25,
76
- policies: 50,
77
- timelineHistoryDays: 365,
78
- undoEnabled: true,
79
- browserSessions: 5,
80
- messagesPerMonth: Infinity,
81
- messageHistoryDays: 90,
82
- threadsPerAgent: Infinity,
83
- },
84
- } as const;
85
-
86
- export function getPlanLimits(plan: string): PlanLimits {
87
- const def = PLANS[plan as PlanId];
88
- if (!def) return PLANS.free;
89
- return {
90
- actionsPerMonth: def.actionsPerMonth,
91
- agents: def.agents,
92
- credentials: def.credentials,
93
- members: def.members,
94
- policies: def.policies,
95
- timelineHistoryDays: def.timelineHistoryDays,
96
- undoEnabled: def.undoEnabled,
97
- browserSessions: def.browserSessions,
98
- messagesPerMonth: def.messagesPerMonth,
99
- messageHistoryDays: def.messageHistoryDays,
100
- threadsPerAgent: def.threadsPerAgent,
101
- };
102
- }
103
-
104
- export function canUndo(plan: string): boolean {
105
- return getPlanLimits(plan).undoEnabled;
106
- }
107
-
108
- /** Map a Stripe price ID back to a plan ID */
109
- export function planFromPriceId(priceId: string): PlanId | null {
110
- for (const plan of Object.values(PLANS)) {
111
- if (plan.stripePriceMonthly === priceId || plan.stripePriceYearly === priceId) {
112
- return plan.id;
113
- }
114
- }
115
- return null;
116
- }