@kya-os/create-mcpi-app 1.7.38-canary.1 → 1.7.38

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 (67) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test$colon$coverage.log +755 -0
  3. package/.turbo/turbo-test.log +200 -0
  4. package/dist/helpers/fetch-cloudflare-mcpi-template.d.ts.map +1 -1
  5. package/dist/helpers/fetch-cloudflare-mcpi-template.js +43 -912
  6. package/dist/helpers/fetch-cloudflare-mcpi-template.js.map +1 -1
  7. package/dist/utils/fetch-remote-config.d.ts.map +1 -1
  8. package/dist/utils/fetch-remote-config.js +2 -2
  9. package/dist/utils/fetch-remote-config.js.map +1 -1
  10. package/package/package.json +77 -0
  11. package/package.json +1 -1
  12. package/ARCHITECTURE_ANALYSIS.md +0 -392
  13. package/CHANGELOG.md +0 -372
  14. package/DEPRECATION_WARNINGS_ANALYSIS.md +0 -192
  15. package/IMPLEMENTATION_SUMMARY.md +0 -108
  16. package/REMEDIATION_PLAN.md +0 -99
  17. package/dist/.tsbuildinfo +0 -1
  18. package/scripts/prepare-pack.js +0 -47
  19. package/scripts/validate-no-workspace.js +0 -79
  20. package/src/__tests__/cloudflare-template.test.ts +0 -490
  21. package/src/__tests__/helpers/fetch-cloudflare-mcpi-template.test.ts +0 -337
  22. package/src/__tests__/helpers/generate-config.test.ts +0 -312
  23. package/src/__tests__/helpers/generate-identity.test.ts +0 -271
  24. package/src/__tests__/helpers/install.test.ts +0 -370
  25. package/src/__tests__/helpers/validate-project-structure.test.ts +0 -467
  26. package/src/__tests__.bak/regression.test.ts +0 -434
  27. package/src/effects/index.ts +0 -80
  28. package/src/helpers/__tests__/config-builder.spec.ts +0 -231
  29. package/src/helpers/apply-identity-preset.ts +0 -209
  30. package/src/helpers/config-builder.ts +0 -165
  31. package/src/helpers/copy-template.ts +0 -11
  32. package/src/helpers/create.ts +0 -239
  33. package/src/helpers/fetch-cloudflare-mcpi-template.ts +0 -2393
  34. package/src/helpers/fetch-cloudflare-template.ts +0 -361
  35. package/src/helpers/fetch-mcpi-template.ts +0 -236
  36. package/src/helpers/fetch-xmcp-template.ts +0 -153
  37. package/src/helpers/generate-config.ts +0 -118
  38. package/src/helpers/generate-identity.ts +0 -163
  39. package/src/helpers/identity-manager.ts +0 -186
  40. package/src/helpers/install.ts +0 -79
  41. package/src/helpers/rename.ts +0 -17
  42. package/src/helpers/validate-project-structure.ts +0 -127
  43. package/src/index.ts +0 -520
  44. package/src/utils/__tests__/fetch-remote-config.test.ts +0 -271
  45. package/src/utils/check-node.ts +0 -17
  46. package/src/utils/fetch-remote-config.ts +0 -179
  47. package/src/utils/is-folder-empty.ts +0 -60
  48. package/src/utils/validate-project-name.ts +0 -132
  49. package/test-cloudflare/README.md +0 -164
  50. package/test-cloudflare/package.json +0 -28
  51. package/test-cloudflare/src/index.ts +0 -341
  52. package/test-cloudflare/src/tools/greet.ts +0 -19
  53. package/test-cloudflare/tests/cache-invalidation.test.ts +0 -410
  54. package/test-cloudflare/tests/cors-security.test.ts +0 -349
  55. package/test-cloudflare/tests/delegation.test.ts +0 -335
  56. package/test-cloudflare/tests/do-routing.test.ts +0 -314
  57. package/test-cloudflare/tests/integration.test.ts +0 -205
  58. package/test-cloudflare/tests/session-management.test.ts +0 -359
  59. package/test-cloudflare/tsconfig.json +0 -16
  60. package/test-cloudflare/vitest.config.ts +0 -9
  61. package/test-cloudflare/wrangler.toml +0 -37
  62. package/test-node/README.md +0 -44
  63. package/test-node/package.json +0 -23
  64. package/test-node/src/tools/greet.ts +0 -25
  65. package/test-node/xmcp.config.ts +0 -20
  66. package/tsconfig.json +0 -26
  67. package/vitest.config.ts +0 -14
