@kya-os/checkpoint-nextjs 1.1.0 → 1.1.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # @kya-os/checkpoint-nextjs
2
2
 
3
+ ## 1.1.1 — 2026-05-17
4
+
5
+ Companion patch to `@kya-os/checkpoint-wasm-runtime@1.1.0`'s
6
+ SDK-WASM-Bundler-Loader-1 fix. **All 1.1.0 users running under Next.js
7
+ Node runtime should upgrade** — `withCheckpoint` couldn't actually be
8
+ deployed under Next.js Node runtime in 1.1.0 due to a Turbopack-
9
+ incompatible URL trick in the wasm-runtime's orchestrator bundle.
10
+
11
+ ### Internal change
12
+
13
+ - `@kya-os/checkpoint-wasm-runtime` dep changed from exact `1.0.0`
14
+ pin (the `workspace:*` default) to `^1.1.0` range (via `workspace:^`).
15
+ Fresh installs now pull `wasm-runtime@1.1.0+`, which adds the
16
+ `"node"` export condition routing Next.js Node-runtime bundlers to
17
+ the bundler-clean `orchestrator-node.mjs` entry.
18
+
19
+ ### No code or config changes
20
+
21
+ Customer middleware.ts call site is unchanged. Verifying envelopes
22
+ under Next.js Node runtime now works end-to-end:
23
+
24
+ ```typescript
25
+ import { withCheckpoint } from '@kya-os/checkpoint-nextjs';
26
+
27
+ export default withCheckpoint({
28
+ tenantHost: 'acme.checkpoint.example',
29
+ legacyEnvelopeFallback: true,
30
+ });
31
+ ```
32
+
33
+ See `@kya-os/checkpoint-wasm-runtime@1.1.0` CHANGELOG for the
34
+ architectural detail.
35
+
36
+ ---
37
+
3
38
  ## 1.1.0 — 2026-05-17
4
39
 
