@kya-os/checkpoint-nextjs 1.0.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 (122) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/EDGE_RUNTIME_WASM_SETUP.md +348 -0
  3. package/README.md +414 -0
  4. package/bin/setup-edge-wasm.js +497 -0
  5. package/dist/.tsbuildinfo +1 -0
  6. package/dist/adapt.d.mts +39 -0
  7. package/dist/adapt.d.ts +39 -0
  8. package/dist/adapt.js +58 -0
  9. package/dist/adapt.js.map +1 -0
  10. package/dist/adapt.mjs +56 -0
  11. package/dist/adapt.mjs.map +1 -0
  12. package/dist/api-client.d.mts +204 -0
  13. package/dist/api-client.d.ts +204 -0
  14. package/dist/api-client.js +206 -0
  15. package/dist/api-client.js.map +1 -0
  16. package/dist/api-client.mjs +199 -0
  17. package/dist/api-client.mjs.map +1 -0
  18. package/dist/api-middleware.d.mts +156 -0
  19. package/dist/api-middleware.d.ts +156 -0
  20. package/dist/api-middleware.js +510 -0
  21. package/dist/api-middleware.js.map +1 -0
  22. package/dist/api-middleware.mjs +505 -0
  23. package/dist/api-middleware.mjs.map +1 -0
  24. package/dist/create-middleware.d.mts +17 -0
  25. package/dist/create-middleware.d.ts +17 -0
  26. package/dist/create-middleware.js +38 -0
  27. package/dist/create-middleware.js.map +1 -0
  28. package/dist/create-middleware.mjs +35 -0
  29. package/dist/create-middleware.mjs.map +1 -0
  30. package/dist/edge/index.d.mts +110 -0
  31. package/dist/edge/index.d.ts +110 -0
  32. package/dist/edge/index.js +277 -0
  33. package/dist/edge/index.js.map +1 -0
  34. package/dist/edge/index.mjs +275 -0
  35. package/dist/edge/index.mjs.map +1 -0
  36. package/dist/edge-runtime-loader.d.mts +50 -0
  37. package/dist/edge-runtime-loader.d.ts +50 -0
  38. package/dist/edge-runtime-loader.js +204 -0
  39. package/dist/edge-runtime-loader.js.map +1 -0
  40. package/dist/edge-runtime-loader.mjs +201 -0
  41. package/dist/edge-runtime-loader.mjs.map +1 -0
  42. package/dist/edge-wasm-middleware.d.mts +68 -0
  43. package/dist/edge-wasm-middleware.d.ts +68 -0
  44. package/dist/edge-wasm-middleware.js +318 -0
  45. package/dist/edge-wasm-middleware.js.map +1 -0
  46. package/dist/edge-wasm-middleware.mjs +315 -0
  47. package/dist/edge-wasm-middleware.mjs.map +1 -0
  48. package/dist/index.d.mts +25 -0
  49. package/dist/index.d.ts +25 -0
  50. package/dist/index.js +1019 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/index.mjs +979 -0
  53. package/dist/index.mjs.map +1 -0
  54. package/dist/middleware-edge.d.mts +46 -0
  55. package/dist/middleware-edge.d.ts +46 -0
  56. package/dist/middleware-edge.js +134 -0
  57. package/dist/middleware-edge.js.map +1 -0
  58. package/dist/middleware-edge.mjs +129 -0
  59. package/dist/middleware-edge.mjs.map +1 -0
  60. package/dist/middleware-node.d.mts +89 -0
  61. package/dist/middleware-node.d.ts +89 -0
  62. package/dist/middleware-node.js +127 -0
  63. package/dist/middleware-node.js.map +1 -0
  64. package/dist/middleware-node.mjs +124 -0
  65. package/dist/middleware-node.mjs.map +1 -0
  66. package/dist/middleware.d.mts +36 -0
  67. package/dist/middleware.d.ts +36 -0
  68. package/dist/middleware.js +15 -0
  69. package/dist/middleware.js.map +1 -0
  70. package/dist/middleware.mjs +12 -0
  71. package/dist/middleware.mjs.map +1 -0
  72. package/dist/nodejs-wasm-loader.d.mts +25 -0
  73. package/dist/nodejs-wasm-loader.d.ts +25 -0
  74. package/dist/nodejs-wasm-loader.js +95 -0
  75. package/dist/nodejs-wasm-loader.js.map +1 -0
  76. package/dist/nodejs-wasm-loader.mjs +85 -0
  77. package/dist/nodejs-wasm-loader.mjs.map +1 -0
  78. package/dist/policy.d.mts +162 -0
  79. package/dist/policy.d.ts +162 -0
  80. package/dist/policy.js +189 -0
  81. package/dist/policy.js.map +1 -0
  82. package/dist/policy.mjs +165 -0
  83. package/dist/policy.mjs.map +1 -0
  84. package/dist/session-tracker.d.mts +55 -0
  85. package/dist/session-tracker.d.ts +55 -0
  86. package/dist/session-tracker.js +170 -0
  87. package/dist/session-tracker.js.map +1 -0
  88. package/dist/session-tracker.mjs +167 -0
  89. package/dist/session-tracker.mjs.map +1 -0
  90. package/dist/signature-verifier.d.mts +33 -0
  91. package/dist/signature-verifier.d.ts +33 -0
  92. package/dist/signature-verifier.js +386 -0
  93. package/dist/signature-verifier.js.map +1 -0
  94. package/dist/signature-verifier.mjs +362 -0
  95. package/dist/signature-verifier.mjs.map +1 -0
  96. package/dist/translate.d.mts +33 -0
  97. package/dist/translate.d.ts +33 -0
  98. package/dist/translate.js +38 -0
  99. package/dist/translate.js.map +1 -0
  100. package/dist/translate.mjs +36 -0
  101. package/dist/translate.mjs.map +1 -0
  102. package/dist/types-C-xCUNTr.d.mts +105 -0
  103. package/dist/types-C-xCUNTr.d.ts +105 -0
  104. package/dist/wasm-middleware.d.mts +63 -0
  105. package/dist/wasm-middleware.d.ts +63 -0
  106. package/dist/wasm-middleware.js +98 -0
  107. package/dist/wasm-middleware.js.map +1 -0
  108. package/dist/wasm-middleware.mjs +95 -0
  109. package/dist/wasm-middleware.mjs.map +1 -0
  110. package/dist/wasm-setup.d.mts +46 -0
  111. package/dist/wasm-setup.d.ts +46 -0
  112. package/dist/wasm-setup.js +176 -0
  113. package/dist/wasm-setup.js.map +1 -0
  114. package/dist/wasm-setup.mjs +167 -0
  115. package/dist/wasm-setup.mjs.map +1 -0
  116. package/package.json +156 -0
  117. package/templates/middleware-wasm-100.ts +153 -0
  118. package/wasm/agentshield_wasm.d.ts +479 -0
  119. package/wasm/agentshield_wasm.js +1536 -0
  120. package/wasm/agentshield_wasm_bg.wasm +0 -0
  121. package/wasm/package.json +30 -0
  122. package/wasm.d.ts +21 -0
