visus-mcp 0.6.0 → 0.6.2
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/.claude/settings.local.json +42 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +47 -0
- package/.github/ISSUE_TEMPLATE/false_positive.md +43 -0
- package/.github/ISSUE_TEMPLATE/new_pattern.md +49 -0
- package/.github/ISSUE_TEMPLATE/security_report.md +31 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +39 -0
- package/.mcpregistry_github_token +1 -0
- package/.mcpregistry_registry_token +1 -0
- package/CLAUDE.md +197 -0
- package/CONTRIBUTING.md +329 -0
- package/README.md +111 -45
- package/STATUS.md +167 -29
- package/SUBMISSION.md +66 -0
- package/TROUBLESHOOT-COGNITO-AUTH-20260324-2029.md +415 -0
- package/TROUBLESHOOT-COGNITO-JWT-20260324.md +592 -0
- package/dist/browser/playwright-renderer.d.ts.map +1 -1
- package/dist/browser/playwright-renderer.js +71 -51
- package/dist/browser/playwright-renderer.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -6
- package/dist/index.js.map +1 -1
- package/dist/sanitizer/elicit-runner.d.ts +48 -0
- package/dist/sanitizer/elicit-runner.d.ts.map +1 -0
- package/dist/sanitizer/elicit-runner.js +100 -0
- package/dist/sanitizer/elicit-runner.js.map +1 -0
- package/dist/sanitizer/framework-mapper.d.ts +2 -0
- package/dist/sanitizer/framework-mapper.d.ts.map +1 -1
- package/dist/sanitizer/framework-mapper.js +91 -45
- package/dist/sanitizer/framework-mapper.js.map +1 -1
- package/dist/sanitizer/hitl-gate.d.ts +69 -0
- package/dist/sanitizer/hitl-gate.d.ts.map +1 -0
- package/dist/sanitizer/hitl-gate.js +101 -0
- package/dist/sanitizer/hitl-gate.js.map +1 -0
- package/dist/sanitizer/threat-reporter.d.ts +1 -0
- package/dist/sanitizer/threat-reporter.d.ts.map +1 -1
- package/dist/sanitizer/threat-reporter.js +10 -7
- package/dist/sanitizer/threat-reporter.js.map +1 -1
- package/infrastructure/stack.ts +1 -0
- package/lambda-deploy/index.js +81512 -0
- package/lambda-deploy/index.js.map +7 -0
- package/lambda-package/browser/__mocks__/playwright-renderer.d.ts +25 -0
- package/lambda-package/browser/__mocks__/playwright-renderer.d.ts.map +1 -0
- package/lambda-package/browser/__mocks__/playwright-renderer.js +119 -0
- package/lambda-package/browser/__mocks__/playwright-renderer.js.map +1 -0
- package/lambda-package/browser/playwright-renderer.d.ts +40 -0
- package/lambda-package/browser/playwright-renderer.d.ts.map +1 -0
- package/lambda-package/browser/playwright-renderer.js +214 -0
- package/lambda-package/browser/playwright-renderer.js.map +1 -0
- package/lambda-package/browser/reader.d.ts +31 -0
- package/lambda-package/browser/reader.d.ts.map +1 -0
- package/lambda-package/browser/reader.js +98 -0
- package/lambda-package/browser/reader.js.map +1 -0
- package/lambda-package/index.d.ts +18 -0
- package/lambda-package/index.d.ts.map +1 -0
- package/lambda-package/index.js +238 -0
- package/lambda-package/index.js.map +1 -0
- package/lambda-package/lambda-handler.d.ts +28 -0
- package/lambda-package/lambda-handler.d.ts.map +1 -0
- package/lambda-package/lambda-handler.js +257 -0
- package/lambda-package/lambda-handler.js.map +1 -0
- package/lambda-package/package-lock.json +7435 -0
- package/lambda-package/package.json +74 -0
- package/lambda-package/runtime.d.ts +50 -0
- package/lambda-package/runtime.d.ts.map +1 -0
- package/lambda-package/runtime.js +86 -0
- package/lambda-package/runtime.js.map +1 -0
- package/lambda-package/sanitizer/elicit-runner.d.ts +48 -0
- package/lambda-package/sanitizer/elicit-runner.d.ts.map +1 -0
- package/lambda-package/sanitizer/elicit-runner.js +100 -0
- package/lambda-package/sanitizer/elicit-runner.js.map +1 -0
- package/lambda-package/sanitizer/framework-mapper.d.ts +24 -0
- package/lambda-package/sanitizer/framework-mapper.d.ts.map +1 -0
- package/lambda-package/sanitizer/framework-mapper.js +342 -0
- package/lambda-package/sanitizer/framework-mapper.js.map +1 -0
- package/lambda-package/sanitizer/hitl-gate.d.ts +69 -0
- package/lambda-package/sanitizer/hitl-gate.d.ts.map +1 -0
- package/lambda-package/sanitizer/hitl-gate.js +101 -0
- package/lambda-package/sanitizer/hitl-gate.js.map +1 -0
- package/lambda-package/sanitizer/index.d.ts +63 -0
- package/lambda-package/sanitizer/index.d.ts.map +1 -0
- package/lambda-package/sanitizer/index.js +105 -0
- package/lambda-package/sanitizer/index.js.map +1 -0
- package/lambda-package/sanitizer/injection-detector.d.ts +34 -0
- package/lambda-package/sanitizer/injection-detector.d.ts.map +1 -0
- package/lambda-package/sanitizer/injection-detector.js +89 -0
- package/lambda-package/sanitizer/injection-detector.js.map +1 -0
- package/lambda-package/sanitizer/patterns.d.ts +30 -0
- package/lambda-package/sanitizer/patterns.d.ts.map +1 -0
- package/lambda-package/sanitizer/patterns.js +372 -0
- package/lambda-package/sanitizer/patterns.js.map +1 -0
- package/lambda-package/sanitizer/pii-allowlist.d.ts +49 -0
- package/lambda-package/sanitizer/pii-allowlist.d.ts.map +1 -0
- package/lambda-package/sanitizer/pii-allowlist.js +231 -0
- package/lambda-package/sanitizer/pii-allowlist.js.map +1 -0
- package/lambda-package/sanitizer/pii-redactor.d.ts +41 -0
- package/lambda-package/sanitizer/pii-redactor.d.ts.map +1 -0
- package/lambda-package/sanitizer/pii-redactor.js +213 -0
- package/lambda-package/sanitizer/pii-redactor.js.map +1 -0
- package/lambda-package/sanitizer/severity-classifier.d.ts +33 -0
- package/lambda-package/sanitizer/severity-classifier.d.ts.map +1 -0
- package/lambda-package/sanitizer/severity-classifier.js +113 -0
- package/lambda-package/sanitizer/severity-classifier.js.map +1 -0
- package/lambda-package/sanitizer/threat-reporter.d.ts +66 -0
- package/lambda-package/sanitizer/threat-reporter.d.ts.map +1 -0
- package/lambda-package/sanitizer/threat-reporter.js +163 -0
- package/lambda-package/sanitizer/threat-reporter.js.map +1 -0
- package/lambda-package/tools/fetch-structured.d.ts +51 -0
- package/lambda-package/tools/fetch-structured.d.ts.map +1 -0
- package/lambda-package/tools/fetch-structured.js +237 -0
- package/lambda-package/tools/fetch-structured.js.map +1 -0
- package/lambda-package/tools/fetch.d.ts +49 -0
- package/lambda-package/tools/fetch.d.ts.map +1 -0
- package/lambda-package/tools/fetch.js +131 -0
- package/lambda-package/tools/fetch.js.map +1 -0
- package/lambda-package/tools/read.d.ts +51 -0
- package/lambda-package/tools/read.d.ts.map +1 -0
- package/lambda-package/tools/read.js +127 -0
- package/lambda-package/tools/read.js.map +1 -0
- package/lambda-package/tools/search.d.ts +45 -0
- package/lambda-package/tools/search.d.ts.map +1 -0
- package/lambda-package/tools/search.js +220 -0
- package/lambda-package/tools/search.js.map +1 -0
- package/lambda-package/types.d.ts +167 -0
- package/lambda-package/types.d.ts.map +1 -0
- package/lambda-package/types.js +16 -0
- package/lambda-package/types.js.map +1 -0
- package/lambda-package/utils/format-converter.d.ts +39 -0
- package/lambda-package/utils/format-converter.d.ts.map +1 -0
- package/lambda-package/utils/format-converter.js +191 -0
- package/lambda-package/utils/format-converter.js.map +1 -0
- package/lambda-package/utils/truncate.d.ts +26 -0
- package/lambda-package/utils/truncate.d.ts.map +1 -0
- package/lambda-package/utils/truncate.js +54 -0
- package/lambda-package/utils/truncate.js.map +1 -0
- package/lambda.zip +0 -0
- package/mcp.json +44 -0
- package/package.json +9 -8
- package/server.json +43 -0
- package/src/browser/playwright-renderer.ts +74 -51
- package/src/index.ts +78 -6
- package/src/sanitizer/elicit-runner.ts +125 -0
- package/src/sanitizer/framework-mapper.ts +92 -45
- package/src/sanitizer/hitl-gate.ts +111 -0
- package/src/sanitizer/threat-reporter.ts +11 -7
- package/tests/elicit-runner.test.ts +232 -0
- package/tests/hitl-gate.test.ts +267 -0
- package/tests/threat-reporter.test.ts +69 -1
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* CRITICAL: The sanitizer ALWAYS runs locally. Rendered HTML is returned from
|
|
9
9
|
* Lambda to the local process before Claude sees it. PHI never touches Lateos infrastructure.
|
|
10
10
|
*/
|
|
11
|
-
import { request } from 'undici';
|
|
12
11
|
import { Ok, Err } from '../types.js';
|
|
13
12
|
/**
|
|
14
13
|
* Configuration
|
|
@@ -63,21 +62,27 @@ async function renderWithLambda(url, timeout_ms) {
|
|
|
63
62
|
try {
|
|
64
63
|
// Retry Lambda calls with exponential backoff (3 attempts)
|
|
65
64
|
const response = await retryWithBackoff(async () => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
65
|
+
const controller = new AbortController();
|
|
66
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout_ms + 5000);
|
|
67
|
+
try {
|
|
68
|
+
return await fetch(`${RENDERER_URL}/render`, {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: {
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
},
|
|
73
|
+
body: JSON.stringify({
|
|
74
|
+
url,
|
|
75
|
+
timeout_ms,
|
|
76
|
+
content_limit_bytes: 512000, // 500KB default
|
|
77
|
+
}),
|
|
78
|
+
signal: controller.signal,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
clearTimeout(timeoutId);
|
|
83
|
+
}
|
|
79
84
|
}, 3, 1000); // 3 retries, starting with 1s delay
|
|
80
|
-
const body = await response.
|
|
85
|
+
const body = await response.json();
|
|
81
86
|
// Check if response is an error
|
|
82
87
|
if ('error' in body) {
|
|
83
88
|
return Err(new Error(`Lambda renderer error: ${body.error}`));
|
|
@@ -103,40 +108,50 @@ async function renderWithLambda(url, timeout_ms) {
|
|
|
103
108
|
}
|
|
104
109
|
}
|
|
105
110
|
/**
|
|
106
|
-
* Render a page using
|
|
111
|
+
* Render a page using native fetch (fallback)
|
|
107
112
|
*/
|
|
108
113
|
async function renderWithFetch(url, timeout_ms) {
|
|
109
114
|
logRenderer('fetch', url);
|
|
110
115
|
try {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
116
|
+
// Use AbortController for timeout
|
|
117
|
+
const controller = new AbortController();
|
|
118
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout_ms);
|
|
119
|
+
try {
|
|
120
|
+
const response = await fetch(url, {
|
|
121
|
+
method: 'GET',
|
|
122
|
+
headers: {
|
|
123
|
+
'User-Agent': 'Visus-MCP/0.3.1 (Security-focused web content fetcher; +https://github.com/lateos/visus-mcp)',
|
|
124
|
+
},
|
|
125
|
+
signal: controller.signal,
|
|
126
|
+
});
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
return Err(new Error(`HTTP ${response.status}: ${response.statusText}`));
|
|
129
|
+
}
|
|
130
|
+
const html = await response.text();
|
|
131
|
+
// Capture Content-Type header
|
|
132
|
+
const contentTypeHeader = response.headers.get('content-type');
|
|
133
|
+
const contentType = contentTypeHeader
|
|
134
|
+
? contentTypeHeader.split(';')[0].trim() // Remove charset and other params
|
|
135
|
+
: 'text/html'; // Default to HTML if missing
|
|
136
|
+
// Extract title using regex (simple fallback)
|
|
137
|
+
const titleMatch = html.match(/<title[^>]*>(.*?)<\/title>/i);
|
|
138
|
+
const title = titleMatch ? titleMatch[1].trim() : '';
|
|
139
|
+
return Ok({
|
|
140
|
+
html,
|
|
141
|
+
title,
|
|
142
|
+
url,
|
|
143
|
+
contentType,
|
|
144
|
+
text: undefined,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
clearTimeout(timeoutId);
|
|
149
|
+
}
|
|
135
150
|
}
|
|
136
151
|
catch (error) {
|
|
137
152
|
if (error instanceof Error) {
|
|
138
|
-
// Handle timeout errors
|
|
139
|
-
if (error.
|
|
153
|
+
// Handle abort/timeout errors
|
|
154
|
+
if (error.name === 'AbortError') {
|
|
140
155
|
return Err(new Error(`Navigation timeout after ${timeout_ms}ms`));
|
|
141
156
|
}
|
|
142
157
|
// Handle network errors
|
|
@@ -188,15 +203,20 @@ export async function renderPage(url, options = {}) {
|
|
|
188
203
|
*/
|
|
189
204
|
export async function checkUrl(url, timeout_ms = 5000) {
|
|
190
205
|
try {
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
206
|
+
const controller = new AbortController();
|
|
207
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout_ms);
|
|
208
|
+
try {
|
|
209
|
+
const response = await fetch(url, {
|
|
210
|
+
method: 'HEAD',
|
|
211
|
+
signal: controller.signal,
|
|
212
|
+
});
|
|
213
|
+
// Consider 2xx and 3xx status codes as accessible
|
|
214
|
+
const isAccessible = (response.status >= 200 && response.status < 400);
|
|
215
|
+
return Ok(isAccessible);
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
clearTimeout(timeoutId);
|
|
219
|
+
}
|
|
200
220
|
}
|
|
201
221
|
catch (error) {
|
|
202
222
|
// URL is not accessible
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright-renderer.js","sourceRoot":"","sources":["../../src/browser/playwright-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"playwright-renderer.js","sourceRoot":"","sources":["../../src/browser/playwright-renderer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG;AAoSH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -23,12 +23,14 @@ import { visusRead, visusReadToolDefinition } from './tools/read.js';
|
|
|
23
23
|
import { visusSearch, visusSearchToolDefinition } from './tools/search.js';
|
|
24
24
|
import { closeBrowser } from './browser/playwright-renderer.js';
|
|
25
25
|
import { detectRuntime, logRuntimeConfig, validateRuntime } from './runtime.js';
|
|
26
|
+
import { shouldElicit } from './sanitizer/hitl-gate.js';
|
|
27
|
+
import { runElicitation } from './sanitizer/elicit-runner.js';
|
|
26
28
|
/**
|
|
27
29
|
* Create and configure the MCP server
|
|
28
30
|
*/
|
|
29
31
|
const server = new Server({
|
|
30
32
|
name: 'visus-mcp',
|
|
31
|
-
version: '0.
|
|
33
|
+
version: '0.6.0'
|
|
32
34
|
}, {
|
|
33
35
|
capabilities: {
|
|
34
36
|
tools: {}
|
|
@@ -47,6 +49,38 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
47
49
|
]
|
|
48
50
|
};
|
|
49
51
|
});
|
|
52
|
+
/**
|
|
53
|
+
* Helper function to handle HITL elicitation for CRITICAL threats
|
|
54
|
+
*
|
|
55
|
+
* Returns modified output with threat_report removed if user declined,
|
|
56
|
+
* or blocked response if user declined to proceed.
|
|
57
|
+
*/
|
|
58
|
+
async function handleCriticalThreatElicitation(output, url) {
|
|
59
|
+
const threatReport = output.threat_report;
|
|
60
|
+
// Check if elicitation is needed
|
|
61
|
+
if (shouldElicit(threatReport ?? null)) {
|
|
62
|
+
const { proceed, includeReport } = await runElicitation(server, threatReport, url);
|
|
63
|
+
if (!proceed) {
|
|
64
|
+
// User declined — return blocked response with threat report
|
|
65
|
+
return {
|
|
66
|
+
output: {
|
|
67
|
+
url,
|
|
68
|
+
blocked: true,
|
|
69
|
+
reason: 'User declined to proceed after CRITICAL threat detected',
|
|
70
|
+
threat_report: threatReport
|
|
71
|
+
},
|
|
72
|
+
blocked: true
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// User accepted — proceed with sanitized content
|
|
76
|
+
// Remove threat_report if user didn't request it
|
|
77
|
+
if (!includeReport && output.threat_report) {
|
|
78
|
+
const { threat_report, ...outputWithoutReport } = output;
|
|
79
|
+
return { output: outputWithoutReport, blocked: false };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return { output, blocked: false };
|
|
83
|
+
}
|
|
50
84
|
/**
|
|
51
85
|
* Handle tool execution requests
|
|
52
86
|
*/
|
|
@@ -59,11 +93,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
59
93
|
if (!result.ok) {
|
|
60
94
|
throw new McpError(ErrorCode.InternalError, `visus_fetch failed: ${result.error.message}`);
|
|
61
95
|
}
|
|
96
|
+
// Handle HITL elicitation for CRITICAL threats
|
|
97
|
+
const { output } = await handleCriticalThreatElicitation(result.value, args.url);
|
|
62
98
|
return {
|
|
63
99
|
content: [
|
|
64
100
|
{
|
|
65
101
|
type: 'text',
|
|
66
|
-
text: JSON.stringify(
|
|
102
|
+
text: JSON.stringify(output, null, 2)
|
|
67
103
|
}
|
|
68
104
|
]
|
|
69
105
|
};
|
|
@@ -73,11 +109,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
73
109
|
if (!result.ok) {
|
|
74
110
|
throw new McpError(ErrorCode.InternalError, `visus_fetch_structured failed: ${result.error.message}`);
|
|
75
111
|
}
|
|
112
|
+
// Handle HITL elicitation for CRITICAL threats
|
|
113
|
+
const { output } = await handleCriticalThreatElicitation(result.value, args.url);
|
|
76
114
|
return {
|
|
77
115
|
content: [
|
|
78
116
|
{
|
|
79
117
|
type: 'text',
|
|
80
|
-
text: JSON.stringify(
|
|
118
|
+
text: JSON.stringify(output, null, 2)
|
|
81
119
|
}
|
|
82
120
|
]
|
|
83
121
|
};
|
|
@@ -87,11 +125,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
87
125
|
if (!result.ok) {
|
|
88
126
|
throw new McpError(ErrorCode.InternalError, `visus_read failed: ${result.error.message}`);
|
|
89
127
|
}
|
|
128
|
+
// Handle HITL elicitation for CRITICAL threats
|
|
129
|
+
const { output } = await handleCriticalThreatElicitation(result.value, args.url);
|
|
90
130
|
return {
|
|
91
131
|
content: [
|
|
92
132
|
{
|
|
93
133
|
type: 'text',
|
|
94
|
-
text: JSON.stringify(
|
|
134
|
+
text: JSON.stringify(output, null, 2)
|
|
95
135
|
}
|
|
96
136
|
]
|
|
97
137
|
};
|
|
@@ -101,11 +141,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
101
141
|
if (!result.ok) {
|
|
102
142
|
throw new McpError(ErrorCode.InternalError, `visus_search failed: ${result.error.message}`);
|
|
103
143
|
}
|
|
144
|
+
// Handle HITL elicitation for CRITICAL threats
|
|
145
|
+
// For search, use the query as the "URL" in the elicitation message
|
|
146
|
+
const { output } = await handleCriticalThreatElicitation(result.value, `search: ${args.query}`);
|
|
104
147
|
return {
|
|
105
148
|
content: [
|
|
106
149
|
{
|
|
107
150
|
type: 'text',
|
|
108
|
-
text: JSON.stringify(
|
|
151
|
+
text: JSON.stringify(output, null, 2)
|
|
109
152
|
}
|
|
110
153
|
]
|
|
111
154
|
};
|
|
@@ -133,7 +176,7 @@ async function startMcpServer() {
|
|
|
133
176
|
timestamp: new Date().toISOString(),
|
|
134
177
|
event: 'mcp_server_started',
|
|
135
178
|
name: 'visus-mcp',
|
|
136
|
-
version: '0.
|
|
179
|
+
version: '0.6.0',
|
|
137
180
|
tools: ['visus_fetch', 'visus_fetch_structured', 'visus_read', 'visus_search']
|
|
138
181
|
}));
|
|
139
182
|
// Graceful shutdown
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,SAAS,EACT,QAAQ,EACT,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAC;AACvG,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,SAAS,EACT,QAAQ,EACT,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAC;AACvG,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D;;GAEG;AACH,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO;QACL,KAAK,EAAE;YACL,wBAAwB;YACxB,kCAAkC;YAClC,uBAAuB;YACvB,yBAAyB;SAC1B;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,KAAK,UAAU,+BAA+B,CAC5C,MAAW,EACX,GAAW;IAEX,MAAM,YAAY,GAAG,MAAM,CAAC,aAAyC,CAAC;IAEtE,iCAAiC;IACjC,IAAI,YAAY,CAAC,YAAY,IAAI,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,MAAM,cAAc,CACrD,MAAM,EACN,YAAa,EACb,GAAG,CACJ,CAAC;QAEF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,6DAA6D;YAC7D,OAAO;gBACL,MAAM,EAAE;oBACN,GAAG;oBACH,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,yDAAyD;oBACjE,aAAa,EAAE,YAAY;iBAC5B;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,iDAAiD;QACjD,iDAAiD;QACjD,IAAI,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YAC3C,MAAM,EAAE,aAAa,EAAE,GAAG,mBAAmB,EAAE,GAAG,MAAM,CAAC;YACzD,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACzD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAEjD,IAAI,CAAC;QACH,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAW,CAAC,CAAC;gBAE7C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBACf,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,uBAAuB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAC9C,CAAC;gBACJ,CAAC;gBAED,+CAA+C;gBAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,+BAA+B,CACtD,MAAM,CAAC,KAAK,EACX,IAAY,CAAC,GAAG,CAClB,CAAC;gBAEF,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;yBACtC;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,KAAK,wBAAwB,CAAC,CAAC,CAAC;gBAC9B,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,IAAW,CAAC,CAAC;gBAEvD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBACf,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,kCAAkC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CACzD,CAAC;gBACJ,CAAC;gBAED,+CAA+C;gBAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,+BAA+B,CACtD,MAAM,CAAC,KAAK,EACX,IAAY,CAAC,GAAG,CAClB,CAAC;gBAEF,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;yBACtC;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAW,CAAC,CAAC;gBAE5C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBACf,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,sBAAsB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAC7C,CAAC;gBACJ,CAAC;gBAED,+CAA+C;gBAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,+BAA+B,CACtD,MAAM,CAAC,KAAK,EACX,IAAY,CAAC,GAAG,CAClB,CAAC;gBAEF,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;yBACtC;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,KAAK,cAAc,CAAC,CAAC,CAAC;gBACpB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAW,CAAC,CAAC;gBAE9C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBACf,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,wBAAwB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAC/C,CAAC;gBACJ,CAAC;gBAED,+CAA+C;gBAC/C,oEAAoE;gBACpE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,+BAA+B,CACtD,MAAM,CAAC,KAAK,EACZ,WAAY,IAAY,CAAC,KAAK,EAAE,CACjC,CAAC;gBAEF,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;yBACtC;qBACF;iBACF,CAAC;YACJ,CAAC;YAED;gBACE,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,cAAc,EACxB,iBAAiB,IAAI,EAAE,CACxB,CAAC;QACN,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACnF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;GAEG;AACH,KAAK,UAAU,cAAc;IAC3B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,8BAA8B;IAC9B,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,uDAAuD;IACvD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,oBAAoB;QAC3B,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,OAAO;QAChB,KAAK,EAAE,CAAC,aAAa,EAAE,wBAAwB,EAAE,YAAY,EAAE,cAAc,CAAC;KAC/E,CAAC,CAAC,CAAC;IAEJ,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC9B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,qBAAqB;SAC7B,CAAC,CAAC,CAAC;QAEJ,MAAM,YAAY,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC/B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,qBAAqB;SAC7B,CAAC,CAAC,CAAC;QAEJ,MAAM,YAAY,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,6BAA6B;IAC7B,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC1B,eAAe,CAAC,OAAO,CAAC,CAAC;IAEzB,mCAAmC;IACnC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,qCAAqC;QACrC,MAAM,cAAc,EAAE,CAAC;IACzB,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC5B,8BAA8B;QAC9B,6DAA6D;QAC7D,qEAAqE;QACrE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,sBAAsB;YAC7B,OAAO,EAAE,+CAA+C;SACzD,CAAC,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AAED,6CAA6C;AAC7C,4EAA4E;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,8DAA8D;AAC9D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;IAC1C,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,eAAe;YACtB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elicitation Runner
|
|
3
|
+
*
|
|
4
|
+
* Executes MCP elicitation requests with comprehensive error handling
|
|
5
|
+
* and fail-safe behavior. If elicitation fails for ANY reason, the
|
|
6
|
+
* sanitized content is delivered — security is never compromised.
|
|
7
|
+
*
|
|
8
|
+
* Error handling includes:
|
|
9
|
+
* - Client doesn't support elicitation
|
|
10
|
+
* - Client timeout
|
|
11
|
+
* - Network errors
|
|
12
|
+
* - Unexpected responses
|
|
13
|
+
*
|
|
14
|
+
* Fail-safe principle: Elicitation is UX. Sanitization is security.
|
|
15
|
+
* Never block content delivery due to elicitation failures.
|
|
16
|
+
*/
|
|
17
|
+
import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
18
|
+
import type { ThreatReport } from './threat-reporter.js';
|
|
19
|
+
/**
|
|
20
|
+
* Result of elicitation execution
|
|
21
|
+
*/
|
|
22
|
+
export interface ElicitationResult {
|
|
23
|
+
/** Whether user chose to proceed with sanitized content */
|
|
24
|
+
proceed: boolean;
|
|
25
|
+
/** Whether to include threat report in response */
|
|
26
|
+
includeReport: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Runs MCP elicitation for CRITICAL threat confirmation
|
|
30
|
+
*
|
|
31
|
+
* Three possible outcomes:
|
|
32
|
+
* 1. User accepts → proceed: true, includeReport: user's choice
|
|
33
|
+
* 2. User declines → proceed: false, includeReport: false
|
|
34
|
+
* 3. User cancels → proceed: false, includeReport: false
|
|
35
|
+
*
|
|
36
|
+
* Fail-safe: Any error → proceed: true, includeReport: true
|
|
37
|
+
* (Content reaches user in sanitized form, security maintained)
|
|
38
|
+
*
|
|
39
|
+
* CRITICAL: Only ONE elicitation per tool call is allowed per MCP spec.
|
|
40
|
+
* Calling this function twice in the same request will cause timeout.
|
|
41
|
+
*
|
|
42
|
+
* @param server The MCP server instance
|
|
43
|
+
* @param threatReport The CRITICAL threat report
|
|
44
|
+
* @param url The source URL
|
|
45
|
+
* @returns Elicitation result with proceed and includeReport flags
|
|
46
|
+
*/
|
|
47
|
+
export declare function runElicitation(server: Server, threatReport: ThreatReport, url: string): Promise<ElicitationResult>;
|
|
48
|
+
//# sourceMappingURL=elicit-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elicit-runner.d.ts","sourceRoot":"","sources":["../../src/sanitizer/elicit-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,OAAO,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,iBAAiB,CAAC,CAsE5B"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elicitation Runner
|
|
3
|
+
*
|
|
4
|
+
* Executes MCP elicitation requests with comprehensive error handling
|
|
5
|
+
* and fail-safe behavior. If elicitation fails for ANY reason, the
|
|
6
|
+
* sanitized content is delivered — security is never compromised.
|
|
7
|
+
*
|
|
8
|
+
* Error handling includes:
|
|
9
|
+
* - Client doesn't support elicitation
|
|
10
|
+
* - Client timeout
|
|
11
|
+
* - Network errors
|
|
12
|
+
* - Unexpected responses
|
|
13
|
+
*
|
|
14
|
+
* Fail-safe principle: Elicitation is UX. Sanitization is security.
|
|
15
|
+
* Never block content delivery due to elicitation failures.
|
|
16
|
+
*/
|
|
17
|
+
import { buildElicitMessage, ElicitSchema } from './hitl-gate.js';
|
|
18
|
+
/**
|
|
19
|
+
* Runs MCP elicitation for CRITICAL threat confirmation
|
|
20
|
+
*
|
|
21
|
+
* Three possible outcomes:
|
|
22
|
+
* 1. User accepts → proceed: true, includeReport: user's choice
|
|
23
|
+
* 2. User declines → proceed: false, includeReport: false
|
|
24
|
+
* 3. User cancels → proceed: false, includeReport: false
|
|
25
|
+
*
|
|
26
|
+
* Fail-safe: Any error → proceed: true, includeReport: true
|
|
27
|
+
* (Content reaches user in sanitized form, security maintained)
|
|
28
|
+
*
|
|
29
|
+
* CRITICAL: Only ONE elicitation per tool call is allowed per MCP spec.
|
|
30
|
+
* Calling this function twice in the same request will cause timeout.
|
|
31
|
+
*
|
|
32
|
+
* @param server The MCP server instance
|
|
33
|
+
* @param threatReport The CRITICAL threat report
|
|
34
|
+
* @param url The source URL
|
|
35
|
+
* @returns Elicitation result with proceed and includeReport flags
|
|
36
|
+
*/
|
|
37
|
+
export async function runElicitation(server, threatReport, url) {
|
|
38
|
+
try {
|
|
39
|
+
// Build user-facing message
|
|
40
|
+
const message = buildElicitMessage(threatReport, url);
|
|
41
|
+
// Execute elicitation
|
|
42
|
+
const result = await server.elicitInput({
|
|
43
|
+
mode: 'form',
|
|
44
|
+
message,
|
|
45
|
+
requestedSchema: ElicitSchema // Type cast due to SDK's strict schema definition
|
|
46
|
+
});
|
|
47
|
+
// Handle user response
|
|
48
|
+
if (result.action === 'accept') {
|
|
49
|
+
// User explicitly accepted
|
|
50
|
+
// Content values can be string | number | boolean | string[]
|
|
51
|
+
const proceed = result.content?.proceed === true || result.content?.proceed === 'true';
|
|
52
|
+
const includeReport = result.content?.view_report === true || result.content?.view_report === 'true' || result.content?.view_report === undefined;
|
|
53
|
+
return {
|
|
54
|
+
proceed,
|
|
55
|
+
includeReport: proceed ? includeReport : false // Only include report if proceeding
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (result.action === 'decline') {
|
|
59
|
+
// User explicitly declined
|
|
60
|
+
return {
|
|
61
|
+
proceed: false,
|
|
62
|
+
includeReport: false
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (result.action === 'cancel') {
|
|
66
|
+
// User canceled or dismissed dialog
|
|
67
|
+
return {
|
|
68
|
+
proceed: false,
|
|
69
|
+
includeReport: false
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Unknown action (should never happen)
|
|
73
|
+
console.error(JSON.stringify({
|
|
74
|
+
timestamp: new Date().toISOString(),
|
|
75
|
+
event: 'elicitation_unknown_action',
|
|
76
|
+
action: result.action,
|
|
77
|
+
message: 'Unexpected elicitation action, proceeding with sanitized content (fail-safe)'
|
|
78
|
+
}));
|
|
79
|
+
return {
|
|
80
|
+
proceed: true,
|
|
81
|
+
includeReport: true
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// Elicitation failed — FAIL SAFE
|
|
86
|
+
// Client may not support elicitation, or timeout occurred
|
|
87
|
+
// Proceed with sanitized content + include report
|
|
88
|
+
console.error(JSON.stringify({
|
|
89
|
+
timestamp: new Date().toISOString(),
|
|
90
|
+
event: 'elicitation_failed',
|
|
91
|
+
error: error instanceof Error ? error.message : String(error),
|
|
92
|
+
message: 'Elicitation not supported or timed out, proceeding with sanitized content (fail-safe)'
|
|
93
|
+
}));
|
|
94
|
+
return {
|
|
95
|
+
proceed: true,
|
|
96
|
+
includeReport: true
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=elicit-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elicit-runner.js","sourceRoot":"","sources":["../../src/sanitizer/elicit-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAYlE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAc,EACd,YAA0B,EAC1B,GAAW;IAEX,IAAI,CAAC;QACH,4BAA4B;QAC5B,MAAM,OAAO,GAAG,kBAAkB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAEtD,sBAAsB;QACtB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;YACtC,IAAI,EAAE,MAAe;YACrB,OAAO;YACP,eAAe,EAAE,YAAmB,CAAC,kDAAkD;SACxF,CAAC,CAAC;QAEH,uBAAuB;QACvB,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,2BAA2B;YAC3B,6DAA6D;YAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;YACvF,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,WAAW,KAAK,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,WAAW,KAAK,SAAS,CAAC;YAElJ,OAAO;gBACL,OAAO;gBACP,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,oCAAoC;aACpF,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,2BAA2B;YAC3B,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,KAAK;aACrB,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,oCAAoC;YACpC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,KAAK;aACrB,CAAC;QACJ,CAAC;QAED,uCAAuC;QACvC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,4BAA4B;YACnC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,8EAA8E;SACxF,CAAC,CAAC,CAAC;QAEJ,OAAO;YACL,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,IAAI;SACpB,CAAC;IAEJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iCAAiC;QACjC,0DAA0D;QAC1D,kDAAkD;QAClD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,oBAAoB;YAC3B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;YAC7D,OAAO,EAAE,uFAAuF;SACjG,CAAC,CAAC,CAAC;QAEJ,OAAO;YACL,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,IAAI;SACpB,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
* - OWASP LLM Top 10 (2025)
|
|
6
6
|
* - NIST AI 600-1 (Generative AI Profile)
|
|
7
7
|
* - MITRE ATLAS (Adversarial Threat Landscape for AI Systems)
|
|
8
|
+
* - ISO/IEC 42001:2023 (AI Management System - Annex A Controls)
|
|
8
9
|
*/
|
|
9
10
|
export interface FrameworkMappings {
|
|
10
11
|
owasp_llm: string;
|
|
11
12
|
nist_ai_600_1: string;
|
|
12
13
|
mitre_atlas: string;
|
|
14
|
+
iso_42001: string;
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
15
17
|
* Get framework mappings for a pattern category
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"framework-mapper.d.ts","sourceRoot":"","sources":["../../src/sanitizer/framework-mapper.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"framework-mapper.d.ts","sourceRoot":"","sources":["../../src/sanitizer/framework-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAyWD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,iBAAiB,CAE/E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAOjD"}
|