@@ -1,410 +0,0 @@
1
- import { describe, test, expect, vi, beforeEach } from 'vitest';
2
-
3
- /**
4
- * Cache Invalidation Tests
5
- * Tests various cache invalidation strategies for security and performance
6
- */
7
- describe('Cache Invalidation Strategies', () => {
8
-
9
- // Mock KV namespaces
10
- const mockKV = {
11
- get: vi.fn(),
12
- put: vi.fn(),
13
- delete: vi.fn(),
14
- list: vi.fn()
15
- };
16
-
17
- beforeEach(() => {
18
- vi.clearAllMocks();
19
- global.fetch = vi.fn();
20
- });
21
-
22
- describe('Short TTL Strategy (Recommended)', () => {
23
- test('should use 5-minute TTL for delegation cache', async () => {
24
- const token = 'test-token';
25
- const CACHE_TTL = 5 * 60; // 5 minutes
26
-
27
- // Store with short TTL
28
- await mockKV.put(
29
- `delegation:${token}`,
30
- 'valid',
31
- { expirationTtl: CACHE_TTL }
32
- );
33
-
34
- expect(mockKV.put).toHaveBeenCalledWith(
35
- `delegation:${token}`,
36
- 'valid',
37
- { expirationTtl: 300 } // 5 minutes in seconds
38
- );
39
- });
40
-
41
- test('should use 1-minute TTL for verification cache', async () => {
42
- const token = 'verified-token';
43
- const VERIFICATION_TTL = 60; // 1 minute
44
-
45
- // Cache verification result
46
- await mockKV.put(
47
- `verified:${token.substring(0, 16)}`,
48
- '1',
49
- { expirationTtl: VERIFICATION_TTL }
50
- );
51
-
52
- expect(mockKV.put).toHaveBeenCalledWith(
53
- expect.stringContaining('verified:'),
54
- '1',
55
- { expirationTtl: 60 }
56
- );
57
- });
58
-
59
- test('should re-verify after TTL expiration', async () => {
60
- const token = 'expired-cache-token';
61
- const cacheKey = `verified:${token.substring(0, 16)}`;
62
-
63
- // First check - cache miss
64
- mockKV.get.mockResolvedValueOnce(null);
65
-
66
- // Verify with API
67
- global.fetch = vi.fn().mockResolvedValueOnce({
68
- ok: true
69
- });
70
-
71
- // Actually call the API
72
- await global.fetch('https://test-api/verify');
73
-
74
- // Cache the result
75
- await mockKV.put(cacheKey, '1', { expirationTtl: 60 });
76
-
77
- // After TTL expires, should re-verify
78
- mockKV.get.mockResolvedValueOnce(null); // Cache expired
79
-
80
- // Call API again
81
- await global.fetch('https://test-api/verify');
82
-
83
- // Should have been called twice
84
- expect(global.fetch).toHaveBeenCalledTimes(2);
85
- });
86
-
87
- test('should handle cache miss gracefully', async () => {
88
- const token = 'no-cache-token';
89
-
90
- // Cache miss
91
- mockKV.get.mockResolvedValueOnce(null);
92
-
93
- // Should proceed with verification
94
- global.fetch = vi.fn().mockResolvedValueOnce({
95
- ok: true
96
- });
97
-
98
- // Should not throw
99
- expect(() => mockKV.get(`verified:${token.substring(0, 16)}`)).not.toThrow();
100
- });
101
- });
102
-
103
- describe('Immediate Invalidation on Revocation', () => {
104
- test('should invalidate all caches when delegation revoked', async () => {
105
- const sessionId = 'revoked-session';
106
- const agentDid = 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK';
107
- const token = 'revoked-token';
108
-
109
- const keysToDelete = [
110
- `session:${sessionId}`,
111
- `agent:${agentDid}:delegation`,
112
- `verified:${token.substring(0, 16)}`
113
- ];
114
-
115
- // Perform invalidation
116
- for (const key of keysToDelete) {
117
- await mockKV.delete(key);
118
- }
119
-
120
- // Verify all caches cleared
121
- expect(mockKV.delete).toHaveBeenCalledTimes(3);
122
- expect(mockKV.delete).toHaveBeenCalledWith(`session:${sessionId}`);
123
- expect(mockKV.delete).toHaveBeenCalledWith(`agent:${agentDid}:delegation`);
124
- expect(mockKV.delete).toHaveBeenCalledWith(`verified:${token.substring(0, 16)}`);
125
- });
126
-
127
- test('should handle partial invalidation failures', async () => {
128
- const sessionId = 'partial-fail-session';
129
- const token = 'partial-fail-token';
130
-
131
- // Some deletions fail
132
- mockKV.delete
133
- .mockResolvedValueOnce(undefined) // Success
134
- .mockRejectedValueOnce(new Error('KV error')) // Fail
135
- .mockResolvedValueOnce(undefined); // Success
136
-
137
- const deletions = [
138
- mockKV.delete(`session:${sessionId}`),
139
- mockKV.delete(`agent:test:delegation`).catch(() => null),
140
- mockKV.delete(`verified:${token.substring(0, 16)}`)
141
- ];
142
-
143
- const results = await Promise.allSettled(deletions);
144
-
145
- // Should not throw, handle failures gracefully
146
- expect(results[0].status).toBe('fulfilled');
147
- expect(results[1].status).toBe('fulfilled'); // Caught error
148
- expect(results[2].status).toBe('fulfilled');
149
- });
150
-
151
- test('should invalidate when API returns 401/403', async () => {
152
- const token = 'unauthorized-token';
153
-
154
- // API returns unauthorized
155
- global.fetch = vi.fn().mockResolvedValueOnce({
156
- ok: false,
157
- status: 401
158
- });
159
-
160
- // Should trigger invalidation
161
- await mockKV.delete(`verified:${token.substring(0, 16)}`);
162
- await mockKV.delete(`delegation:${token}`);
163
-
164
- expect(mockKV.delete).toHaveBeenCalledTimes(2);
165
- });
166
- });
167
-
168
- describe('Batch Invalidation', () => {
169
- test('should invalidate all tokens for a user', async () => {
170
- const userId = 'user-123';
171
-
172
- // List all user's tokens
173
- mockKV.list.mockResolvedValueOnce({
174
- keys: [
175
- { name: `user:${userId}:delegation:1` },
176
- { name: `user:${userId}:delegation:2` },
177
- { name: `user:${userId}:delegation:3` }
178
- ]
179
- });
180
-
181
- // Get list of keys
182
- const result = await mockKV.list({ prefix: `user:${userId}:` });
183
-
184
- // Delete all
185
- const deletions = result.keys.map(key =>
186
- mockKV.delete(key.name)
187
- );
188
-
189
- await Promise.all(deletions);
190
-
191
- expect(mockKV.delete).toHaveBeenCalledTimes(3);
192
- });
193
-
194
- test('should invalidate all tokens for an agent', async () => {
195
- const agentDid = 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK';
196
-
197
- // List all agent's tokens
198
- mockKV.list.mockResolvedValueOnce({
199
- keys: [
200
- { name: `agent:${agentDid}:delegation` },
201
- { name: `agent:${agentDid}:session:1` },
202
- { name: `agent:${agentDid}:session:2` }
203
- ]
204
- });
205
-
206
- const result = await mockKV.list({ prefix: `agent:${agentDid}:` });
207
-
208
- // Delete all
209
- const deletions = result.keys.map(key =>
210
- mockKV.delete(key.name)
211
- );
212
-
213
- await Promise.all(deletions);
214
-
215
- expect(mockKV.delete).toHaveBeenCalledTimes(3);
216
- });
217
- });
218
-
219
- describe('Performance Optimization', () => {
220
- test('should batch verification requests', async () => {
221
- const tokens = ['token1', 'token2', 'token3'];
222
-
223
- // Check cache for all tokens
224
- mockKV.get
225
- .mockResolvedValueOnce(null) // token1 miss
226
- .mockResolvedValueOnce('1') // token2 hit
227
- .mockResolvedValueOnce(null); // token3 miss
228
-
229
- // Only verify uncached tokens
230
- const toVerify = ['token1', 'token3'];
231
-
232
- // Batch API call
233
- global.fetch = vi.fn().mockResolvedValueOnce({
234
- ok: true,
235
- json: async () => ({
236
- results: {
237
- token1: { valid: true },
238
- token3: { valid: false }
239
- }
240
- })
241
- });
242
-
243
- // Make the batch API call
244
- await global.fetch('https://test-api/batch-verify', {
245
- method: 'POST',
246
- body: JSON.stringify({ tokens: toVerify })
247
- });
248
-
249
- // Should have made single API call for multiple tokens
250
- expect(global.fetch).toHaveBeenCalledTimes(1);
251
- });
252
-
253
- test('should use stale-while-revalidate pattern', async () => {
254
- const token = 'stale-token';
255
- const cacheKey = `verified:${token.substring(0, 16)}`;
256
-
257
- // Stale-while-revalidate pattern test
258
- // This test verifies that:
259
- // 1. Cached value is returned immediately (fast response)
260
- // 2. Background revalidation happens asynchronously
261
-
262
- // Simulate getting a cached value
263
- const staleCachedValue = '1';
264
-
265
- // In a real implementation:
266
- // - Check cache first, return immediately if found (stale but fast)
267
- // - Trigger background revalidation without blocking
268
- // - User experiences fast response with eventual consistency
269
-
270
- expect(staleCachedValue).toBe('1'); // Immediate return
271
-
272
- // Background revalidation would happen asynchronously
273
- const backgroundRevalidation = async () => {
274
- await mockKV.put(cacheKey, '1', { expirationTtl: 60 });
275
- };
276
-
277
- // Verify pattern is conceptually sound
278
- expect(typeof backgroundRevalidation).toBe('function');
279
- });
280
- });
281
-
282
- describe('Cache Consistency', () => {
283
- test('should maintain consistency across DO instances', async () => {
284
- const token = 'consistent-token';
285
-
286
- // Instance 1 invalidates
287
- await mockKV.delete(`verified:${token.substring(0, 16)}`);
288
-
289
- // Instance 2 should see invalidation
290
- mockKV.get.mockResolvedValueOnce(null);
291
-
292
- const result = await mockKV.get(`verified:${token.substring(0, 16)}`);
293
- expect(result).toBeNull();
294
- });
295
-
296
- test('should handle race conditions during invalidation', async () => {
297
- const token = 'race-condition-token';
298
-
299
- // Simulate concurrent operations
300
- const operations = [
301
- mockKV.put(`verified:${token.substring(0, 16)}`, '1', { expirationTtl: 60 }),
302
- mockKV.delete(`verified:${token.substring(0, 16)}`),
303
- mockKV.get(`verified:${token.substring(0, 16)}`)
304
- ];
305
-
306
- // All operations should complete without error
307
- const results = await Promise.allSettled(operations);
308
-
309
- expect(results.every(r => r.status === 'fulfilled')).toBe(true);
310
- });
311
- });
312
-
313
- describe('Monitoring and Metrics', () => {
314
- test('should track cache hit rate', () => {
315
- const metrics = {
316
- cacheHits: 0,
317
- cacheMisses: 0,
318
- get hitRate() {
319
- const total = this.cacheHits + this.cacheMisses;
320
- return total > 0 ? this.cacheHits / total : 0;
321
- }
322
- };
323
-
324
- // Simulate cache operations
325
- metrics.cacheHits += 8;
326
- metrics.cacheMisses += 2;
327
-
328
- expect(metrics.hitRate).toBe(0.8); // 80% hit rate
329
- });
330
-
331
- test('should track invalidation frequency', () => {
332
- const metrics = {
333
- invalidations: [],
334
- addInvalidation(reason: string) {
335
- this.invalidations.push({
336
- timestamp: Date.now(),
337
- reason
338
- });
339
- },
340
- getRate(windowMs: number) {
341
- const now = Date.now();
342
- const recent = this.invalidations.filter(
343
- i => i.timestamp > now - windowMs
344
- );
345
- return recent.length;
346
- }
347
- };
348
-
349
- // Track invalidations
350
- metrics.addInvalidation('revocation');
351
- metrics.addInvalidation('expiration');
352
- metrics.addInvalidation('manual');
353
-
354
- // Check rate in last minute
355
- const ratePerMinute = metrics.getRate(60000);
356
- expect(ratePerMinute).toBe(3);
357
- });
358
- });
359
-
360
- describe('Edge Cases', () => {
361
- test('should handle KV storage limits', async () => {
362
- // KV has 25 MiB value limit
363
- // Use a smaller token for testing (1 MiB instead of 26 MiB to avoid test output issues)
364
- const largeToken = 'x'.repeat(1024 * 1024); // 1 MiB
365
-
366
- try {
367
- await mockKV.put('large-key', largeToken);
368
- } catch (error: any) {
369
- expect(error.message).toContain('too large');
370
- }
371
-
372
- // Should use token hash instead
373
- const tokenHash = 'hash-of-large-token';
374
- await mockKV.put(`verified:${tokenHash.substring(0, 16)}`, '1');
375
-
376
- expect(mockKV.put).toHaveBeenCalledWith(
377
- expect.stringContaining('verified:'),
378
- '1'
379
- // No third argument expected
380
- );
381
- });
382
-
383
- test('should handle KV operation failures', async () => {
384
- // KV operations can fail
385
- mockKV.get.mockRejectedValueOnce(new Error('KV unavailable'));
386
-
387
- try {
388
- await mockKV.get('test-key');
389
- } catch (error: any) {
390
- expect(error.message).toBe('KV unavailable');
391
- }
392
-
393
- // Should fail open (allow request) in read failures
394
- // Should fail closed (deny request) in write failures
395
- });
396
-
397
- test('should handle clock skew', () => {
398
- const serverTime = Date.now();
399
- const clientTime = serverTime + (5 * 60 * 1000); // 5 minutes ahead
400
-
401
- const skew = Math.abs(clientTime - serverTime);
402
- const maxSkew = 2 * 60 * 1000; // 2 minutes tolerance
403
-
404
- // Should detect excessive skew
405
- if (skew > maxSkew) {
406
- expect(skew).toBeGreaterThan(maxSkew);
407
- }
408
- });
409
- });
410
- });