@@ -0,0 +1,497 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * AgentShield Edge Runtime WASM Setup Script
5
+ *
6
+ * This script helps Next.js users set up WASM support for Edge Runtime (middleware).
7
+ * It copies necessary files and creates the required configuration.
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const { execSync } = require('child_process');
13
+
14
+ // Colors for console output
15
+ const colors = {
16
+ reset: '\x1b[0m',
17
+ bright: '\x1b[1m',
18
+ green: '\x1b[32m',
19
+ yellow: '\x1b[33m',
20
+ blue: '\x1b[34m',
21
+ red: '\x1b[31m',
22
+ };
23
+
24
+ function log(message, color = colors.reset) {
25
+ console.log(`${color}${message}${colors.reset}`);
26
+ }
27
+
28
+ function error(message) {
29
+ console.error(`${colors.red}❌ ${message}${colors.reset}`);
30
+ }
31
+
32
+ function success(message) {
33
+ log(`✅ ${message}`, colors.green);
34
+ }
35
+
36
+ function info(message) {
37
+ log(`ℹ️ ${message}`, colors.blue);
38
+ }
39
+
40
+ function warning(message) {
41
+ log(`⚠️ ${message}`, colors.yellow);
42
+ }
43
+
44
+ async function main() {
45
+ log('\n🚀 AgentShield Edge Runtime WASM Setup\n', colors.bright);
46
+
47
+ // Step 1: Check if we're in a Next.js project
48
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
49
+ if (!fs.existsSync(packageJsonPath)) {
50
+ error('No package.json found. Please run this command from your Next.js project root.');
51
+ process.exit(1);
52
+ }
53
+
54
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
55
+ const hasNext = packageJson.dependencies?.next || packageJson.devDependencies?.next;
56
+
57
+ if (!hasNext) {
58
+ warning('Next.js not detected in package.json. Continuing anyway...');
59
+ }
60
+
61
+ // Step 2: Check if AgentShield is installed
62
+ const agentShieldPath = path.join(process.cwd(), 'node_modules', '@kya-os', 'agentshield-nextjs');
63
+ if (!fs.existsSync(agentShieldPath)) {
64
+ error('@kya-os/checkpoint-nextjs not found in node_modules.');
65
+ info('Please install it first:');
66
+ console.log(' npm install @kya-os/checkpoint-nextjs');
67
+ console.log(' # or');
68
+ console.log(' pnpm add @kya-os/checkpoint-nextjs');
69
+ process.exit(1);
70
+ }
71
+
72
+ // Step 3: Create wasm directory
73
+ const wasmDir = path.join(process.cwd(), 'wasm');
74
+ if (!fs.existsSync(wasmDir)) {
75
+ fs.mkdirSync(wasmDir, { recursive: true });
76
+ success('Created wasm/ directory');
77
+ }
78
+
79
+ // Step 4: Copy WASM file
80
+ const sourceWasm = path.join(agentShieldPath, 'dist', 'wasm', 'agentshield_wasm_bg.wasm');
81
+ const destWasm = path.join(wasmDir, 'agentshield_wasm_bg.wasm');
82
+
83
+ if (fs.existsSync(sourceWasm)) {
84
+ fs.copyFileSync(sourceWasm, destWasm);
85
+ const sizeKB = (fs.statSync(destWasm).size / 1024).toFixed(1);
86
+ const sizeMB = (fs.statSync(destWasm).size / 1024 / 1024).toFixed(2);
87
+ const sizeStr = sizeKB < 1024 ? `${sizeKB}KB` : `${sizeMB}MB`;
88
+ success(`Copied WASM file to wasm/ (${sizeStr})`);
89
+ } else {
90
+ // Try alternative location
91
+ const altSourceWasm = path.join(agentShieldPath, 'wasm', 'agentshield_wasm_bg.wasm');
92
+ if (fs.existsSync(altSourceWasm)) {
93
+ fs.copyFileSync(altSourceWasm, destWasm);
94
+ const sizeKB = (fs.statSync(destWasm).size / 1024).toFixed(1);
95
+ const sizeMB = (fs.statSync(destWasm).size / 1024 / 1024).toFixed(2);
96
+ const sizeStr = sizeKB < 1024 ? `${sizeKB}KB` : `${sizeMB}MB`;
97
+ success(`Copied WASM file to wasm/ (${sizeStr})`);
98
+ } else {
99
+ error('WASM file not found in the package. The package may be corrupted.');
100
+ process.exit(1);
101
+ }
102
+ }
103
+
104
+ // Step 5: Create TypeScript definitions
105
+ const dtsContent = `// Auto-generated by agentshield-setup-edge
106
+ // TypeScript definitions for AgentShield WASM in Edge Runtime
107
+
108
+ declare module '*.wasm?module' {
109
+ const wasmModule: WebAssembly.Module;
110
+ export default wasmModule;
111
+ }
112
+
113
+ export interface AgentShieldWasm {
114
+ detect_agent(metadata: string): string;
115
+ get_version(): string;
116
+ memory: WebAssembly.Memory;
117
+ }
118
+
119
+ export interface DetectionResult {
120
+ isAgent: boolean;
121
+ confidence: number;
122
+ agent?: string;
123
+ verificationMethod: 'cryptographic' | 'pattern';
124
+ riskLevel?: 'low' | 'medium' | 'high' | 'critical';
125
+ timestamp: string;
126
+ }
127
+ `;
128
+
129
+ const dtsPath = path.join(wasmDir, 'agentshield.d.ts');
130
+ fs.writeFileSync(dtsPath, dtsContent);
131
+ success('Created TypeScript definitions');
132
+
133
+ // Step 6: Create lib directory and Edge loader
134
+ const libDir = path.join(process.cwd(), 'lib');
135
+ if (!fs.existsSync(libDir)) {
136
+ fs.mkdirSync(libDir, { recursive: true });
137
+ }
138
+
139
+ const edgeLoaderContent = `/**
140
+ * AgentShield Edge Runtime Loader
141
+ * Auto-generated by agentshield-setup-edge
142
+ *
143
+ * This module provides WASM-based AI agent detection for Next.js Edge Runtime.
144
+ */
145
+
146
+ import type { NextRequest } from 'next/server';
147
+ import wasmModule from '../wasm/agentshield_wasm_bg.wasm?module';
148
+
149
+ let wasmInstance: WebAssembly.Instance | null = null;
150
+ let wasmMemory: WebAssembly.Memory | null = null;
151
+
152
+ interface WasmExports {
153
+ detect_agent(metadataPtr: number, metadataLen: number): number;
154
+ get_version(): number;
155
+ __wbindgen_malloc(size: number): number;
156
+ __wbindgen_free(ptr: number, size: number): void;
157
+ __wbindgen_realloc(ptr: number, oldSize: number, newSize: number): number;
158
+ memory: WebAssembly.Memory;
159
+ }
160
+
161
+ async function initWasm(): Promise<void> {
162
+ if (wasmInstance) return;
163
+
164
+ wasmMemory = new WebAssembly.Memory({ initial: 17, maximum: 256 });
165
+
166
+ const imports = {
167
+ wbg: {
168
+ __wbindgen_throw: (ptr: number, len: number) => {
169
+ throw new Error(readString(ptr, len));
170
+ },
171
+ __wbg_log_: (ptr: number, len: number) => {
172
+ console.log(readString(ptr, len));
173
+ },
174
+ },
175
+ env: {
176
+ memory: wasmMemory,
177
+ },
178
+ };
179
+
180
+ wasmInstance = await WebAssembly.instantiate(wasmModule, imports);
181
+ }
182
+
183
+ function readString(ptr: number, len: number): string {
184
+ if (!wasmInstance || !wasmMemory) throw new Error('WASM not initialized');
185
+ const memory = new Uint8Array(wasmMemory.buffer);
186
+ const bytes = memory.slice(ptr, ptr + len);
187
+ return new TextDecoder().decode(bytes);
188
+ }
189
+
190
+ function writeString(str: string): [number, number] {
191
+ if (!wasmInstance) throw new Error('WASM not initialized');
192
+ const exports = wasmInstance.exports as unknown as WasmExports;
193
+
194
+ const encoded = new TextEncoder().encode(str);
195
+ const ptr = exports.__wbindgen_malloc(encoded.length);
196
+
197
+ const memory = new Uint8Array(exports.memory.buffer);
198
+ memory.set(encoded, ptr);
199
+
200
+ return [ptr, encoded.length];
201
+ }
202
+
203
+ export interface DetectionResult {
204
+ isAgent: boolean;
205
+ confidence: number;
206
+ agent?: string;
207
+ verificationMethod: 'cryptographic' | 'pattern';
208
+ riskLevel?: 'low' | 'medium' | 'high' | 'critical';
209
+ timestamp?: string;
210
+ }
211
+
212
+ export interface AgentShieldOptions {
213
+ enableWasm?: boolean;
214
+ onAgentDetected?: (result: DetectionResult) => void;
215
+ blockAgents?: boolean;
216
+ allowedAgents?: string[];
217
+ }
218
+
219
+ /**
220
+ * Create an AgentShield middleware instance
221
+ */
222
+ export function createAgentShieldMiddleware(options: AgentShieldOptions = {}) {
223
+ let initialized = false;
224
+
225
+ return {
226
+ async init(): Promise<void> {
227
+ if (initialized) return;
228
+
229
+ if (options.enableWasm !== false) {
230
+ try {
231
+ await initWasm();
232
+ initialized = true;
233
+ console.log('✅ AgentShield WASM initialized in Edge Runtime');
234
+ } catch (error) {
235
+ console.warn('⚠️ WASM initialization failed, using pattern detection:', error);
236
+ initialized = true;
237
+ }
238
+ } else {
239
+ initialized = true;
240
+ }
241
+ },
242
+
243
+ async detect(request: NextRequest): Promise<DetectionResult> {
244
+ const metadata = {
245
+ userAgent: request.headers.get('user-agent') || '',
246
+ ipAddress: request.ip || request.headers.get('x-forwarded-for')?.split(',')[0] || '',
247
+ headers: Object.fromEntries(request.headers.entries()),
248
+ };
249
+
250
+ // Try WASM detection first
251
+ if (wasmInstance && options.enableWasm !== false) {
252
+ try {
253
+ const exports = wasmInstance.exports as unknown as WasmExports;
254
+ const [ptr, len] = writeString(JSON.stringify(metadata));
255
+
256
+ const resultPtr = exports.detect_agent(ptr, len);
257
+ const resultLen = 1024; // Assume max result size
258
+ const resultStr = readString(resultPtr, resultLen);
259
+
260
+ exports.__wbindgen_free(ptr, len);
261
+ exports.__wbindgen_free(resultPtr, resultLen);
262
+
263
+ const result = JSON.parse(resultStr);
264
+
265
+ const detection: DetectionResult = {
266
+ ...result,
267
+ verificationMethod: 'cryptographic',
268
+ timestamp: new Date().toISOString(),
269
+ };
270
+
271
+ if (options.onAgentDetected && detection.isAgent) {
272
+ options.onAgentDetected(detection);
273
+ }
274
+
275
+ return detection;
276
+ } catch (error) {
277
+ console.error('WASM detection failed:', error);
278
+ // Fall through to pattern detection
279
+ }
280
+ }
281
+
282
+ // Fallback: Pattern-based detection
283
+ return patternDetection(metadata, options);
284
+ },
285
+
286
+ isInitialized(): boolean {
287
+ return initialized;
288
+ },
289
+
290
+ getVerificationMethod(): 'cryptographic' | 'pattern' {
291
+ return wasmInstance ? 'cryptographic' : 'pattern';
292
+ },
293
+ };
294
+ }
295
+
296
+ /**
297
+ * Pattern-based detection fallback
298
+ */
299
+ function patternDetection(
300
+ metadata: { userAgent: string; ipAddress: string; headers: Record<string, string> },
301
+ options: AgentShieldOptions
302
+ ): DetectionResult {
303
+ const userAgent = metadata.userAgent.toLowerCase();
304
+
305
+ // Known AI agent patterns with confidence scores
306
+ const aiAgentPatterns = [
307
+ { pattern: /chatgpt-user/i, name: 'ChatGPT', confidence: 0.95 },
308
+ { pattern: /claude-web/i, name: 'Claude', confidence: 0.95 },
309
+ { pattern: /anthropic/i, name: 'Anthropic', confidence: 0.90 },
310
+ { pattern: /openai/i, name: 'OpenAI', confidence: 0.90 },
311
+ { pattern: /gpt-crawler/i, name: 'GPT Crawler', confidence: 0.95 },
312
+ { pattern: /copilot/i, name: 'GitHub Copilot', confidence: 0.85 },
313
+ { pattern: /bard/i, name: 'Google Bard', confidence: 0.85 },
314
+ { pattern: /gemini/i, name: 'Google Gemini', confidence: 0.85 },
315
+ { pattern: /perplexity/i, name: 'Perplexity', confidence: 0.85 },
316
+ ];
317
+
318
+ // Check headers for AI-specific patterns
319
+ const suspiciousHeaders = [
320
+ 'x-openai-',
321
+ 'x-anthropic-',
322
+ 'x-ai-',
323
+ 'x-llm-',
324
+ ];
325
+
326
+ let headerBoost = 0;
327
+ for (const [key, value] of Object.entries(metadata.headers)) {
328
+ if (suspiciousHeaders.some(prefix => key.toLowerCase().startsWith(prefix))) {
329
+ headerBoost = 0.1;
330
+ break;
331
+ }
332
+ }
333
+
334
+ // Check user agent patterns
335
+ for (const { pattern, name, confidence } of aiAgentPatterns) {
336
+ if (pattern.test(userAgent)) {
337
+ const finalConfidence = Math.min(confidence + headerBoost, 1.0);
338
+
339
+ const result: DetectionResult = {
340
+ isAgent: true,
341
+ confidence: finalConfidence,
342
+ agent: name,
343
+ verificationMethod: 'pattern',
344
+ riskLevel: finalConfidence > 0.9 ? 'high' : 'medium',
345
+ timestamp: new Date().toISOString(),
346
+ };
347
+
348
+ if (options.onAgentDetected) {
349
+ options.onAgentDetected(result);
350
+ }
351
+
352
+ return result;
353
+ }
354
+ }
355
+
356
+ // Not detected as AI agent
357
+ return {
358
+ isAgent: false,
359
+ confidence: 0.85,
360
+ verificationMethod: 'pattern',
361
+ timestamp: new Date().toISOString(),
362
+ };
363
+ }
364
+
365
+ export default createAgentShieldMiddleware;
366
+ `;
367
+
368
+ const edgeLoaderPath = path.join(libDir, 'agentshield-edge.ts');
369
+ fs.writeFileSync(edgeLoaderPath, edgeLoaderContent);
370
+ success('Created Edge Runtime loader at lib/agentshield-edge.ts');
371
+
372
+ // Step 7: Create example middleware if it doesn't exist
373
+ const middlewarePath = path.join(process.cwd(), 'middleware.ts');
374
+ if (!fs.existsSync(middlewarePath)) {
375
+ const middlewareContent = `import { NextResponse } from 'next/server';
376
+ import type { NextRequest } from 'next/server';
377
+ import { createAgentShieldMiddleware } from './lib/agentshield-edge';
378
+
379
+ // Initialize AgentShield
380
+ const agentShield = createAgentShieldMiddleware({
381
+ enableWasm: true,
382
+ onAgentDetected: (result) => {
383
+ console.log(\`🤖 AI Agent detected: \${result.agent} (confidence: \${(result.confidence * 100).toFixed(1)}%)\`);
384
+ },
385
+ });
386
+
387
+ export async function middleware(request: NextRequest) {
388
+ // Initialize WASM on first request
389
+ await agentShield.init();
390
+
391
+ // Detect AI agents
392
+ const detection = await agentShield.detect(request);
393
+
394
+ // Log detection results
395
+ if (detection.isAgent) {
396
+ console.log(\`AI Agent detected on \${request.url}:\`, detection);
397
+
398
+ // Optional: Add headers to track AI agent traffic
399
+ const response = NextResponse.next();
400
+ response.headers.set('X-Agent-Detected', detection.agent || 'unknown');
401
+ response.headers.set('X-Agent-Confidence', detection.confidence.toString());
402
+ return response;
403
+
404
+ // Optional: Block AI agents
405
+ // if (detection.confidence > 0.9) {
406
+ // return NextResponse.json(
407
+ // { error: 'AI agent access denied' },
408
+ // { status: 403 }
409
+ // );
410
+ // }
411
+ }
412
+
413
+ return NextResponse.next();
414
+ }
415
+
416
+ export const config = {
417
+ matcher: [
418
+ /*
419
+ * Match all request paths except for the ones starting with:
420
+ * - api/admin (protect admin APIs)
421
+ * - _next/static (static files)
422
+ * - _next/image (image optimization files)
423
+ * - favicon.ico (favicon file)
424
+ */
425
+ '/((?!_next/static|_next/image|favicon.ico).*)',
426
+ ],
427
+ };
428
+ `;
429
+
430
+ fs.writeFileSync(middlewarePath, middlewareContent);
431
+ success('Created example middleware.ts');
432
+ } else {
433
+ info('middleware.ts already exists - skipping creation');
434
+ info('See lib/agentshield-edge.ts for integration instructions');
435
+ }
436
+
437
+ // Step 8: Update next.config.js if needed
438
+ const nextConfigPath = path.join(process.cwd(), 'next.config.js');
439
+ const nextConfigMjsPath = path.join(process.cwd(), 'next.config.mjs');
440
+ const configPath = fs.existsSync(nextConfigPath)
441
+ ? nextConfigPath
442
+ : fs.existsSync(nextConfigMjsPath)
443
+ ? nextConfigMjsPath
444
+ : null;
445
+
446
+ if (configPath) {
447
+ const configContent = fs.readFileSync(configPath, 'utf8');
448
+
449
+ if (!configContent.includes('wasm')) {
450
+ warning('Your next.config.js may need to be updated to handle WASM files.');
451
+ console.log('\nAdd this to your webpack config:\n');
452
+ console.log(
453
+ colors.yellow +
454
+ ` webpack: (config) => {
455
+ config.module.rules.push({
456
+ test: /\\.wasm$/,
457
+ type: 'asset/resource',
458
+ });
459
+ return config;
460
+ },` +
461
+ colors.reset
462
+ );
463
+ }
464
+ }
465
+
466
+ // Step 9: Final instructions
467
+ console.log('\n' + colors.bright + '🎉 Setup Complete!' + colors.reset);
468
+ console.log(
469
+ '\n' + colors.green + 'AgentShield Edge Runtime WASM is now configured!' + colors.reset
470
+ );
471
+ console.log('\nNext steps:');
472
+ console.log('1. Review the generated files:');
473
+ console.log(' - wasm/agentshield_wasm_bg.wasm (WASM binary)');
474
+ console.log(' - lib/agentshield-edge.ts (Edge Runtime loader)');
475
+ console.log(' - middleware.ts (Example implementation)');
476
+ console.log('\n2. Test your setup:');
477
+ console.log(' npm run dev');
478
+ console.log(' # Visit your site and check the console for detection logs');
479
+ console.log('\n3. Deploy to Vercel:');
480
+ console.log(' git add .');
481
+ console.log(' git commit -m "Add AgentShield WASM for Edge Runtime"');
482
+ console.log(' git push');
483
+ console.log(
484
+ '\n' +
485
+ colors.blue +
486
+ 'Documentation: https://github.com/kya-os/agentshield#edge-runtime' +
487
+ colors.reset
488
+ );
489
+ console.log(colors.blue + 'Issues: https://github.com/kya-os/agentshield/issues' + colors.reset);
490
+ }
491
+
492
+ // Run the setup
493
+ main().catch((err) => {
494
+ error('Setup failed: ' + err.message);
495
+ console.error(err);
496
+ process.exit(1);
497
+ });