@wardnmesh/sdk-node 0.4.1 → 0.4.5

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 ADDED
@@ -0,0 +1,147 @@
1
+ # Changelog
2
+
3
+ All notable changes to @wardnmesh/sdk-node will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.4.0] - 2026-01-17
9
+
10
+ ### 🚨 Breaking Changes
11
+
12
+ **Action-Based Architecture**: Replaces boolean `allowed` field with granular action types.
13
+
14
+ - **`ScanResult.allowed` → `ScanResult.action`**
15
+ - Type: `boolean` → `ThreatAction` (`'block'` | `'confirm'` | `'warn'` | `'log'` | `'allow'`)
16
+ - Provides fine-grained control over threat response
17
+ - Enables user confirmation for high-risk operations
18
+
19
+ ### Added
20
+
21
+ - **Confirmation Support** (`action: 'confirm'`)
22
+ - New `confirmationDetails` field in `ScanResult`
23
+ - Pre-formatted confirmation messages with context
24
+ - Configurable timeout and default action
25
+ - Designed for user approval dialogs in CLI/UI
26
+
27
+ - **Action Priority System**
28
+ - `determineAction()` method with priority: `block` > `confirm` > `warn` > `log` > `allow`
29
+ - Defensive fail-closed design: defaults to `'block'` on invalid actions
30
+ - Comprehensive validation with fallback safety
31
+
32
+ - **Enhanced Violation Metadata**
33
+ - Added `recommendedAction: ThreatAction` field to `Violation`
34
+ - Added `scope: string` field for categorization
35
+ - Richer context for decision-making
36
+
37
+ ### Changed
38
+
39
+ - **Core API**: `scan()` now returns `action` instead of `allowed`
40
+ - **Middleware**: Callbacks now receive full `ScanResult` instead of just `violations`
41
+ - **Error Handling**: Invalid `recommendedAction` values trigger warnings and fail-closed
42
+
43
+ ### Fixed
44
+
45
+ - **Defensive Design**: Prevents security bypass from missing/invalid `recommendedAction`
46
+ - **Type Safety**: All violation fields properly validated before action determination
47
+
48
+ ### Migration
49
+
50
+ See [MIGRATION_v0.4.0.md](MIGRATION_v0.4.0.md) for detailed upgrade guide.
51
+
52
+ **Quick Migration**:
53
+ ```typescript
54
+ // Before (v0.2.3)
55
+ if (!result.allowed) { throw new Error('Blocked'); }
56
+
57
+ // After (v0.4.0)
58
+ if (result.action === 'block') { throw new Error('Blocked'); }
59
+ ```
60
+
61
+ ### Testing
62
+
63
+ - ✅ 17 tests passing (4 test suites)
64
+ - ✅ All action types validated
65
+ - ✅ Confirmation flow tested
66
+ - ✅ Fail-closed behavior verified
67
+
68
+ ---
69
+
70
+ ## [0.2.3] - 2026-01-16
71
+
72
+ ### Fixed
73
+
74
+ - Improved severity-to-action mapping in integrations
75
+ - Enhanced error handling with better null checks
76
+
77
+ ### Documentation
78
+
79
+ - Updated examples with current API patterns
80
+ - Clarified rule configuration options
81
+
82
+ ---
83
+
84
+ ## [0.2.0] - 2026-01-15
85
+
86
+ ### Added
87
+
88
+ - **Semantic Analysis**: ML-based threat detection using local models
89
+ - **State Tracking**: Session-aware detection for multi-turn attacks
90
+ - **Pattern Detectors**: Regex-based threat pattern matching
91
+ - **Sequence Detectors**: Multi-step attack pattern recognition
92
+
93
+ ### Changed
94
+
95
+ - Unified detector API for all detection types
96
+ - Improved telemetry with detailed metrics
97
+
98
+ ### Performance
99
+
100
+ - <20ms latency for most scans
101
+ - Local-first processing (no external API calls)
102
+ - Lazy loading for ML models
103
+
104
+ ---
105
+
106
+ ## [0.1.0] - 2026-01-10
107
+
108
+ ### Added
109
+
110
+ - Initial release of WardnMesh SDK for Node.js
111
+ - Core `Wardn` class with singleton pattern
112
+ - Basic threat detection for:
113
+ - PII (Personal Identifiable Information)
114
+ - Prompt injection patterns
115
+ - API key leakage
116
+ - Express middleware support
117
+ - Next.js middleware support
118
+ - Vercel AI SDK integration
119
+ - Local rule management
120
+
121
+ ### Features
122
+
123
+ - Rule-based scanning engine
124
+ - Configurable severity levels
125
+ - Telemetry and reporting
126
+ - Extensible detector system
127
+ - TypeScript support with full type definitions
128
+
129
+ ---
130
+
131
+ ## Version Compatibility
132
+
133
+ | SDK Version | MCP Server | Node.js | Status |
134
+ |-------------|------------|---------|--------|
135
+ | 0.4.0 | 0.2.3+ | 18+ | ✅ Current |
136
+ | 0.2.3 | 0.2.0+ | 18+ | ⚠️ Legacy |
137
+ | 0.2.0 | 0.2.0+ | 18+ | ⚠️ Legacy |
138
+ | 0.1.0 | 0.1.0+ | 18+ | ❌ Deprecated |
139
+
140
+ ---
141
+
142
+ ## Links
143
+
144
+ - [NPM Package](https://www.npmjs.com/package/@wardnmesh/sdk-node)
145
+ - [GitHub Repository](https://github.com/PCIRCLE-AI/wardnmesh)
146
+ - [Documentation](https://wardnmesh.ai/docs/sdk)
147
+ - [Migration Guides](MIGRATION_v0.4.0.md)
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @wardnmesh/sdk-node
2
2
 
3
- > **Latest Version: v0.4.0** (Released 2026-01-17)
3
+ > **Latest Version: v0.4.5** (Released 2026-01-19)
4
4
 
5
5
  **WardnMesh.AI** (formerly AgentGuard) is an active defense middleware for AI Agents. This SDK allows you to verify LLM inputs/outputs, block prompt injections, and prevent data exfiltration in real-time.
6
6
 
@@ -26,9 +26,9 @@
26
26
  ## Installation
27
27
 
28
28
  ```bash
29
- npm install @wardnmesh/sdk-node@0.4.0
29
+ npm install @wardnmesh/sdk-node@latest
30
30
  # or
31
- yarn add @wardnmesh/sdk-node@0.4.0
31
+ yarn add @wardnmesh/sdk-node@latest
32
32
  ```
33
33
 
34
34
  ## v0.4.0 API Overview
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wardnmesh/sdk-node",
3
- "version": "0.4.1",
3
+ "version": "0.4.5",
4
4
  "description": "WardnMesh.AI Node.js SDK - Active Defense Middleware for AI Agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,7 +29,8 @@
29
29
  "dist",
30
30
  "bin",
31
31
  "README.md",
32
- "LICENSE"
32
+ "LICENSE",
33
+ "CHANGELOG.md"
33
34
  ],
34
35
  "publishConfig": {
35
36
  "access": "public"
@@ -42,18 +43,23 @@
42
43
  ],
43
44
  "repository": {
44
45
  "type": "git",
45
- "url": "git+https://github.com/PCIRCLE-AI/wardnmesh.git"
46
+ "url": "git+https://github.com/PCIRCLE-AI/wardnmesh-sdk-node.git"
46
47
  },
47
48
  "bugs": {
48
- "url": "https://github.com/PCIRCLE-AI/wardnmesh/issues"
49
+ "url": "https://github.com/PCIRCLE-AI/wardnmesh-sdk-node/issues"
49
50
  },
50
51
  "homepage": "https://wardnmesh.ai",
51
52
  "author": "KT",
52
53
  "license": "Elastic-2.0",
54
+ "engines": {
55
+ "node": ">=18.0.0",
56
+ "npm": ">=9.0.0"
57
+ },
53
58
  "devDependencies": {
54
59
  "@types/jest": "^29.5.11",
55
60
  "@types/node": "^20.10.0",
56
61
  "jest": "^29.7.0",
62
+ "next": "^14.2.35",
57
63
  "ts-jest": "^29.1.1",
58
64
  "typescript": "^5.0.0"
59
65
  },
@@ -1,28 +0,0 @@
1
- import { AgentGuardConfig, ScanResult, AgentRequest } from "./types";
2
- import { SessionStateProvider } from "./state/session-manager";
3
- export declare class AgentGuard {
4
- private static instance;
5
- private config;
6
- private stateProvider;
7
- private telemetry;
8
- private patternDetector;
9
- private sequenceDetector;
10
- private stateDetector;
11
- private semanticDetector;
12
- private constructor();
13
- private initTelemetry;
14
- static getInstance(): AgentGuard;
15
- static init(config: AgentGuardConfig, stateProvider?: SessionStateProvider): AgentGuard;
16
- /** Main entry point to scan an agent request */
17
- scan(request: AgentRequest): Promise<ScanResult>;
18
- /** Normalize request to ToolData format */
19
- private normalizeRequest;
20
- /** Run detector for a single rule */
21
- private detectViolation;
22
- /** Handle semantic detection */
23
- private detectSemanticViolation;
24
- /** Report violation to telemetry */
25
- private reportViolation;
26
- /** Report scan completion to telemetry */
27
- private reportScanComplete;
28
- }
@@ -1,206 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AgentGuard = void 0;
4
- const pattern_1 = require("./detectors/pattern");
5
- const sequence_1 = require("./detectors/sequence");
6
- const state_1 = require("./detectors/state");
7
- const session_manager_1 = require("./state/session-manager");
8
- const reporter_1 = require("./telemetry/reporter");
9
- const semantic_detector_1 = require("./detectors/semantic-detector");
10
- /** Synchronous state adapter for in-request state management */
11
- class SyncStateAdapter {
12
- constructor(initialState, maxHistory = 50) {
13
- this.maxHistory = maxHistory;
14
- this.state = {
15
- startTime: initialState.startTime || new Date().toISOString(),
16
- toolCalls: initialState.toolCalls || [],
17
- recentTools: initialState.recentTools || [],
18
- detectedViolations: initialState.detectedViolations || [],
19
- customState: initialState.customState || {},
20
- currentFile: initialState.currentFile,
21
- };
22
- }
23
- getRecentTools(count) {
24
- const tools = this.state.recentTools || [];
25
- return count ? tools.slice(-count) : tools;
26
- }
27
- setCustomState(key, value) {
28
- this.state.customState[key] = value;
29
- }
30
- getCustomState(key) {
31
- return this.state.customState[key];
32
- }
33
- addToolCall(tool) {
34
- if (!this.state.recentTools)
35
- this.state.recentTools = [];
36
- this.state.recentTools.push(tool);
37
- if (this.state.recentTools.length > this.maxHistory) {
38
- this.state.recentTools.shift();
39
- }
40
- }
41
- exportState() {
42
- return this.state;
43
- }
44
- }
45
- class AgentGuard {
46
- constructor(config, stateProvider) {
47
- this.config = config;
48
- this.stateProvider = stateProvider || new session_manager_1.InMemorySessionStateProvider();
49
- this.telemetry = this.initTelemetry();
50
- this.patternDetector = new pattern_1.PatternDetector();
51
- this.sequenceDetector = new sequence_1.SequenceDetector();
52
- this.stateDetector = new state_1.StateDetector();
53
- this.semanticDetector = semantic_detector_1.SemanticDetector.getInstance();
54
- // Emit startup event
55
- this.telemetry.emit({
56
- eventType: "agent_started",
57
- timestamp: new Date().toISOString(),
58
- data: {
59
- config: {
60
- appName: this.config.telemetry?.serviceName,
61
- ruleCount: this.config.rules.length,
62
- },
63
- },
64
- });
65
- }
66
- initTelemetry() {
67
- if (this.config.telemetry?.enabled && process.env.CCB_ENDPOINT) {
68
- return new reporter_1.CCBReporter(process.env.CCB_ENDPOINT, process.env.CCB_API_KEY || "", this.config.telemetry.serviceName || "unknown-service");
69
- }
70
- return new reporter_1.ConsoleReporter();
71
- }
72
- static getInstance() {
73
- if (!AgentGuard.instance) {
74
- throw new Error("AgentGuard not initialized. Call AgentGuard.init() first.");
75
- }
76
- return AgentGuard.instance;
77
- }
78
- static init(config, stateProvider) {
79
- AgentGuard.instance = new AgentGuard(config, stateProvider);
80
- return AgentGuard.instance;
81
- }
82
- /** Main entry point to scan an agent request */
83
- async scan(request) {
84
- const start = Date.now();
85
- const violations = [];
86
- const sessionId = request.sessionId || "default";
87
- try {
88
- const rawState = await this.stateProvider.getState(sessionId);
89
- const stateAdapter = new SyncStateAdapter(rawState, this.config.maxHistorySize);
90
- const toolData = this.normalizeRequest(request);
91
- stateAdapter.addToolCall(toolData);
92
- // Lazy load semantic model if needed
93
- if (this.config.rules.some((r) => r.detector.type === "semantic")) {
94
- await this.semanticDetector.init();
95
- }
96
- // Run all detectors
97
- for (const rule of this.config.rules) {
98
- const violation = await this.detectViolation(rule, toolData, stateAdapter);
99
- if (violation) {
100
- violations.push(violation);
101
- this.reportViolation(violation, toolData, sessionId);
102
- }
103
- }
104
- await this.stateProvider.setState(sessionId, stateAdapter.exportState());
105
- const result = {
106
- allowed: !violations.some((v) => v.severity === "critical"),
107
- violations,
108
- latencyMs: Date.now() - start,
109
- metadata: { analyzedRules: this.config.rules.length },
110
- };
111
- this.reportScanComplete(result, sessionId);
112
- return result;
113
- }
114
- catch (error) {
115
- // Fail-Open Resilience: Never crash the application
116
- console.error("[AgentGuard] Scan failed, failing open:", error);
117
- this.telemetry.emit({
118
- eventType: "error",
119
- timestamp: new Date().toISOString(),
120
- data: {
121
- error: error instanceof Error ? error.message : "Unknown error",
122
- sessionId,
123
- },
124
- });
125
- return {
126
- allowed: true, // Fail-open
127
- violations: [],
128
- latencyMs: Date.now() - start,
129
- metadata: {
130
- error: true,
131
- errorDetails: error instanceof Error ? error.message : "Unknown",
132
- },
133
- };
134
- }
135
- }
136
- /** Normalize request to ToolData format */
137
- normalizeRequest(request) {
138
- return {
139
- toolName: request.toolName || "llm_input",
140
- parameters: request.parameters || { prompt: request.prompt || "" },
141
- result: { success: true },
142
- duration: 0,
143
- timestamp: new Date().toISOString(),
144
- };
145
- }
146
- /** Run detector for a single rule */
147
- async detectViolation(rule, toolData, stateAdapter) {
148
- switch (rule.detector.type) {
149
- case "pattern":
150
- return this.patternDetector.detect(toolData, rule, stateAdapter);
151
- case "sequence":
152
- return this.sequenceDetector.detect(toolData, rule, stateAdapter);
153
- case "state":
154
- return this.stateDetector.detect(toolData, rule, stateAdapter);
155
- case "semantic":
156
- return this.detectSemanticViolation(rule, toolData);
157
- default:
158
- return null;
159
- }
160
- }
161
- /** Handle semantic detection */
162
- async detectSemanticViolation(rule, toolData) {
163
- const prompt = toolData.parameters.prompt ||
164
- JSON.stringify(toolData.parameters);
165
- const config = rule.detector.config;
166
- const { detected, reason, score } = await this.semanticDetector.scan(prompt, config.threshold || 0.75);
167
- if (!detected)
168
- return null;
169
- return {
170
- id: crypto.randomUUID(),
171
- ruleId: rule.id,
172
- ruleName: rule.name,
173
- severity: rule.severity,
174
- description: reason || "Semantic Violation",
175
- context: {
176
- toolName: toolData.toolName,
177
- toolData,
178
- additionalInfo: { score },
179
- },
180
- timestamp: new Date().toISOString(),
181
- };
182
- }
183
- /** Report violation to telemetry */
184
- reportViolation(violation, toolData, sessionId) {
185
- this.telemetry.emit({
186
- eventType: "violation_detected",
187
- timestamp: new Date().toISOString(),
188
- data: { violation, toolData },
189
- metadata: { sessionId },
190
- });
191
- }
192
- /** Report scan completion to telemetry */
193
- reportScanComplete(result, sessionId) {
194
- this.telemetry.emit({
195
- eventType: "scan_complete",
196
- timestamp: new Date().toISOString(),
197
- data: {
198
- allowed: result.allowed,
199
- latencyMs: result.latencyMs,
200
- violationCount: result.violations.length,
201
- },
202
- metadata: { sessionId },
203
- });
204
- }
205
- }
206
- exports.AgentGuard = AgentGuard;