5
40
  Closes [SDK-Envelope-Plumbing-1 (#2594)](https://github.com/Know-That-Ai/agent-shield/issues/2594).
@@ -1,10 +1,37 @@
1
1
  import { NextRequest } from 'next/server';
2
2
 
3
3
  /**
4
- * Edge Runtime Compatible WASM Loader for AgentShield
4
+ * Edge Runtime Compatible WASM Loader for Checkpoint
5
5
  *
6
6
  * This module provides a pre-built solution for loading WASM in Edge Runtime.
7
7
  * It requires the WASM file to be manually placed in the project.
8
+ *
9
+ * ## SSOT for pattern detection
10
+ *
11
+ * The fallback `patternDetection` path imports BOTH pattern arrays
12
+ * from `@kya-os/checkpoint-shared/constants/agents`:
13
+ *
14
+ * - `KNOWN_AGENT_PATTERNS` — strict SSOT carved for the server-side
15
+ * classifier (per-agent rows with category + isLegitimate fields).
16
+ * - `INTERACTIVE_AGENT_PATTERNS` — supplement holding interactive-
17
+ * session tokens, generic vendor fallbacks, and the GPT-Crawler
18
+ * entry that lives in seed-agent-types-data.ts (NOT in the strict
19
+ * SSOT).
20
+ *
21
+ * Pre-#2599 this file had a 15-pattern inline subset that diverged
22
+ * from the shared SSOT — the you.com regex was tightened in agents.ts
23
+ * but reverted here. SSOT-Fallback-Drift-1 (this PR) collapsed the
24
+ * inline duplication and moved the supplement into checkpoint-shared
25
+ * so both layers reference the same source. EPIC #2573 (PDM-2) is the
26
+ * future unified-SSOT consolidation that folds the two arrays into
27
+ * one canonical table.
28
+ *
29
+ * ## Naming
30
+ *
31
+ * Old `AgentShield`-prefixed exports are kept as `@deprecated` aliases
32
+ * for one release (`createEdgeAgentShield`, `EdgeRuntimeAgentShield`,
33
+ * `AgentShieldConfig`, `getDefaultAgentShield`). New code should import
34
+ * the `Checkpoint`-prefixed names directly.
8
35
  */
9
36
 
10
37
  interface WasmModule {
@@ -19,7 +46,7 @@ interface DetectionResult {
19
46
  riskLevel?: 'low' | 'medium' | 'high' | 'critical';
20
47
  timestamp: string;
21
48
  }
22
- interface AgentShieldConfig {
49
+ interface EdgeCheckpointConfig {
23
50
  wasmModule?: WebAssembly.Module;
24
51
  enableWasm?: boolean;
25
52
  onAgentDetected?: (result: DetectionResult) => void;
@@ -27,12 +54,12 @@ interface AgentShieldConfig {
27
54
  allowedAgents?: string[];
28
55
  debug?: boolean;
29
56
  }
30
- declare class EdgeRuntimeAgentShield {
57
+ declare class EdgeRuntimeCheckpoint {
31
58
  private wasmInstance;
32
59
  private wasmMemory;
33
60
  private config;
34
61
  private initialized;
35
- constructor(config?: AgentShieldConfig);
62
+ constructor(config?: EdgeCheckpointConfig);
36
63
  init(wasmModule?: WebAssembly.Module): Promise<void>;
37
64
  private readString;
38
65
  private writeString;
@@ -42,9 +69,18 @@ declare class EdgeRuntimeAgentShield {
42
69
  getVerificationMethod(): 'cryptographic' | 'pattern';
43
70
  }
44
71
  /**
45
- * Factory function to create an AgentShield instance for Edge Runtime
72
+ * Factory function to create a Checkpoint instance for Edge Runtime.
46
73
  */
47
- declare function createEdgeAgentShield(config?: AgentShieldConfig): EdgeRuntimeAgentShield;
48
- declare function getDefaultAgentShield(config?: AgentShieldConfig): EdgeRuntimeAgentShield;
74
+ declare function createEdgeCheckpoint(config?: EdgeCheckpointConfig): EdgeRuntimeCheckpoint;
75
+ declare function getDefaultEdgeCheckpoint(config?: EdgeCheckpointConfig): EdgeRuntimeCheckpoint;
76
+
77
+ /** @deprecated Renamed to {@link EdgeCheckpointConfig}. */
78
+ type AgentShieldConfig = EdgeCheckpointConfig;
79
+ /** @deprecated Renamed to {@link EdgeRuntimeCheckpoint}. */
80
+ declare const EdgeRuntimeAgentShield: typeof EdgeRuntimeCheckpoint;
81
+ /** @deprecated Renamed to {@link createEdgeCheckpoint}. */
82
+ declare const createEdgeAgentShield: typeof createEdgeCheckpoint;
83
+ /** @deprecated Renamed to {@link getDefaultEdgeCheckpoint}. */
84
+ declare const getDefaultAgentShield: typeof getDefaultEdgeCheckpoint;
49
85
 
50
- export { type AgentShieldConfig, type DetectionResult, type WasmModule, createEdgeAgentShield, getDefaultAgentShield };
86
+ export { type AgentShieldConfig, type DetectionResult, type EdgeCheckpointConfig, EdgeRuntimeAgentShield, EdgeRuntimeCheckpoint, type WasmModule, createEdgeAgentShield, createEdgeCheckpoint, getDefaultAgentShield, getDefaultEdgeCheckpoint };
@@ -1,10 +1,37 @@
1
1
  import { NextRequest } from 'next/server';
2
2
 
3
3
  /**
4
- * Edge Runtime Compatible WASM Loader for AgentShield
4
+ * Edge Runtime Compatible WASM Loader for Checkpoint
5
5
  *
6
6
  * This module provides a pre-built solution for loading WASM in Edge Runtime.
7
7
  * It requires the WASM file to be manually placed in the project.
8
+ *
9
+ * ## SSOT for pattern detection
10
+ *
11
+ * The fallback `patternDetection` path imports BOTH pattern arrays
12
+ * from `@kya-os/checkpoint-shared/constants/agents`:
13
+ *
14
+ * - `KNOWN_AGENT_PATTERNS` — strict SSOT carved for the server-side
15
+ * classifier (per-agent rows with category + isLegitimate fields).
16
+ * - `INTERACTIVE_AGENT_PATTERNS` — supplement holding interactive-
17
+ * session tokens, generic vendor fallbacks, and the GPT-Crawler
18
+ * entry that lives in seed-agent-types-data.ts (NOT in the strict
19
+ * SSOT).
20
+ *
21
+ * Pre-#2599 this file had a 15-pattern inline subset that diverged
22
+ * from the shared SSOT — the you.com regex was tightened in agents.ts
23
+ * but reverted here. SSOT-Fallback-Drift-1 (this PR) collapsed the
24
+ * inline duplication and moved the supplement into checkpoint-shared
25
+ * so both layers reference the same source. EPIC #2573 (PDM-2) is the
26
+ * future unified-SSOT consolidation that folds the two arrays into
27
+ * one canonical table.
28
+ *
29
+ * ## Naming
30
+ *
31
+ * Old `AgentShield`-prefixed exports are kept as `@deprecated` aliases
32
+ * for one release (`createEdgeAgentShield`, `EdgeRuntimeAgentShield`,
33
+ * `AgentShieldConfig`, `getDefaultAgentShield`). New code should import
34
+ * the `Checkpoint`-prefixed names directly.
8
35
  */
9
36
 
10
37
  interface WasmModule {
@@ -19,7 +46,7 @@ interface DetectionResult {
19
46
  riskLevel?: 'low' | 'medium' | 'high' | 'critical';
20
47
  timestamp: string;
21
48
  }
22
- interface AgentShieldConfig {
49
+ interface EdgeCheckpointConfig {
23
50
  wasmModule?: WebAssembly.Module;
24
51
  enableWasm?: boolean;
25
52
  onAgentDetected?: (result: DetectionResult) => void;
@@ -27,12 +54,12 @@ interface AgentShieldConfig {
27
54
  allowedAgents?: string[];
28
55
  debug?: boolean;
29
56
  }
30
- declare class EdgeRuntimeAgentShield {
57
+ declare class EdgeRuntimeCheckpoint {
31
58
  private wasmInstance;
32
59
  private wasmMemory;
33
60
  private config;
34
61
  private initialized;
35
- constructor(config?: AgentShieldConfig);
62
+ constructor(config?: EdgeCheckpointConfig);
36
63
  init(wasmModule?: WebAssembly.Module): Promise<void>;
37
64
  private readString;
38
65
  private writeString;
@@ -42,9 +69,18 @@ declare class EdgeRuntimeAgentShield {
42
69
  getVerificationMethod(): 'cryptographic' | 'pattern';
43
70
  }
44
71
  /**
45
- * Factory function to create an AgentShield instance for Edge Runtime
72
+ * Factory function to create a Checkpoint instance for Edge Runtime.
46
73
  */
47
- declare function createEdgeAgentShield(config?: AgentShieldConfig): EdgeRuntimeAgentShield;
48
- declare function getDefaultAgentShield(config?: AgentShieldConfig): EdgeRuntimeAgentShield;
74
+ declare function createEdgeCheckpoint(config?: EdgeCheckpointConfig): EdgeRuntimeCheckpoint;
75
+ declare function getDefaultEdgeCheckpoint(config?: EdgeCheckpointConfig): EdgeRuntimeCheckpoint;
76
+
77
+ /** @deprecated Renamed to {@link EdgeCheckpointConfig}. */
78
+ type AgentShieldConfig = EdgeCheckpointConfig;
79
+ /** @deprecated Renamed to {@link EdgeRuntimeCheckpoint}. */
80
+ declare const EdgeRuntimeAgentShield: typeof EdgeRuntimeCheckpoint;
81
+ /** @deprecated Renamed to {@link createEdgeCheckpoint}. */
82
+ declare const createEdgeAgentShield: typeof createEdgeCheckpoint;
83
+ /** @deprecated Renamed to {@link getDefaultEdgeCheckpoint}. */
84
+ declare const getDefaultAgentShield: typeof getDefaultEdgeCheckpoint;
49
85
 
50
- export { type AgentShieldConfig, type DetectionResult, type WasmModule, createEdgeAgentShield, getDefaultAgentShield };
86
+ export { type AgentShieldConfig, type DetectionResult, type EdgeCheckpointConfig, EdgeRuntimeAgentShield, EdgeRuntimeCheckpoint, type WasmModule, createEdgeAgentShield, createEdgeCheckpoint, getDefaultAgentShield, getDefaultEdgeCheckpoint };
@@ -1,5 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ var checkpointShared = require('@kya-os/checkpoint-shared');
4
+
5
+ // src/edge-runtime-loader.ts
6
+
3
7
  // src/utils.ts
4
8
  function getClientIp(request) {
5
9
  const forwardedFor = request.headers.get("x-forwarded-for");
@@ -17,7 +21,40 @@ function getClientIp(request) {
17
21
  }
18
22
 
19
23
  // src/edge-runtime-loader.ts
20
- var EdgeRuntimeAgentShield = class {
24
+ var SUSPICIOUS_HEADER_PREFIXES = ["x-openai-", "x-anthropic-", "x-ai-", "x-llm-", "x-gpt-"];
25
+ function escapeRegex(s) {
26
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
27
+ }
28
+ var TOKEN_REGEX_CACHE = /* @__PURE__ */ new Map();
29
+ function tokenRegex(token) {
30
+ const cached = TOKEN_REGEX_CACHE.get(token);
31
+ if (cached) return cached;
32
+ const regex = new RegExp(`\\b${escapeRegex(token)}\\b`, "i");
33
+ TOKEN_REGEX_CACHE.set(token, regex);
34
+ return regex;
35
+ }
36
+ function matchKnownAgent(lowercasedUa) {
37
+ let best = null;
38
+ for (const entry of checkpointShared.KNOWN_AGENT_PATTERNS) {
39
+ for (const pattern of entry.patterns) {
40
+ if (tokenRegex(pattern).test(lowercasedUa)) {
41
+ if (!best || entry.confidence > best.confidence) {
42
+ best = { name: entry.name, confidence: entry.confidence };
43
+ }
44
+ break;
45
+ }
46
+ }
47
+ }
48
+ for (const { pattern, name, confidence } of checkpointShared.INTERACTIVE_AGENT_PATTERNS) {
49
+ if (pattern.test(lowercasedUa)) {
50
+ if (!best || confidence > best.confidence) {
51
+ best = { name, confidence };
52
+ }
53
+ }
54
+ }
55
+ return best;
56
+ }
57
+ var EdgeRuntimeCheckpoint = class {
21
58
  wasmInstance = null;
22
59
  wasmMemory = null;
23
60
  config;
@@ -49,7 +86,7 @@ var EdgeRuntimeAgentShield = class {
49
86
  this.wasmInstance = await WebAssembly.instantiate(module, imports);
50
87
  this.initialized = true;
51
88
  if (this.config.debug) {
52
- console.log("\u2705 AgentShield WASM initialized in Edge Runtime");
89
+ console.log("\u2705 Checkpoint WASM initialized in Edge Runtime");
53
90
  }
54
91
  } catch (error) {
55
92
  console.warn("\u26A0\uFE0F WASM initialization failed, using pattern detection:", error);
@@ -126,59 +163,29 @@ var EdgeRuntimeAgentShield = class {
126
163
  return this.patternDetection(metadata);
127
164
  }
128
165
  patternDetection(metadata) {
129
- const userAgent = metadata.userAgent.toLowerCase();
130
- const patterns = [
131
- // High confidence - explicit AI identifiers
132
- { pattern: /chatgpt-user/i, name: "ChatGPT", confidence: 0.95 },
133
- { pattern: /claude-web/i, name: "Claude", confidence: 0.95 },
134
- { pattern: /claude-user/i, name: "Claude", confidence: 0.95 },
135
- { pattern: /gpt-crawler/i, name: "GPT Crawler", confidence: 0.95 },
136
- { pattern: /perplexitybot/i, name: "Perplexity", confidence: 0.95 },
137
- { pattern: /perplexity-user/i, name: "Perplexity", confidence: 0.95 },
138
- { pattern: /perplexity-ai/i, name: "Perplexity", confidence: 0.95 },
139
- // Medium-high confidence - company identifiers
140
- { pattern: /anthropic/i, name: "Anthropic", confidence: 0.9 },
141
- { pattern: /openai/i, name: "OpenAI", confidence: 0.9 },
142
- // Medium confidence - product names
143
- { pattern: /copilot/i, name: "GitHub Copilot", confidence: 0.85 },
144
- { pattern: /bard/i, name: "Google Bard", confidence: 0.85 },
145
- { pattern: /gemini/i, name: "Google Gemini", confidence: 0.85 },
146
- { pattern: /perplexity/i, name: "Perplexity", confidence: 0.85 },
147
- // Fallback
148
- // UA-context-only pattern — `\b` is the correct anchor for UA
149
- // substring matching. PR #2591's tightened `[\s;()]` form
150
- // dropped `/`, which broke legit UA shapes like `you.com/1.0`
151
- // and `+https://you.com)` (cursor catch on the same PR — see
152
- // sibling agents.ts comment for the full rationale + UA shapes).
153
- // CodeQL js/regex/missing-regexp-anchor speculates about URL
154
- // misuse; this codebase only applies the pattern to UA strings.
155
- { pattern: /\byou\.com\b/i, name: "You.com", confidence: 0.8 },
156
- { pattern: /\bphind\b/i, name: "Phind", confidence: 0.8 }
157
- ];
158
- const suspiciousHeaders = ["x-openai-", "x-anthropic-", "x-ai-", "x-llm-", "x-gpt-"];
166
+ const lowercasedUa = metadata.userAgent.toLowerCase();
159
167
  let headerBoost = 0;
160
- for (const [key] of Object.entries(metadata.headers)) {
161
- if (suspiciousHeaders.some((prefix) => key.toLowerCase().startsWith(prefix))) {
168
+ for (const key of Object.keys(metadata.headers)) {
169
+ if (SUSPICIOUS_HEADER_PREFIXES.some((prefix) => key.toLowerCase().startsWith(prefix))) {
162
170
  headerBoost = 0.1;
163
171
  break;
164
172
  }
165
173
  }
166
- for (const { pattern, name, confidence } of patterns) {
167
- if (pattern.test(userAgent)) {
168
- const finalConfidence = Math.min(confidence + headerBoost, 1);
169
- const result = {
170
- isAgent: true,
171
- confidence: finalConfidence,
172
- agent: name,
173
- verificationMethod: "pattern",
174
- riskLevel: finalConfidence > 0.9 ? "high" : "medium",
175
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
176
- };
177
- if (this.config.onAgentDetected) {
178
- this.config.onAgentDetected(result);
179
- }
180
- return result;
174
+ const match = matchKnownAgent(lowercasedUa);
175
+ if (match) {
176
+ const finalConfidence = Math.min(match.confidence + headerBoost, 1);
177
+ const result = {
178
+ isAgent: true,
179
+ confidence: finalConfidence,
180
+ agent: match.name,
181
+ verificationMethod: "pattern",
182
+ riskLevel: finalConfidence > 0.9 ? "high" : "medium",
183
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
184
+ };
185
+ if (this.config.onAgentDetected) {
186
+ this.config.onAgentDetected(result);
181
187
  }
188
+ return result;
182
189
  }
183
190
  return {
184
191
  isAgent: false,
@@ -194,16 +201,23 @@ var EdgeRuntimeAgentShield = class {
194
201
  return this.wasmInstance ? "cryptographic" : "pattern";
195
202
  }
196
203
  };
197
- function createEdgeAgentShield(config) {
198
- return new EdgeRuntimeAgentShield(config);
204
+ function createEdgeCheckpoint(config) {
205
+ return new EdgeRuntimeCheckpoint(config);
199
206
  }
200
207
  var defaultInstance = null;
201
- function getDefaultAgentShield(config) {
208
+ function getDefaultEdgeCheckpoint(config) {
202
209
  if (!defaultInstance) {
203
- defaultInstance = new EdgeRuntimeAgentShield(config);
210
+ defaultInstance = new EdgeRuntimeCheckpoint(config);
204
211
  }
205
212
  return defaultInstance;
206
213
  }
214
+ var EdgeRuntimeAgentShield = EdgeRuntimeCheckpoint;
215
+ var createEdgeAgentShield = createEdgeCheckpoint;
216
+ var getDefaultAgentShield = getDefaultEdgeCheckpoint;
207
217
 
218
+ exports.EdgeRuntimeAgentShield = EdgeRuntimeAgentShield;
219
+ exports.EdgeRuntimeCheckpoint = EdgeRuntimeCheckpoint;
208
220
  exports.createEdgeAgentShield = createEdgeAgentShield;
221
+ exports.createEdgeCheckpoint = createEdgeCheckpoint;
209
222
  exports.getDefaultAgentShield = getDefaultAgentShield;
223
+ exports.getDefaultEdgeCheckpoint = getDefaultEdgeCheckpoint;
@@ -1,3 +1,7 @@
1
+ import { KNOWN_AGENT_PATTERNS, INTERACTIVE_AGENT_PATTERNS } from '@kya-os/checkpoint-shared';
2
+
3
+ // src/edge-runtime-loader.ts
4
+
1
5
  // src/utils.ts
2
6
  function getClientIp(request) {
3
7
  const forwardedFor = request.headers.get("x-forwarded-for");
@@ -15,7 +19,40 @@ function getClientIp(request) {
15
19
  }
16
20
 
17
21
  // src/edge-runtime-loader.ts
18
- var EdgeRuntimeAgentShield = class {
22
+ var SUSPICIOUS_HEADER_PREFIXES = ["x-openai-", "x-anthropic-", "x-ai-", "x-llm-", "x-gpt-"];
23
+ function escapeRegex(s) {
24
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
25
+ }
26
+ var TOKEN_REGEX_CACHE = /* @__PURE__ */ new Map();
27
+ function tokenRegex(token) {
28
+ const cached = TOKEN_REGEX_CACHE.get(token);
29
+ if (cached) return cached;
30
+ const regex = new RegExp(`\\b${escapeRegex(token)}\\b`, "i");
31
+ TOKEN_REGEX_CACHE.set(token, regex);
32
+ return regex;
33
+ }
34
+ function matchKnownAgent(lowercasedUa) {
35
+ let best = null;
36
+ for (const entry of KNOWN_AGENT_PATTERNS) {
37
+ for (const pattern of entry.patterns) {
38
+ if (tokenRegex(pattern).test(lowercasedUa)) {
39
+ if (!best || entry.confidence > best.confidence) {
40
+ best = { name: entry.name, confidence: entry.confidence };
41
+ }
42
+ break;
43
+ }
44
+ }
45
+ }
46
+ for (const { pattern, name, confidence } of INTERACTIVE_AGENT_PATTERNS) {
47
+ if (pattern.test(lowercasedUa)) {
48
+ if (!best || confidence > best.confidence) {
49
+ best = { name, confidence };
50
+ }
51
+ }
52
+ }
53
+ return best;
54
+ }
55
+ var EdgeRuntimeCheckpoint = class {
19
56
  wasmInstance = null;
20
57
  wasmMemory = null;
21
58
  config;
@@ -47,7 +84,7 @@ var EdgeRuntimeAgentShield = class {
47
84
  this.wasmInstance = await WebAssembly.instantiate(module, imports);
48
85
  this.initialized = true;
49
86
  if (this.config.debug) {
50
- console.log("\u2705 AgentShield WASM initialized in Edge Runtime");
87
+ console.log("\u2705 Checkpoint WASM initialized in Edge Runtime");
51
88
  }
52
89
  } catch (error) {
53
90
  console.warn("\u26A0\uFE0F WASM initialization failed, using pattern detection:", error);
@@ -124,59 +161,29 @@ var EdgeRuntimeAgentShield = class {
124
161
  return this.patternDetection(metadata);
125
162
  }
126
163
  patternDetection(metadata) {
127
- const userAgent = metadata.userAgent.toLowerCase();
128
- const patterns = [
129
- // High confidence - explicit AI identifiers
130
- { pattern: /chatgpt-user/i, name: "ChatGPT", confidence: 0.95 },
131
- { pattern: /claude-web/i, name: "Claude", confidence: 0.95 },
132
- { pattern: /claude-user/i, name: "Claude", confidence: 0.95 },
133
- { pattern: /gpt-crawler/i, name: "GPT Crawler", confidence: 0.95 },
134
- { pattern: /perplexitybot/i, name: "Perplexity", confidence: 0.95 },
135
- { pattern: /perplexity-user/i, name: "Perplexity", confidence: 0.95 },
136
- { pattern: /perplexity-ai/i, name: "Perplexity", confidence: 0.95 },
137
- // Medium-high confidence - company identifiers
138
- { pattern: /anthropic/i, name: "Anthropic", confidence: 0.9 },
139
- { pattern: /openai/i, name: "OpenAI", confidence: 0.9 },
140
- // Medium confidence - product names
141
- { pattern: /copilot/i, name: "GitHub Copilot", confidence: 0.85 },
142
- { pattern: /bard/i, name: "Google Bard", confidence: 0.85 },
143
- { pattern: /gemini/i, name: "Google Gemini", confidence: 0.85 },
144
- { pattern: /perplexity/i, name: "Perplexity", confidence: 0.85 },
145
- // Fallback
146
- // UA-context-only pattern — `\b` is the correct anchor for UA
147
- // substring matching. PR #2591's tightened `[\s;()]` form
148
- // dropped `/`, which broke legit UA shapes like `you.com/1.0`
149
- // and `+https://you.com)` (cursor catch on the same PR — see
150
- // sibling agents.ts comment for the full rationale + UA shapes).
151
- // CodeQL js/regex/missing-regexp-anchor speculates about URL
152
- // misuse; this codebase only applies the pattern to UA strings.
153
- { pattern: /\byou\.com\b/i, name: "You.com", confidence: 0.8 },
154
- { pattern: /\bphind\b/i, name: "Phind", confidence: 0.8 }
155
- ];
156
- const suspiciousHeaders = ["x-openai-", "x-anthropic-", "x-ai-", "x-llm-", "x-gpt-"];
164
+ const lowercasedUa = metadata.userAgent.toLowerCase();
157
165
  let headerBoost = 0;
158
- for (const [key] of Object.entries(metadata.headers)) {
159
- if (suspiciousHeaders.some((prefix) => key.toLowerCase().startsWith(prefix))) {
166
+ for (const key of Object.keys(metadata.headers)) {
167
+ if (SUSPICIOUS_HEADER_PREFIXES.some((prefix) => key.toLowerCase().startsWith(prefix))) {
160
168
  headerBoost = 0.1;
161
169
  break;
162
170
  }
163
171
  }
164
- for (const { pattern, name, confidence } of patterns) {
165
- if (pattern.test(userAgent)) {
166
- const finalConfidence = Math.min(confidence + headerBoost, 1);
167
- const result = {
168
- isAgent: true,
169
- confidence: finalConfidence,
170
- agent: name,
171
- verificationMethod: "pattern",
172
- riskLevel: finalConfidence > 0.9 ? "high" : "medium",
173
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
174
- };
175
- if (this.config.onAgentDetected) {
176
- this.config.onAgentDetected(result);
177
- }
178
- return result;
172
+ const match = matchKnownAgent(lowercasedUa);
173
+ if (match) {
174
+ const finalConfidence = Math.min(match.confidence + headerBoost, 1);
175
+ const result = {
176
+ isAgent: true,
177
+ confidence: finalConfidence,
178
+ agent: match.name,
179
+ verificationMethod: "pattern",
180
+ riskLevel: finalConfidence > 0.9 ? "high" : "medium",
181
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
182
+ };
183
+ if (this.config.onAgentDetected) {
184
+ this.config.onAgentDetected(result);
179
185
  }
186
+ return result;
180
187
  }
181
188
  return {
182
189
  isAgent: false,
@@ -192,15 +199,18 @@ var EdgeRuntimeAgentShield = class {
192
199
  return this.wasmInstance ? "cryptographic" : "pattern";
193
200
  }
194
201
  };
195
- function createEdgeAgentShield(config) {
196
- return new EdgeRuntimeAgentShield(config);
202
+ function createEdgeCheckpoint(config) {
203
+ return new EdgeRuntimeCheckpoint(config);
197
204
  }
198
205
  var defaultInstance = null;
199
- function getDefaultAgentShield(config) {
206
+ function getDefaultEdgeCheckpoint(config) {
200
207
  if (!defaultInstance) {
201
- defaultInstance = new EdgeRuntimeAgentShield(config);
208
+ defaultInstance = new EdgeRuntimeCheckpoint(config);
202
209
  }
203
210
  return defaultInstance;
204
211
  }
212
+ var EdgeRuntimeAgentShield = EdgeRuntimeCheckpoint;
213
+ var createEdgeAgentShield = createEdgeCheckpoint;
214
+ var getDefaultAgentShield = getDefaultEdgeCheckpoint;
205
215
 
206
- export { createEdgeAgentShield, getDefaultAgentShield };
216
+ export { EdgeRuntimeAgentShield, EdgeRuntimeCheckpoint, createEdgeAgentShield, createEdgeCheckpoint, getDefaultAgentShield, getDefaultEdgeCheckpoint };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kya-os/checkpoint-nextjs",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Checkpoint Next.js middleware for AI agent detection (formerly @kya-os/agentshield-nextjs)",
5
5
  "keywords": [
6
6
  "nextjs",
@@ -135,8 +135,8 @@
135
135
  "@noble/ed25519": "^2.2.3",
136
136
  "@noble/hashes": "^2.0.1",
137
137
  "@kya-os/checkpoint": "1.0.0",
138
- "@kya-os/checkpoint-wasm-runtime": "1.0.0",
139
- "@kya-os/checkpoint-shared": "1.0.0"
138
+ "@kya-os/checkpoint-shared": "1.0.0",
139
+ "@kya-os/checkpoint-wasm-runtime": "^1.1.0"
140
140
  },
141
141
  "scripts": {
142
142
  "build": "tsup",