@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,206 @@
1
+ 'use strict';
2
+
3
+ // src/api-client.ts
4
+ var DEFAULT_BASE_URL = "https://kya.vouched.id";
5
+ var EDGE_DETECT_URL = "https://detect.checkpoint-gateway.ai";
6
+ var DEFAULT_TIMEOUT = 5e3;
7
+ var CheckpointApiClient = class {
8
+ apiKey;
9
+ baseUrl;
10
+ useEdge;
11
+ timeout;
12
+ debug;
13
+ constructor(config) {
14
+ if (!config.apiKey) {
15
+ throw new Error("AgentShield API key is required");
16
+ }
17
+ this.apiKey = config.apiKey;
18
+ this.useEdge = config.useEdge !== false;
19
+ this.baseUrl = config.baseUrl || (this.useEdge ? EDGE_DETECT_URL : DEFAULT_BASE_URL);
20
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
21
+ this.debug = config.debug || false;
22
+ }
23
+ /**
24
+ * Call the enforce API to check if a request should be allowed
25
+ */
26
+ async enforce(input) {
27
+ const startTime = Date.now();
28
+ try {
29
+ const controller = new AbortController();
30
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
31
+ try {
32
+ const endpoint = this.useEdge ? `${this.baseUrl}/__detect/enforce` : `${this.baseUrl}/api/v1/enforce`;
33
+ const response = await fetch(endpoint, {
34
+ method: "POST",
35
+ headers: {
36
+ "Content-Type": "application/json",
37
+ Authorization: `Bearer ${this.apiKey}`,
38
+ "X-Request-ID": input.requestId || crypto.randomUUID()
39
+ },
40
+ body: JSON.stringify(input),
41
+ signal: controller.signal
42
+ });
43
+ clearTimeout(timeoutId);
44
+ const data = await response.json();
45
+ if (this.debug) {
46
+ console.log("[AgentShield] Enforce response:", {
47
+ status: response.status,
48
+ action: data.data?.decision.action,
49
+ processingTimeMs: Date.now() - startTime
50
+ });
51
+ }
52
+ if (!response.ok) {
53
+ return {
54
+ success: false,
55
+ error: {
56
+ code: `HTTP_${response.status}`,
57
+ message: data.error?.message || `HTTP error: ${response.status}`
58
+ }
59
+ };
60
+ }
61
+ return data;
62
+ } catch (error) {
63
+ clearTimeout(timeoutId);
64
+ throw error;
65
+ }
66
+ } catch (error) {
67
+ if (error instanceof Error && error.name === "AbortError") {
68
+ if (this.debug) {
69
+ console.warn("[AgentShield] Request timed out");
70
+ }
71
+ return {
72
+ success: false,
73
+ error: {
74
+ code: "TIMEOUT",
75
+ message: `Request timed out after ${this.timeout}ms`
76
+ }
77
+ };
78
+ }
79
+ if (this.debug) {
80
+ console.error("[AgentShield] Request failed:", error);
81
+ }
82
+ return {
83
+ success: false,
84
+ error: {
85
+ code: "NETWORK_ERROR",
86
+ message: error instanceof Error ? error.message : "Network request failed"
87
+ }
88
+ };
89
+ }
90
+ }
91
+ /**
92
+ * Quick check - returns just the action without full response parsing
93
+ * Useful for very fast middleware that just needs allow/block
94
+ */
95
+ async quickCheck(input) {
96
+ const result = await this.enforce(input);
97
+ if (!result.success || !result.data) {
98
+ return {
99
+ action: "allow",
100
+ error: result.error?.message
101
+ };
102
+ }
103
+ return {
104
+ action: result.data.decision.action
105
+ };
106
+ }
107
+ /**
108
+ * Check if this client is using edge detection (Gateway Worker)
109
+ */
110
+ isUsingEdge() {
111
+ return this.useEdge;
112
+ }
113
+ /**
114
+ * Log a detection result to AgentShield database.
115
+ * Use after Gateway Worker detection to persist results.
116
+ * Fire-and-forget - returns immediately without waiting for DB write.
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * // After receiving Gateway response
121
+ * if (client.isUsingEdge() && response.data?.detection) {
122
+ * client.logDetection({
123
+ * detection: response.data.detection,
124
+ * context: { userAgent, ipAddress, path, url, method }
125
+ * }).catch(err => console.error('Log failed:', err));
126
+ * }
127
+ * ```
128
+ */
129
+ async logDetection(input) {
130
+ const logEndpoint = this.useEdge ? `${DEFAULT_BASE_URL}/api/v1/log-detection` : `${this.baseUrl}/api/v1/log-detection`;
131
+ try {
132
+ const controller = new AbortController();
133
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
134
+ try {
135
+ const response = await fetch(logEndpoint, {
136
+ method: "POST",
137
+ headers: {
138
+ "Content-Type": "application/json",
139
+ Authorization: `Bearer ${this.apiKey}`
140
+ },
141
+ body: JSON.stringify({
142
+ detection: {
143
+ isAgent: input.detection.isAgent,
144
+ confidence: input.detection.confidence,
145
+ agentName: input.detection.agentName,
146
+ agentType: input.detection.agentType,
147
+ detectionClass: input.detection.detectionClass,
148
+ verificationMethod: input.detection.verificationMethod,
149
+ reasons: input.detection.reasons
150
+ },
151
+ context: input.context,
152
+ source: input.source || "gateway"
153
+ }),
154
+ signal: controller.signal
155
+ });
156
+ clearTimeout(timeoutId);
157
+ if (!response.ok && this.debug) {
158
+ console.warn("[AgentShield] Log detection returned non-2xx:", response.status);
159
+ }
160
+ } catch (error) {
161
+ clearTimeout(timeoutId);
162
+ throw error;
163
+ }
164
+ } catch (error) {
165
+ if (this.debug) {
166
+ console.error("[AgentShield] Log detection failed:", error);
167
+ }
168
+ throw error;
169
+ }
170
+ }
171
+ };
172
+ var clientInstance = null;
173
+ function getCheckpointApiClient(config) {
174
+ if (!clientInstance) {
175
+ const apiKey = config?.apiKey || process.env.CHECKPOINT_API_KEY;
176
+ if (!apiKey) {
177
+ throw new Error(
178
+ "AgentShield API key is required. Set CHECKPOINT_API_KEY environment variable or pass apiKey in config."
179
+ );
180
+ }
181
+ clientInstance = new CheckpointApiClient({
182
+ apiKey,
183
+ baseUrl: config?.baseUrl || process.env.AGENTSHIELD_API_URL,
184
+ // Default to edge detection unless explicitly disabled
185
+ useEdge: config?.useEdge ?? process.env.AGENTSHIELD_USE_EDGE !== "false",
186
+ timeout: config?.timeout,
187
+ debug: config?.debug || process.env.AGENTSHIELD_DEBUG === "true"
188
+ });
189
+ }
190
+ return clientInstance;
191
+ }
192
+ function resetCheckpointApiClient() {
193
+ clientInstance = null;
194
+ }
195
+ var AgentShieldClient = CheckpointApiClient;
196
+ var getAgentShieldClient = getCheckpointApiClient;
197
+ var resetAgentShieldClient = resetCheckpointApiClient;
198
+
199
+ exports.AgentShieldClient = AgentShieldClient;
200
+ exports.CheckpointApiClient = CheckpointApiClient;
201
+ exports.getAgentShieldClient = getAgentShieldClient;
202
+ exports.getCheckpointApiClient = getCheckpointApiClient;
203
+ exports.resetAgentShieldClient = resetAgentShieldClient;
204
+ exports.resetCheckpointApiClient = resetCheckpointApiClient;
205
+ //# sourceMappingURL=api-client.js.map
206
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api-client.ts"],"names":[],"mappings":"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","file":"api-client.js","sourcesContent":["/**\n * AgentShield API Client\n *\n * Lightweight client for calling the AgentShield enforce API from middleware.\n * Designed for Edge Runtime compatibility (no Node.js-specific APIs).\n */\n\nimport type { EnforcementAction } from '@kya-os/checkpoint-shared';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * API client configuration\n */\nexport interface CheckpointApiClientConfig {\n /** API key for authentication */\n apiKey: string;\n /** API base URL (defaults to production) */\n baseUrl?: string;\n /**\n * Use edge detection for lower latency (~30-50ms vs ~150ms) and better coverage.\n * Edge detection can identify non-JS clients (curl, Python, Claude Code WebFetch)\n * that the pixel cannot detect since they don't execute JavaScript.\n * @default true\n */\n useEdge?: boolean;\n /** Request timeout in milliseconds (default: 5000) */\n timeout?: number;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Enforcement action — re-exported from `@kya-os/checkpoint-shared`\n * so consumers of this package can keep importing it from the same\n * place. The canonical 6-value union is defined in\n * `packages/checkpoint-shared/src/policy/constants.ts`. `'instruct'`\n * tells the middleware to emit a 401 with an MCP-I Link header\n * pointing the agent at a connect/consent URL.\n */\nexport type { EnforcementAction };\n\n/**\n * Enforcement decision from the API\n */\nexport interface EnforcementDecision {\n action: EnforcementAction;\n reason: string;\n isAgent: boolean;\n confidence: number;\n agentName?: string;\n agentType?: string;\n redirectUrl?: string;\n message?: string;\n metadata?: {\n policyVersion?: string;\n signatureVerified?: boolean;\n denyListMatch?: {\n clientDid?: string;\n agentDid?: string;\n clientName?: string;\n reason?: string;\n };\n };\n}\n\n/**\n * Detection result (optional in response)\n */\nexport interface DetectionResult {\n isAgent: boolean;\n confidence: number;\n agentName?: string;\n agentType?: string;\n /** Detection class: 'human', 'ai_agent', 'bot', 'incomplete_data' */\n detectionClass?: string;\n verificationMethod?: string;\n reasons?: string[];\n /** Detection engine used: 'wasm' or 'javascript-fallback' */\n detectionMethod?: string;\n}\n\n/**\n * Enforce API response\n */\nexport interface EnforceResponse {\n success: boolean;\n data?: {\n decision: EnforcementDecision;\n processingTimeMs: number;\n requestId: string;\n detection?: DetectionResult;\n };\n error?: {\n code: string;\n message: string;\n };\n}\n\n/**\n * Request input for enforce API\n */\nexport interface EnforceInput {\n /** HTTP headers from the incoming request */\n headers?: Record<string, string>;\n /** User-Agent header */\n userAgent?: string;\n /** Client IP address */\n ipAddress?: string;\n /** Request path */\n path?: string;\n /** Request URL */\n url?: string;\n /** HTTP method */\n method?: string;\n /** Request ID for tracing */\n requestId?: string;\n /** Options */\n options?: {\n /** Include full detection result */\n includeDetectionResult?: boolean;\n /** Cache TTL override */\n cacheTTL?: number;\n };\n}\n\n/**\n * Input for logging a detection result\n */\nexport interface LogDetectionInput {\n /** Detection result from Gateway */\n detection: DetectionResult;\n /** Request context */\n context: {\n userAgent?: string;\n ipAddress?: string;\n path?: string;\n url?: string;\n method?: string;\n };\n /** Source of the detection */\n source?: 'gateway' | 'middleware';\n}\n\n// ============================================================================\n// Client Implementation\n// ============================================================================\n\nconst DEFAULT_BASE_URL = 'https://kya.vouched.id';\nconst EDGE_DETECT_URL = 'https://detect.checkpoint-gateway.ai';\nconst DEFAULT_TIMEOUT = 5000;\n\n/**\n * AgentShield API Client\n *\n * @example\n * ```typescript\n * const client = new CheckpointApiClient({\n * apiKey: process.env.CHECKPOINT_API_KEY!,\n * });\n *\n * const result = await client.enforce({\n * headers: Object.fromEntries(request.headers),\n * path: request.nextUrl.pathname,\n * method: request.method,\n * });\n *\n * if (result.decision.action === 'block') {\n * return new Response('Access denied', { status: 403 });\n * }\n * ```\n */\nexport class CheckpointApiClient {\n private apiKey: string;\n private baseUrl: string;\n private useEdge: boolean;\n private timeout: number;\n private debug: boolean;\n\n constructor(config: CheckpointApiClientConfig) {\n if (!config.apiKey) {\n throw new Error('AgentShield API key is required');\n }\n\n this.apiKey = config.apiKey;\n // Default to edge detection for better coverage (detects non-JS clients)\n this.useEdge = config.useEdge !== false; // true by default\n this.baseUrl = config.baseUrl || (this.useEdge ? EDGE_DETECT_URL : DEFAULT_BASE_URL);\n this.timeout = config.timeout || DEFAULT_TIMEOUT;\n this.debug = config.debug || false;\n }\n\n /**\n * Call the enforce API to check if a request should be allowed\n */\n async enforce(input: EnforceInput): Promise<EnforceResponse> {\n const startTime = Date.now();\n\n try {\n // Create abort controller for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n // Use edge endpoint or Vercel API based on configuration\n const endpoint = this.useEdge\n ? `${this.baseUrl}/__detect/enforce`\n : `${this.baseUrl}/api/v1/enforce`;\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n 'X-Request-ID': input.requestId || crypto.randomUUID(),\n },\n body: JSON.stringify(input),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Parse response\n const data = (await response.json()) as EnforceResponse;\n\n if (this.debug) {\n console.log('[AgentShield] Enforce response:', {\n status: response.status,\n action: data.data?.decision.action,\n processingTimeMs: Date.now() - startTime,\n });\n }\n\n // Handle non-2xx responses\n if (!response.ok) {\n return {\n success: false,\n error: {\n code: `HTTP_${response.status}`,\n message: data.error?.message || `HTTP error: ${response.status}`,\n },\n };\n }\n\n return data;\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n } catch (error) {\n // Handle timeout\n if (error instanceof Error && error.name === 'AbortError') {\n if (this.debug) {\n console.warn('[AgentShield] Request timed out');\n }\n return {\n success: false,\n error: {\n code: 'TIMEOUT',\n message: `Request timed out after ${this.timeout}ms`,\n },\n };\n }\n\n // Handle network errors\n if (this.debug) {\n console.error('[AgentShield] Request failed:', error);\n }\n\n return {\n success: false,\n error: {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Network request failed',\n },\n };\n }\n }\n\n /**\n * Quick check - returns just the action without full response parsing\n * Useful for very fast middleware that just needs allow/block\n */\n async quickCheck(input: EnforceInput): Promise<{\n action: EnforcementAction;\n error?: string;\n }> {\n const result = await this.enforce(input);\n\n if (!result.success || !result.data) {\n // On error, default to allow (fail-open)\n return {\n action: 'allow',\n error: result.error?.message,\n };\n }\n\n return {\n action: result.data.decision.action,\n };\n }\n\n /**\n * Check if this client is using edge detection (Gateway Worker)\n */\n isUsingEdge(): boolean {\n return this.useEdge;\n }\n\n /**\n * Log a detection result to AgentShield database.\n * Use after Gateway Worker detection to persist results.\n * Fire-and-forget - returns immediately without waiting for DB write.\n *\n * @example\n * ```typescript\n * // After receiving Gateway response\n * if (client.isUsingEdge() && response.data?.detection) {\n * client.logDetection({\n * detection: response.data.detection,\n * context: { userAgent, ipAddress, path, url, method }\n * }).catch(err => console.error('Log failed:', err));\n * }\n * ```\n */\n async logDetection(input: LogDetectionInput): Promise<void> {\n // Don't await - fire and forget\n // Use the base URL (not edge) for logging since this goes to the main API\n const logEndpoint = this.useEdge\n ? `${DEFAULT_BASE_URL}/api/v1/log-detection`\n : `${this.baseUrl}/api/v1/log-detection`;\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(logEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n detection: {\n isAgent: input.detection.isAgent,\n confidence: input.detection.confidence,\n agentName: input.detection.agentName,\n agentType: input.detection.agentType,\n detectionClass: input.detection.detectionClass,\n verificationMethod: input.detection.verificationMethod,\n reasons: input.detection.reasons,\n },\n context: input.context,\n source: input.source || 'gateway',\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok && this.debug) {\n console.warn('[AgentShield] Log detection returned non-2xx:', response.status);\n }\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n } catch (error) {\n // Silently fail for fire-and-forget, but log in debug mode\n if (this.debug) {\n console.error('[AgentShield] Log detection failed:', error);\n }\n // Re-throw so caller can catch if needed\n throw error;\n }\n }\n}\n\n/**\n * Create a singleton client instance\n *\n * @example\n * ```typescript\n * // In middleware.ts\n * import { getCheckpointApiClient } from '@kya-os/checkpoint-nextjs';\n *\n * const client = getCheckpointApiClient();\n * ```\n */\nlet clientInstance: CheckpointApiClient | null = null;\n\nexport function getCheckpointApiClient(\n config?: Partial<CheckpointApiClientConfig>\n): CheckpointApiClient {\n if (!clientInstance) {\n const apiKey = config?.apiKey || process.env.CHECKPOINT_API_KEY;\n\n if (!apiKey) {\n throw new Error(\n 'AgentShield API key is required. Set CHECKPOINT_API_KEY environment variable or pass apiKey in config.'\n );\n }\n\n clientInstance = new CheckpointApiClient({\n apiKey,\n baseUrl: config?.baseUrl || process.env.AGENTSHIELD_API_URL,\n // Default to edge detection unless explicitly disabled\n useEdge: config?.useEdge ?? process.env.AGENTSHIELD_USE_EDGE !== 'false',\n timeout: config?.timeout,\n debug: config?.debug || process.env.AGENTSHIELD_DEBUG === 'true',\n });\n }\n\n return clientInstance;\n}\n\n/**\n * Reset the singleton client (useful for testing)\n */\nexport function resetCheckpointApiClient(): void {\n clientInstance = null;\n}\n\n// ---------------------------------------------------------------------------\n// Back-compat aliases (Phase D rename — `AgentShield*` → `CheckpointApi*`).\n//\n// The SaaS-API deployment shape is preserved post-Phase-D — it talks to\n// the Cloudflare DNS gateway and remains a supported deployment option\n// alongside the local-engine `withCheckpoint` path. The names changed\n// to align with the rest of the `checkpoint-*` packages; the old names\n// stay live as @deprecated aliases for one release.\n// ---------------------------------------------------------------------------\n\n/** @deprecated Renamed to {@link CheckpointApiClient}. The runtime is identical. */\nexport const AgentShieldClient = CheckpointApiClient;\n\n/** @deprecated Renamed to {@link CheckpointApiClientConfig}. */\nexport type AgentShieldClientConfig = CheckpointApiClientConfig;\n\n/** @deprecated Renamed to {@link getCheckpointApiClient}. */\nexport const getAgentShieldClient = getCheckpointApiClient;\n\n/** @deprecated Renamed to {@link resetCheckpointApiClient}. */\nexport const resetAgentShieldClient = resetCheckpointApiClient;\n"]}
@@ -0,0 +1,199 @@
1
+ // src/api-client.ts
2
+ var DEFAULT_BASE_URL = "https://kya.vouched.id";
3
+ var EDGE_DETECT_URL = "https://detect.checkpoint-gateway.ai";
4
+ var DEFAULT_TIMEOUT = 5e3;
5
+ var CheckpointApiClient = class {
6
+ apiKey;
7
+ baseUrl;
8
+ useEdge;
9
+ timeout;
10
+ debug;
11
+ constructor(config) {
12
+ if (!config.apiKey) {
13
+ throw new Error("AgentShield API key is required");
14
+ }
15
+ this.apiKey = config.apiKey;
16
+ this.useEdge = config.useEdge !== false;
17
+ this.baseUrl = config.baseUrl || (this.useEdge ? EDGE_DETECT_URL : DEFAULT_BASE_URL);
18
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
19
+ this.debug = config.debug || false;
20
+ }
21
+ /**
22
+ * Call the enforce API to check if a request should be allowed
23
+ */
24
+ async enforce(input) {
25
+ const startTime = Date.now();
26
+ try {
27
+ const controller = new AbortController();
28
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
29
+ try {
30
+ const endpoint = this.useEdge ? `${this.baseUrl}/__detect/enforce` : `${this.baseUrl}/api/v1/enforce`;
31
+ const response = await fetch(endpoint, {
32
+ method: "POST",
33
+ headers: {
34
+ "Content-Type": "application/json",
35
+ Authorization: `Bearer ${this.apiKey}`,
36
+ "X-Request-ID": input.requestId || crypto.randomUUID()
37
+ },
38
+ body: JSON.stringify(input),
39
+ signal: controller.signal
40
+ });
41
+ clearTimeout(timeoutId);
42
+ const data = await response.json();
43
+ if (this.debug) {
44
+ console.log("[AgentShield] Enforce response:", {
45
+ status: response.status,
46
+ action: data.data?.decision.action,
47
+ processingTimeMs: Date.now() - startTime
48
+ });
49
+ }
50
+ if (!response.ok) {
51
+ return {
52
+ success: false,
53
+ error: {
54
+ code: `HTTP_${response.status}`,
55
+ message: data.error?.message || `HTTP error: ${response.status}`
56
+ }
57
+ };
58
+ }
59
+ return data;
60
+ } catch (error) {
61
+ clearTimeout(timeoutId);
62
+ throw error;
63
+ }
64
+ } catch (error) {
65
+ if (error instanceof Error && error.name === "AbortError") {
66
+ if (this.debug) {
67
+ console.warn("[AgentShield] Request timed out");
68
+ }
69
+ return {
70
+ success: false,
71
+ error: {
72
+ code: "TIMEOUT",
73
+ message: `Request timed out after ${this.timeout}ms`
74
+ }
75
+ };
76
+ }
77
+ if (this.debug) {
78
+ console.error("[AgentShield] Request failed:", error);
79
+ }
80
+ return {
81
+ success: false,
82
+ error: {
83
+ code: "NETWORK_ERROR",
84
+ message: error instanceof Error ? error.message : "Network request failed"
85
+ }
86
+ };
87
+ }
88
+ }
89
+ /**
90
+ * Quick check - returns just the action without full response parsing
91
+ * Useful for very fast middleware that just needs allow/block
92
+ */
93
+ async quickCheck(input) {
94
+ const result = await this.enforce(input);
95
+ if (!result.success || !result.data) {
96
+ return {
97
+ action: "allow",
98
+ error: result.error?.message
99
+ };
100
+ }
101
+ return {
102
+ action: result.data.decision.action
103
+ };
104
+ }
105
+ /**
106
+ * Check if this client is using edge detection (Gateway Worker)
107
+ */
108
+ isUsingEdge() {
109
+ return this.useEdge;
110
+ }
111
+ /**
112
+ * Log a detection result to AgentShield database.
113
+ * Use after Gateway Worker detection to persist results.
114
+ * Fire-and-forget - returns immediately without waiting for DB write.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * // After receiving Gateway response
119
+ * if (client.isUsingEdge() && response.data?.detection) {
120
+ * client.logDetection({
121
+ * detection: response.data.detection,
122
+ * context: { userAgent, ipAddress, path, url, method }
123
+ * }).catch(err => console.error('Log failed:', err));
124
+ * }
125
+ * ```
126
+ */
127
+ async logDetection(input) {
128
+ const logEndpoint = this.useEdge ? `${DEFAULT_BASE_URL}/api/v1/log-detection` : `${this.baseUrl}/api/v1/log-detection`;
129
+ try {
130
+ const controller = new AbortController();
131
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
132
+ try {
133
+ const response = await fetch(logEndpoint, {
134
+ method: "POST",
135
+ headers: {
136
+ "Content-Type": "application/json",
137
+ Authorization: `Bearer ${this.apiKey}`
138
+ },
139
+ body: JSON.stringify({
140
+ detection: {
141
+ isAgent: input.detection.isAgent,
142
+ confidence: input.detection.confidence,
143
+ agentName: input.detection.agentName,
144
+ agentType: input.detection.agentType,
145
+ detectionClass: input.detection.detectionClass,
146
+ verificationMethod: input.detection.verificationMethod,
147
+ reasons: input.detection.reasons
148
+ },
149
+ context: input.context,
150
+ source: input.source || "gateway"
151
+ }),
152
+ signal: controller.signal
153
+ });
154
+ clearTimeout(timeoutId);
155
+ if (!response.ok && this.debug) {
156
+ console.warn("[AgentShield] Log detection returned non-2xx:", response.status);
157
+ }
158
+ } catch (error) {
159
+ clearTimeout(timeoutId);
160
+ throw error;
161
+ }
162
+ } catch (error) {
163
+ if (this.debug) {
164
+ console.error("[AgentShield] Log detection failed:", error);
165
+ }
166
+ throw error;
167
+ }
168
+ }
169
+ };
170
+ var clientInstance = null;
171
+ function getCheckpointApiClient(config) {
172
+ if (!clientInstance) {
173
+ const apiKey = config?.apiKey || process.env.CHECKPOINT_API_KEY;
174
+ if (!apiKey) {
175
+ throw new Error(
176
+ "AgentShield API key is required. Set CHECKPOINT_API_KEY environment variable or pass apiKey in config."
177
+ );
178
+ }
179
+ clientInstance = new CheckpointApiClient({
180
+ apiKey,
181
+ baseUrl: config?.baseUrl || process.env.AGENTSHIELD_API_URL,
182
+ // Default to edge detection unless explicitly disabled
183
+ useEdge: config?.useEdge ?? process.env.AGENTSHIELD_USE_EDGE !== "false",
184
+ timeout: config?.timeout,
185
+ debug: config?.debug || process.env.AGENTSHIELD_DEBUG === "true"
186
+ });
187
+ }
188
+ return clientInstance;
189
+ }
190
+ function resetCheckpointApiClient() {
191
+ clientInstance = null;
192
+ }
193
+ var AgentShieldClient = CheckpointApiClient;
194
+ var getAgentShieldClient = getCheckpointApiClient;
195
+ var resetAgentShieldClient = resetCheckpointApiClient;
196
+
197
+ export { AgentShieldClient, CheckpointApiClient, getAgentShieldClient, getCheckpointApiClient, resetAgentShieldClient, resetCheckpointApiClient };
198
+ //# sourceMappingURL=api-client.mjs.map
199
+ //# sourceMappingURL=api-client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api-client.ts"],"names":[],"mappings":"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","file":"api-client.mjs","sourcesContent":["/**\n * AgentShield API Client\n *\n * Lightweight client for calling the AgentShield enforce API from middleware.\n * Designed for Edge Runtime compatibility (no Node.js-specific APIs).\n */\n\nimport type { EnforcementAction } from '@kya-os/checkpoint-shared';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * API client configuration\n */\nexport interface CheckpointApiClientConfig {\n /** API key for authentication */\n apiKey: string;\n /** API base URL (defaults to production) */\n baseUrl?: string;\n /**\n * Use edge detection for lower latency (~30-50ms vs ~150ms) and better coverage.\n * Edge detection can identify non-JS clients (curl, Python, Claude Code WebFetch)\n * that the pixel cannot detect since they don't execute JavaScript.\n * @default true\n */\n useEdge?: boolean;\n /** Request timeout in milliseconds (default: 5000) */\n timeout?: number;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Enforcement action — re-exported from `@kya-os/checkpoint-shared`\n * so consumers of this package can keep importing it from the same\n * place. The canonical 6-value union is defined in\n * `packages/checkpoint-shared/src/policy/constants.ts`. `'instruct'`\n * tells the middleware to emit a 401 with an MCP-I Link header\n * pointing the agent at a connect/consent URL.\n */\nexport type { EnforcementAction };\n\n/**\n * Enforcement decision from the API\n */\nexport interface EnforcementDecision {\n action: EnforcementAction;\n reason: string;\n isAgent: boolean;\n confidence: number;\n agentName?: string;\n agentType?: string;\n redirectUrl?: string;\n message?: string;\n metadata?: {\n policyVersion?: string;\n signatureVerified?: boolean;\n denyListMatch?: {\n clientDid?: string;\n agentDid?: string;\n clientName?: string;\n reason?: string;\n };\n };\n}\n\n/**\n * Detection result (optional in response)\n */\nexport interface DetectionResult {\n isAgent: boolean;\n confidence: number;\n agentName?: string;\n agentType?: string;\n /** Detection class: 'human', 'ai_agent', 'bot', 'incomplete_data' */\n detectionClass?: string;\n verificationMethod?: string;\n reasons?: string[];\n /** Detection engine used: 'wasm' or 'javascript-fallback' */\n detectionMethod?: string;\n}\n\n/**\n * Enforce API response\n */\nexport interface EnforceResponse {\n success: boolean;\n data?: {\n decision: EnforcementDecision;\n processingTimeMs: number;\n requestId: string;\n detection?: DetectionResult;\n };\n error?: {\n code: string;\n message: string;\n };\n}\n\n/**\n * Request input for enforce API\n */\nexport interface EnforceInput {\n /** HTTP headers from the incoming request */\n headers?: Record<string, string>;\n /** User-Agent header */\n userAgent?: string;\n /** Client IP address */\n ipAddress?: string;\n /** Request path */\n path?: string;\n /** Request URL */\n url?: string;\n /** HTTP method */\n method?: string;\n /** Request ID for tracing */\n requestId?: string;\n /** Options */\n options?: {\n /** Include full detection result */\n includeDetectionResult?: boolean;\n /** Cache TTL override */\n cacheTTL?: number;\n };\n}\n\n/**\n * Input for logging a detection result\n */\nexport interface LogDetectionInput {\n /** Detection result from Gateway */\n detection: DetectionResult;\n /** Request context */\n context: {\n userAgent?: string;\n ipAddress?: string;\n path?: string;\n url?: string;\n method?: string;\n };\n /** Source of the detection */\n source?: 'gateway' | 'middleware';\n}\n\n// ============================================================================\n// Client Implementation\n// ============================================================================\n\nconst DEFAULT_BASE_URL = 'https://kya.vouched.id';\nconst EDGE_DETECT_URL = 'https://detect.checkpoint-gateway.ai';\nconst DEFAULT_TIMEOUT = 5000;\n\n/**\n * AgentShield API Client\n *\n * @example\n * ```typescript\n * const client = new CheckpointApiClient({\n * apiKey: process.env.CHECKPOINT_API_KEY!,\n * });\n *\n * const result = await client.enforce({\n * headers: Object.fromEntries(request.headers),\n * path: request.nextUrl.pathname,\n * method: request.method,\n * });\n *\n * if (result.decision.action === 'block') {\n * return new Response('Access denied', { status: 403 });\n * }\n * ```\n */\nexport class CheckpointApiClient {\n private apiKey: string;\n private baseUrl: string;\n private useEdge: boolean;\n private timeout: number;\n private debug: boolean;\n\n constructor(config: CheckpointApiClientConfig) {\n if (!config.apiKey) {\n throw new Error('AgentShield API key is required');\n }\n\n this.apiKey = config.apiKey;\n // Default to edge detection for better coverage (detects non-JS clients)\n this.useEdge = config.useEdge !== false; // true by default\n this.baseUrl = config.baseUrl || (this.useEdge ? EDGE_DETECT_URL : DEFAULT_BASE_URL);\n this.timeout = config.timeout || DEFAULT_TIMEOUT;\n this.debug = config.debug || false;\n }\n\n /**\n * Call the enforce API to check if a request should be allowed\n */\n async enforce(input: EnforceInput): Promise<EnforceResponse> {\n const startTime = Date.now();\n\n try {\n // Create abort controller for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n // Use edge endpoint or Vercel API based on configuration\n const endpoint = this.useEdge\n ? `${this.baseUrl}/__detect/enforce`\n : `${this.baseUrl}/api/v1/enforce`;\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n 'X-Request-ID': input.requestId || crypto.randomUUID(),\n },\n body: JSON.stringify(input),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Parse response\n const data = (await response.json()) as EnforceResponse;\n\n if (this.debug) {\n console.log('[AgentShield] Enforce response:', {\n status: response.status,\n action: data.data?.decision.action,\n processingTimeMs: Date.now() - startTime,\n });\n }\n\n // Handle non-2xx responses\n if (!response.ok) {\n return {\n success: false,\n error: {\n code: `HTTP_${response.status}`,\n message: data.error?.message || `HTTP error: ${response.status}`,\n },\n };\n }\n\n return data;\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n } catch (error) {\n // Handle timeout\n if (error instanceof Error && error.name === 'AbortError') {\n if (this.debug) {\n console.warn('[AgentShield] Request timed out');\n }\n return {\n success: false,\n error: {\n code: 'TIMEOUT',\n message: `Request timed out after ${this.timeout}ms`,\n },\n };\n }\n\n // Handle network errors\n if (this.debug) {\n console.error('[AgentShield] Request failed:', error);\n }\n\n return {\n success: false,\n error: {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Network request failed',\n },\n };\n }\n }\n\n /**\n * Quick check - returns just the action without full response parsing\n * Useful for very fast middleware that just needs allow/block\n */\n async quickCheck(input: EnforceInput): Promise<{\n action: EnforcementAction;\n error?: string;\n }> {\n const result = await this.enforce(input);\n\n if (!result.success || !result.data) {\n // On error, default to allow (fail-open)\n return {\n action: 'allow',\n error: result.error?.message,\n };\n }\n\n return {\n action: result.data.decision.action,\n };\n }\n\n /**\n * Check if this client is using edge detection (Gateway Worker)\n */\n isUsingEdge(): boolean {\n return this.useEdge;\n }\n\n /**\n * Log a detection result to AgentShield database.\n * Use after Gateway Worker detection to persist results.\n * Fire-and-forget - returns immediately without waiting for DB write.\n *\n * @example\n * ```typescript\n * // After receiving Gateway response\n * if (client.isUsingEdge() && response.data?.detection) {\n * client.logDetection({\n * detection: response.data.detection,\n * context: { userAgent, ipAddress, path, url, method }\n * }).catch(err => console.error('Log failed:', err));\n * }\n * ```\n */\n async logDetection(input: LogDetectionInput): Promise<void> {\n // Don't await - fire and forget\n // Use the base URL (not edge) for logging since this goes to the main API\n const logEndpoint = this.useEdge\n ? `${DEFAULT_BASE_URL}/api/v1/log-detection`\n : `${this.baseUrl}/api/v1/log-detection`;\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(logEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n detection: {\n isAgent: input.detection.isAgent,\n confidence: input.detection.confidence,\n agentName: input.detection.agentName,\n agentType: input.detection.agentType,\n detectionClass: input.detection.detectionClass,\n verificationMethod: input.detection.verificationMethod,\n reasons: input.detection.reasons,\n },\n context: input.context,\n source: input.source || 'gateway',\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok && this.debug) {\n console.warn('[AgentShield] Log detection returned non-2xx:', response.status);\n }\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n } catch (error) {\n // Silently fail for fire-and-forget, but log in debug mode\n if (this.debug) {\n console.error('[AgentShield] Log detection failed:', error);\n }\n // Re-throw so caller can catch if needed\n throw error;\n }\n }\n}\n\n/**\n * Create a singleton client instance\n *\n * @example\n * ```typescript\n * // In middleware.ts\n * import { getCheckpointApiClient } from '@kya-os/checkpoint-nextjs';\n *\n * const client = getCheckpointApiClient();\n * ```\n */\nlet clientInstance: CheckpointApiClient | null = null;\n\nexport function getCheckpointApiClient(\n config?: Partial<CheckpointApiClientConfig>\n): CheckpointApiClient {\n if (!clientInstance) {\n const apiKey = config?.apiKey || process.env.CHECKPOINT_API_KEY;\n\n if (!apiKey) {\n throw new Error(\n 'AgentShield API key is required. Set CHECKPOINT_API_KEY environment variable or pass apiKey in config.'\n );\n }\n\n clientInstance = new CheckpointApiClient({\n apiKey,\n baseUrl: config?.baseUrl || process.env.AGENTSHIELD_API_URL,\n // Default to edge detection unless explicitly disabled\n useEdge: config?.useEdge ?? process.env.AGENTSHIELD_USE_EDGE !== 'false',\n timeout: config?.timeout,\n debug: config?.debug || process.env.AGENTSHIELD_DEBUG === 'true',\n });\n }\n\n return clientInstance;\n}\n\n/**\n * Reset the singleton client (useful for testing)\n */\nexport function resetCheckpointApiClient(): void {\n clientInstance = null;\n}\n\n// ---------------------------------------------------------------------------\n// Back-compat aliases (Phase D rename — `AgentShield*` → `CheckpointApi*`).\n//\n// The SaaS-API deployment shape is preserved post-Phase-D — it talks to\n// the Cloudflare DNS gateway and remains a supported deployment option\n// alongside the local-engine `withCheckpoint` path. The names changed\n// to align with the rest of the `checkpoint-*` packages; the old names\n// stay live as @deprecated aliases for one release.\n// ---------------------------------------------------------------------------\n\n/** @deprecated Renamed to {@link CheckpointApiClient}. The runtime is identical. */\nexport const AgentShieldClient = CheckpointApiClient;\n\n/** @deprecated Renamed to {@link CheckpointApiClientConfig}. */\nexport type AgentShieldClientConfig = CheckpointApiClientConfig;\n\n/** @deprecated Renamed to {@link getCheckpointApiClient}. */\nexport const getAgentShieldClient = getCheckpointApiClient;\n\n/** @deprecated Renamed to {@link resetCheckpointApiClient}. */\nexport const resetAgentShieldClient = resetCheckpointApiClient;\n"]}
@@ -0,0 +1,156 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { EnforcementDecision } from './api-client.mjs';
3
+ import '@kya-os/checkpoint-shared';
4
+
5
+ /**
6
+ * API-based AgentShield Middleware for Next.js
7
+ *
8
+ * This middleware uses the AgentShield API for detection and enforcement,
9
+ * instead of running detection locally. This approach:
10
+ *
11
+ * 1. Works reliably in Edge Runtime (no WASM loading issues)
12
+ * 2. Ensures consistent detection across all platforms
13
+ * 3. Applies centralized policies from the dashboard
14
+ * 4. Supports deny lists, thresholds, and path rules
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * // middleware.ts
19
+ * import { withCheckpointApi } from '@kya-os/checkpoint-nextjs/api-middleware';
20
+ *
21
+ * export default withCheckpointApi({
22
+ * apiKey: process.env.CHECKPOINT_API_KEY!,
23
+ * // Optional overrides:
24
+ * onBlock: 'redirect', // 'block' | 'redirect' | 'challenge'
25
+ * redirectUrl: '/blocked',
26
+ * skipPaths: ['/api/health', '/_next/*'],
27
+ * });
28
+ *
29
+ * export const config = {
30
+ * matcher: ['/((?!_next/static|favicon.ico).*)'],
31
+ * };
32
+ * ```
33
+ */
34
+
35
+ /**
36
+ * Middleware configuration
37
+ */
38
+ interface CheckpointApiMiddlewareConfig {
39
+ /** API key (or use CHECKPOINT_API_KEY env var) */
40
+ apiKey?: string;
41
+ /** API base URL (defaults to production) */
42
+ apiUrl?: string;
43
+ /**
44
+ * Use edge detection for lower latency (~30-50ms vs ~150ms) and better coverage.
45
+ * Edge detection can identify non-JS clients (curl, Python, Claude Code WebFetch)
46
+ * that the pixel cannot detect since they don't execute JavaScript.
47
+ * Set to false to use the Vercel API instead.
48
+ * @default true
49
+ */
50
+ useEdge?: boolean;
51
+ /** Request timeout in ms (default: 5000) */
52
+ timeout?: number;
53
+ /**
54
+ * Action to take when an agent should be blocked
55
+ * - 'block': Return 403 response
56
+ * - 'redirect': Redirect to redirectUrl
57
+ * - 'challenge': Show a challenge page (future)
58
+ * Default: uses policy from dashboard
59
+ */
60
+ onBlock?: 'block' | 'redirect' | 'challenge';
61
+ /**
62
+ * URL to redirect to when blocking (if onBlock is 'redirect')
63
+ * Default: uses redirectUrl from dashboard policy
64
+ */
65
+ redirectUrl?: string;
66
+ /**
67
+ * How the middleware handles a `redirect` / `instruct` action.
68
+ *
69
+ * - `'instruct'` (default): return HTTP 401 with an MCP-I Link header + JSON
70
+ * body pointing the agent at the redirect URL. LLMs surface the URL as a
71
+ * clickable link for the user. Matches the Cloudflare Gateway contract.
72
+ * - `'http'`: legacy behavior — return HTTP 302 with `Location`. Most LLM
73
+ * fetchers won't follow the redirect, so this is only useful when your
74
+ * traffic is real browsers.
75
+ *
76
+ * @default 'instruct'
77
+ */
78
+ redirectMode?: 'instruct' | 'http';
79
+ /**
80
+ * Custom blocked response
81
+ */
82
+ blockedResponse?: {
83
+ status?: number;
84
+ message?: string;
85
+ headers?: Record<string, string>;
86
+ };
87
+ /**
88
+ * Paths to skip (in addition to dashboard policy)
89
+ * Supports glob patterns: '/api/*', '/_next/*'
90
+ */
91
+ skipPaths?: string[];
92
+ /**
93
+ * Only enforce on these paths (overrides dashboard policy)
94
+ */
95
+ includePaths?: string[];
96
+ /**
97
+ * Callback when an agent is detected
98
+ */
99
+ onAgentDetected?: (request: NextRequest, decision: EnforcementDecision) => void | Promise<void>;
100
+ /**
101
+ * Callback to customize the blocked response
102
+ */
103
+ customBlockedResponse?: (request: NextRequest, decision: EnforcementDecision) => NextResponse | Promise<NextResponse>;
104
+ /**
105
+ * Whether to fail open (allow) on API errors
106
+ * Default: true (recommended for production)
107
+ */
108
+ failOpen?: boolean;
109
+ /**
110
+ * Enable debug logging
111
+ */
112
+ debug?: boolean;
113
+ }
114
+ /**
115
+ * Create AgentShield middleware with API-based detection
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * // middleware.ts
120
+ * import { withCheckpointApi } from '@kya-os/checkpoint-nextjs/api-middleware';
121
+ *
122
+ * export default withCheckpointApi({
123
+ * onBlock: 'block',
124
+ * skipPaths: ['/api/health'],
125
+ * });
126
+ * ```
127
+ */
128
+ declare function withCheckpointApi(config?: CheckpointApiMiddlewareConfig): (request: NextRequest) => Promise<NextResponse>;
129
+ /** @deprecated Renamed to {@link withCheckpointApi}. The behaviour is identical. */
130
+ declare const withAgentShield: typeof withCheckpointApi;
131
+ /** @deprecated Renamed to {@link CheckpointApiMiddlewareConfig}. */
132
+ type AgentShieldMiddlewareConfig = CheckpointApiMiddlewareConfig;
133
+ /**
134
+ * @deprecated Module-load-time invocation of the legacy `withAgentShield()`.
135
+ * Construct the middleware explicitly via `withCheckpointApi({ apiKey })`
136
+ * instead of relying on a default-constructed singleton at import time.
137
+ */
138
+ declare function agentShieldMiddleware(_request: NextRequest): Promise<NextResponse>;
139
+ /**
140
+ * @deprecated The "enhanced middleware" combined detection + storage +
141
+ * enforcement into a single legacy path that no longer exists. Migrate
142
+ * to `withCheckpoint` (local-engine) or `withCheckpointApi` (SaaS-gateway).
143
+ */
144
+ declare function createEnhancedAgentShieldMiddleware(_config?: EnhancedMiddlewareConfig): (request: NextRequest) => Promise<NextResponse>;
145
+ /** @deprecated The enhanced-middleware path is gone. Use `CheckpointConfig` (local-engine) or `CheckpointApiMiddlewareConfig` (SaaS). */
146
+ type EnhancedMiddlewareConfig = Record<string, unknown>;
147
+ /** @deprecated Storage was tied to the legacy enhanced-middleware path. */
148
+ type StorageAdapter = Record<string, unknown>;
149
+ /** @deprecated Storage was tied to the legacy enhanced-middleware path. */
150
+ type StorageConfig = Record<string, unknown>;
151
+ /** @deprecated Detection events now flow through the engine; the legacy event shape no longer applies. */
152
+ type AgentDetectionEvent = Record<string, unknown>;
153
+ /** @deprecated Use `EdgeSessionTracker` / `StatelessSessionChecker` from `./session-tracker`. */
154
+ type AgentSession = Record<string, unknown>;
155
+
156
+ export { type AgentDetectionEvent, type AgentSession, type AgentShieldMiddlewareConfig, type CheckpointApiMiddlewareConfig, type EnhancedMiddlewareConfig, type StorageAdapter, type StorageConfig, agentShieldMiddleware, createEnhancedAgentShieldMiddleware, withAgentShield, withCheckpointApi };