cbrowser 18.3.10 → 18.3.11

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 (47) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/mcp-server-remote.d.ts.map +1 -1
  6. package/dist/mcp-server-remote.js +8 -1
  7. package/dist/mcp-server-remote.js.map +1 -1
  8. package/dist/mcp-tools/base/index.d.ts +4 -2
  9. package/dist/mcp-tools/base/index.d.ts.map +1 -1
  10. package/dist/mcp-tools/base/index.js +7 -2
  11. package/dist/mcp-tools/base/index.js.map +1 -1
  12. package/dist/mcp-tools/base/security-tools.d.ts +12 -0
  13. package/dist/mcp-tools/base/security-tools.d.ts.map +1 -0
  14. package/dist/mcp-tools/base/security-tools.js +85 -0
  15. package/dist/mcp-tools/base/security-tools.js.map +1 -0
  16. package/dist/security/audit-wrapper.d.ts +148 -0
  17. package/dist/security/audit-wrapper.d.ts.map +1 -0
  18. package/dist/security/audit-wrapper.js +433 -0
  19. package/dist/security/audit-wrapper.js.map +1 -0
  20. package/dist/security/description-scanner.d.ts +132 -0
  21. package/dist/security/description-scanner.d.ts.map +1 -0
  22. package/dist/security/description-scanner.js +408 -0
  23. package/dist/security/description-scanner.js.map +1 -0
  24. package/dist/security/index.d.ts +23 -0
  25. package/dist/security/index.d.ts.map +1 -0
  26. package/dist/security/index.js +29 -0
  27. package/dist/security/index.js.map +1 -0
  28. package/dist/security/output-sanitizer.d.ts +132 -0
  29. package/dist/security/output-sanitizer.d.ts.map +1 -0
  30. package/dist/security/output-sanitizer.js +344 -0
  31. package/dist/security/output-sanitizer.js.map +1 -0
  32. package/dist/security/request-signing.d.ts +53 -0
  33. package/dist/security/request-signing.d.ts.map +1 -0
  34. package/dist/security/request-signing.js +142 -0
  35. package/dist/security/request-signing.js.map +1 -0
  36. package/dist/security/tool-permissions.d.ts +96 -0
  37. package/dist/security/tool-permissions.d.ts.map +1 -0
  38. package/dist/security/tool-permissions.js +317 -0
  39. package/dist/security/tool-permissions.js.map +1 -0
  40. package/dist/security/tool-pinning.d.ts +143 -0
  41. package/dist/security/tool-pinning.d.ts.map +1 -0
  42. package/dist/security/tool-pinning.js +302 -0
  43. package/dist/security/tool-pinning.js.map +1 -0
  44. package/dist/types.d.ts +26 -0
  45. package/dist/types.d.ts.map +1 -1
  46. package/dist/types.js.map +1 -1
  47. package/package.json +1 -1
@@ -0,0 +1,433 @@
1
+ /**
2
+ * CBrowser - Cognitive Browser Automation
3
+ * Copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com
4
+ * Learn more at https://cbrowser.ai - MIT License
5
+ */
6
+ /**
7
+ * Tool Invocation Audit Wrapper for CBrowser MCP Server
8
+ *
9
+ * Provides comprehensive audit logging for all MCP tool invocations.
10
+ * Captures tool name, parameters (with sensitive value redaction),
11
+ * timing, results, and links to triggered actions.
12
+ *
13
+ * Usage:
14
+ * import { wrapToolHandler, createAuditContext } from "./security/audit-wrapper.js";
15
+ *
16
+ * const auditContext = createAuditContext();
17
+ * const wrappedHandler = wrapToolHandler(originalHandler, "tool_name", auditContext);
18
+ */
19
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
20
+ import { homedir } from "node:os";
21
+ import { join } from "node:path";
22
+ import { randomUUID } from "node:crypto";
23
+ // Sensitive parameter patterns - values matching these will be redacted
24
+ const SENSITIVE_PATTERNS = [
25
+ /password/i,
26
+ /secret/i,
27
+ /token/i,
28
+ /key/i,
29
+ /credential/i,
30
+ /auth/i,
31
+ /apikey/i,
32
+ /api_key/i,
33
+ /bearer/i,
34
+ /private/i,
35
+ /passphrase/i,
36
+ /pin/i,
37
+ /ssn/i,
38
+ /credit/i,
39
+ /card/i,
40
+ ];
41
+ // Tool zone classifications for security audit categorization
42
+ // Green: Read-only, safe operations
43
+ // Yellow: Potentially modifying state
44
+ // Red: Sensitive operations (credentials, payments)
45
+ // Black: Should not happen in normal operation
46
+ const TOOL_ZONES = {
47
+ // Green zone - read-only operations
48
+ screenshot: "green",
49
+ status: "green",
50
+ extract: "green",
51
+ analyze_page: "green",
52
+ agent_ready_audit: "green",
53
+ empathy_audit: "green",
54
+ list_sessions: "green",
55
+ list_baselines: "green",
56
+ list_cognitive_personas: "green",
57
+ persona_traits_list: "green",
58
+ persona_values_lookup: "green",
59
+ persona_trait_lookup: "green",
60
+ visual_baseline: "green",
61
+ heal_stats: "green",
62
+ stealth_status: "green",
63
+ stealth_check: "green",
64
+ browser_health: "green",
65
+ perf_baseline: "green",
66
+ ab_comparison: "green",
67
+ coverage_map: "green",
68
+ compare_personas_init: "green",
69
+ compare_personas_complete: "green",
70
+ competitive_benchmark: "green",
71
+ cross_browser_diff: "green",
72
+ // Yellow zone - state-modifying operations
73
+ navigate: "yellow",
74
+ click: "yellow",
75
+ smart_click: "yellow",
76
+ fill: "yellow",
77
+ scroll: "yellow",
78
+ hover: "yellow",
79
+ assert: "yellow",
80
+ save_session: "yellow",
81
+ load_session: "yellow",
82
+ delete_session: "yellow",
83
+ reset_browser: "yellow",
84
+ browser_recover: "yellow",
85
+ dismiss_overlay: "yellow",
86
+ stealth_enable: "yellow",
87
+ stealth_disable: "yellow",
88
+ stealth_diagnose: "yellow",
89
+ cognitive_journey_init: "yellow",
90
+ cognitive_journey_update_state: "yellow",
91
+ cognitive_journey_autonomous: "yellow",
92
+ find_element_by_intent: "yellow",
93
+ nl_test_inline: "yellow",
94
+ nl_test_file: "yellow",
95
+ generate_tests: "yellow",
96
+ repair_test: "yellow",
97
+ detect_flaky_tests: "yellow",
98
+ chaos_test: "yellow",
99
+ responsive_test: "yellow",
100
+ cross_browser_test: "yellow",
101
+ visual_regression: "yellow",
102
+ perf_regression: "yellow",
103
+ hunt_bugs: "yellow",
104
+ // Persona creation - yellow (creates persistent data)
105
+ persona_create_start: "yellow",
106
+ persona_create_submit_traits: "yellow",
107
+ persona_create_from_description: "yellow",
108
+ persona_create_questionnaire_start: "yellow",
109
+ persona_create_questionnaire_answer: "yellow",
110
+ persona_questionnaire_build: "yellow",
111
+ persona_questionnaire_get: "yellow",
112
+ persona_category_guidance: "yellow",
113
+ persona_create_cancel: "yellow",
114
+ compare_personas: "yellow",
115
+ // Red zone - sensitive operations
116
+ set_api_key: "red",
117
+ clear_api_key: "red",
118
+ ask_user: "red", // Can be used for phishing
119
+ // Marketing tools - yellow (external integrations)
120
+ marketing_audience_discover: "yellow",
121
+ marketing_campaign_create: "yellow",
122
+ marketing_campaign_run: "yellow",
123
+ marketing_campaign_report_result: "yellow",
124
+ marketing_compete: "yellow",
125
+ marketing_discover_status: "yellow",
126
+ marketing_funnel_analyze: "yellow",
127
+ marketing_influence_matrix: "yellow",
128
+ marketing_lever_analysis: "yellow",
129
+ marketing_personas_list: "yellow",
130
+ list_influence_patterns: "yellow",
131
+ // Cloudflare/anti-detection - yellow
132
+ cloudflare_detect: "yellow",
133
+ cloudflare_wait: "yellow",
134
+ };
135
+ /**
136
+ * Create an audit context for tool wrapping
137
+ *
138
+ * @param options Optional configuration
139
+ * @returns AuditContext instance
140
+ */
141
+ export function createAuditContext(options) {
142
+ const dataDir = process.env.CBROWSER_DATA_DIR || join(homedir(), ".cbrowser");
143
+ const auditDir = options?.auditDir || join(dataDir, "audit");
144
+ // Ensure audit directory exists
145
+ if (!existsSync(auditDir)) {
146
+ mkdirSync(auditDir, { recursive: true });
147
+ }
148
+ return {
149
+ sessionId: options?.sessionId || randomUUID().slice(0, 8),
150
+ auditDir,
151
+ enabled: options?.enabled ?? (process.env.CBROWSER_AUDIT_ENABLED !== "false"),
152
+ includeStackTraces: options?.includeStackTraces ?? false,
153
+ actionsTriggered: new Map(),
154
+ };
155
+ }
156
+ /**
157
+ * Redact sensitive values from parameters
158
+ *
159
+ * @param params The parameters object to redact
160
+ * @returns Copy of params with sensitive values replaced with "[REDACTED]"
161
+ */
162
+ export function redactSensitiveParams(params) {
163
+ const redacted = {};
164
+ for (const [key, value] of Object.entries(params)) {
165
+ // Check if key matches sensitive pattern
166
+ const isSensitive = SENSITIVE_PATTERNS.some((pattern) => pattern.test(key));
167
+ // Process arrays and objects recursively (even if key is sensitive)
168
+ // This allows nested structures to have their own sensitive fields redacted
169
+ if (Array.isArray(value)) {
170
+ // Handle arrays - check each element recursively
171
+ redacted[key] = value.map((item) => {
172
+ if (typeof item === "object" && item !== null) {
173
+ return redactSensitiveParams(item);
174
+ }
175
+ // Redact primitive values in arrays if parent key is sensitive
176
+ return isSensitive ? "[REDACTED]" : item;
177
+ });
178
+ }
179
+ else if (typeof value === "object" && value !== null) {
180
+ // Recursively redact nested objects
181
+ redacted[key] = redactSensitiveParams(value);
182
+ }
183
+ else if (isSensitive && value !== undefined && value !== null) {
184
+ // Redact primitive sensitive values
185
+ redacted[key] = "[REDACTED]";
186
+ }
187
+ else {
188
+ redacted[key] = value;
189
+ }
190
+ }
191
+ return redacted;
192
+ }
193
+ /**
194
+ * Get the zone classification for a tool
195
+ *
196
+ * @param toolName The name of the tool
197
+ * @returns ActionZone classification
198
+ */
199
+ export function getToolZone(toolName) {
200
+ return TOOL_ZONES[toolName] || "yellow"; // Default to yellow for unknown tools
201
+ }
202
+ /**
203
+ * Get the audit log file path for the current date
204
+ *
205
+ * @param auditDir The audit directory path
206
+ * @returns Path to the tool invocations audit file
207
+ */
208
+ function getAuditFilePath(auditDir) {
209
+ const date = new Date().toISOString().split("T")[0];
210
+ return join(auditDir, `tool-invocations-${date}.json`);
211
+ }
212
+ /**
213
+ * Write an audit entry to the log file
214
+ *
215
+ * @param entry The audit entry to write
216
+ * @param auditDir The audit directory path
217
+ */
218
+ function writeAuditEntry(entry, auditDir) {
219
+ const filePath = getAuditFilePath(auditDir);
220
+ let entries = [];
221
+ if (existsSync(filePath)) {
222
+ try {
223
+ entries = JSON.parse(readFileSync(filePath, "utf-8"));
224
+ }
225
+ catch {
226
+ // If file is corrupted, start fresh
227
+ entries = [];
228
+ }
229
+ }
230
+ entries.push(entry);
231
+ writeFileSync(filePath, JSON.stringify(entries, null, 2));
232
+ }
233
+ /**
234
+ * Wrap a tool handler with audit logging
235
+ *
236
+ * This wraps any MCP tool handler to automatically:
237
+ * - Generate a unique request ID
238
+ * - Log the tool name and (redacted) parameters
239
+ * - Time the execution
240
+ * - Capture success/failure status
241
+ * - Write to the audit log
242
+ *
243
+ * @param handler The original tool handler function
244
+ * @param toolName The name of the tool being wrapped
245
+ * @param context The audit context
246
+ * @returns A wrapped handler with identical signature
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * const context = createAuditContext();
251
+ *
252
+ * server.tool(
253
+ * "navigate",
254
+ * "Navigate to a URL",
255
+ * { url: z.string().url() },
256
+ * wrapToolHandler(
257
+ * async ({ url }) => {
258
+ * await browser.navigate(url);
259
+ * return { content: [{ type: "text", text: "Navigated" }] };
260
+ * },
261
+ * "navigate",
262
+ * context
263
+ * )
264
+ * );
265
+ * ```
266
+ */
267
+ export function wrapToolHandler(handler, toolName, context) {
268
+ return async (params) => {
269
+ // Skip logging if disabled
270
+ if (!context.enabled) {
271
+ return handler(params);
272
+ }
273
+ const requestId = randomUUID();
274
+ const startTime = Date.now();
275
+ const zone = getToolZone(toolName);
276
+ // Initialize actions tracking for this request
277
+ context.actionsTriggered.set(requestId, []);
278
+ let result = "success";
279
+ let error;
280
+ try {
281
+ const response = await handler(params);
282
+ return response;
283
+ }
284
+ catch (err) {
285
+ result = "failure";
286
+ error = err instanceof Error ? err.message : String(err);
287
+ if (context.includeStackTraces && err instanceof Error && err.stack) {
288
+ error = `${error}\n${err.stack}`;
289
+ }
290
+ throw err;
291
+ }
292
+ finally {
293
+ const duration = Date.now() - startTime;
294
+ const actionsTriggered = context.actionsTriggered.get(requestId) || [];
295
+ context.actionsTriggered.delete(requestId);
296
+ const entry = {
297
+ timestamp: new Date().toISOString(),
298
+ sessionId: context.sessionId,
299
+ requestId,
300
+ tool: toolName,
301
+ parameters: redactSensitiveParams(params),
302
+ zone,
303
+ result,
304
+ duration,
305
+ error,
306
+ actionsTriggered,
307
+ };
308
+ try {
309
+ writeAuditEntry(entry, context.auditDir);
310
+ }
311
+ catch (writeErr) {
312
+ // Don't let audit logging failures break tool execution
313
+ console.error(`[CBrowser Audit] Failed to write audit entry: ${writeErr instanceof Error ? writeErr.message : String(writeErr)}`);
314
+ }
315
+ }
316
+ };
317
+ }
318
+ /**
319
+ * Link an action to the current tool invocation
320
+ *
321
+ * Call this from within browser actions to link them to the triggering tool call.
322
+ *
323
+ * @param context The audit context
324
+ * @param requestId The request ID of the tool invocation
325
+ * @param actionId The ID of the triggered action (from AuditEntry)
326
+ */
327
+ export function linkActionToInvocation(context, requestId, actionId) {
328
+ const actions = context.actionsTriggered.get(requestId);
329
+ if (actions) {
330
+ actions.push(actionId);
331
+ }
332
+ }
333
+ /**
334
+ * Create a wrapper factory for a specific audit context
335
+ *
336
+ * This is useful when registering many tools with the same context.
337
+ *
338
+ * @param context The audit context
339
+ * @returns A function that wraps handlers with the given context
340
+ *
341
+ * @example
342
+ * ```typescript
343
+ * const context = createAuditContext();
344
+ * const wrap = createWrapperFactory(context);
345
+ *
346
+ * server.tool("navigate", "...", schema, wrap(navigateHandler, "navigate"));
347
+ * server.tool("click", "...", schema, wrap(clickHandler, "click"));
348
+ * ```
349
+ */
350
+ export function createWrapperFactory(context) {
351
+ return (handler, toolName) => wrapToolHandler(handler, toolName, context);
352
+ }
353
+ /**
354
+ * Read audit entries for a specific date
355
+ *
356
+ * @param auditDir The audit directory path
357
+ * @param date ISO date string (YYYY-MM-DD) or Date object
358
+ * @returns Array of tool invocation entries
359
+ */
360
+ export function readAuditEntries(auditDir, date) {
361
+ const dateStr = date
362
+ ? typeof date === "string"
363
+ ? date
364
+ : date.toISOString().split("T")[0]
365
+ : new Date().toISOString().split("T")[0];
366
+ const filePath = join(auditDir, `tool-invocations-${dateStr}.json`);
367
+ if (!existsSync(filePath)) {
368
+ return [];
369
+ }
370
+ try {
371
+ return JSON.parse(readFileSync(filePath, "utf-8"));
372
+ }
373
+ catch {
374
+ return [];
375
+ }
376
+ }
377
+ /**
378
+ * Get audit statistics for a date range
379
+ *
380
+ * @param auditDir The audit directory path
381
+ * @param startDate Start date (inclusive)
382
+ * @param endDate End date (inclusive), defaults to today
383
+ * @returns Audit statistics
384
+ */
385
+ export function getAuditStats(auditDir, startDate, endDate) {
386
+ const end = endDate || new Date();
387
+ const start = startDate || new Date(end.getTime() - 7 * 24 * 60 * 60 * 1000); // Default to last 7 days
388
+ const stats = {
389
+ totalInvocations: 0,
390
+ successCount: 0,
391
+ failureCount: 0,
392
+ blockedCount: 0,
393
+ byTool: {},
394
+ byZone: { green: 0, yellow: 0, red: 0, black: 0 },
395
+ avgDuration: 0,
396
+ sessions: [],
397
+ };
398
+ let totalDuration = 0;
399
+ const sessionsSet = new Set();
400
+ // Iterate through dates in range
401
+ const current = new Date(start);
402
+ while (current <= end) {
403
+ const entries = readAuditEntries(auditDir, current);
404
+ for (const entry of entries) {
405
+ stats.totalInvocations++;
406
+ totalDuration += entry.duration;
407
+ sessionsSet.add(entry.sessionId);
408
+ // Count by result
409
+ switch (entry.result) {
410
+ case "success":
411
+ stats.successCount++;
412
+ break;
413
+ case "failure":
414
+ stats.failureCount++;
415
+ break;
416
+ case "blocked":
417
+ stats.blockedCount++;
418
+ break;
419
+ }
420
+ // Count by tool
421
+ stats.byTool[entry.tool] = (stats.byTool[entry.tool] || 0) + 1;
422
+ // Count by zone
423
+ stats.byZone[entry.zone]++;
424
+ }
425
+ current.setDate(current.getDate() + 1);
426
+ }
427
+ stats.avgDuration = stats.totalInvocations > 0
428
+ ? Math.round(totalDuration / stats.totalInvocations)
429
+ : 0;
430
+ stats.sessions = Array.from(sessionsSet);
431
+ return stats;
432
+ }
433
+ //# sourceMappingURL=audit-wrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-wrapper.js","sourceRoot":"","sources":["../../src/security/audit-wrapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * CBrowser - Cognitive Browser Automation
3
+ * Copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com
4
+ * Learn more at https://cbrowser.ai - MIT License
5
+ */
6
+ import type { ToolDefinition } from "./tool-pinning.js";
7
+ /**
8
+ * Severity levels for scan issues
9
+ * - info: Informational, not necessarily problematic
10
+ * - warning: Potentially suspicious, warrants review
11
+ * - critical: Highly likely malicious, should be blocked
12
+ */
13
+ export type ScanSeverity = "info" | "warning" | "critical";
14
+ /**
15
+ * A single issue detected in a tool description
16
+ */
17
+ export interface ScanIssue {
18
+ /** Pattern category that matched (e.g., "cross_tool_instruction") */
19
+ pattern: string;
20
+ /** Severity level of this issue */
21
+ severity: ScanSeverity;
22
+ /** The actual text that matched the pattern */
23
+ match: string;
24
+ /** Character position in the description where match was found */
25
+ position?: number;
26
+ }
27
+ /**
28
+ * Result of scanning a single tool's description
29
+ */
30
+ export interface ToolScanResult {
31
+ /** Name of the tool that was scanned */
32
+ toolName: string;
33
+ /** Overall status based on highest severity issue found */
34
+ status: "clean" | "warning" | "critical";
35
+ /** List of issues found in the description */
36
+ issues: ScanIssue[];
37
+ }
38
+ /**
39
+ * Result of scanning all tools on an MCP server
40
+ */
41
+ export interface ServerScanResult {
42
+ /** Name of the server that was scanned */
43
+ serverName: string;
44
+ /** Total number of tools scanned */
45
+ toolCount: number;
46
+ /** Overall status based on worst tool status */
47
+ status: "clean" | "warning" | "critical";
48
+ /** List of tools that had issues (excludes clean tools) */
49
+ issues: ToolScanResult[];
50
+ }
51
+ /**
52
+ * Summary of scanning multiple MCP servers
53
+ */
54
+ export interface ScanSummary {
55
+ /** Results for each server scanned */
56
+ servers: ServerScanResult[];
57
+ /** Aggregate statistics */
58
+ summary: {
59
+ /** Total tools scanned across all servers */
60
+ total: number;
61
+ /** Tools with no issues */
62
+ clean: number;
63
+ /** Tools with warning-level issues */
64
+ warning: number;
65
+ /** Tools with critical-level issues */
66
+ critical: number;
67
+ };
68
+ }
69
+ /**
70
+ * Scan a single tool's description for injection patterns.
71
+ *
72
+ * @param name - The tool's name
73
+ * @param description - The tool's description text
74
+ * @returns Scan result with status and any issues found
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const result = scanToolDescription("navigate", "Navigate to a URL");
79
+ * if (result.status !== "clean") {
80
+ * console.warn("Issues found:", result.issues);
81
+ * }
82
+ * ```
83
+ */
84
+ export declare function scanToolDescription(name: string, description: string): ToolScanResult;
85
+ /**
86
+ * Scan an array of tool definitions for injection patterns.
87
+ *
88
+ * @param tools - Array of tool definitions to scan
89
+ * @param serverName - Name of the server (optional, defaults to "unknown")
90
+ * @returns Server scan result with aggregate status
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const tools = [
95
+ * { name: "navigate", description: "Navigate to URL", schema: {} },
96
+ * { name: "click", description: "Click element", schema: {} },
97
+ * ];
98
+ * const result = scanToolDefinitions(tools, "cbrowser");
99
+ * console.log("Server status:", result.status);
100
+ * ```
101
+ */
102
+ export declare function scanToolDefinitions(tools: ToolDefinition[], serverName?: string): ServerScanResult;
103
+ /**
104
+ * Scan MCP configuration file for all registered servers.
105
+ * Currently this function parses the config but cannot actually
106
+ * scan tool descriptions without starting the servers.
107
+ *
108
+ * @param configPath - Path to claude_desktop_config.json
109
+ * @returns Scan summary with results for each server
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const summary = scanMcpConfig("~/.config/claude/claude_desktop_config.json");
114
+ * console.log("Total issues:", summary.summary.critical + summary.summary.warning);
115
+ * ```
116
+ */
117
+ export declare function scanMcpConfig(configPath: string): ScanSummary;
118
+ /**
119
+ * Get a formatted report of scan results.
120
+ *
121
+ * @param result - Server scan result to format
122
+ * @returns Human-readable report string
123
+ */
124
+ export declare function formatScanReport(result: ServerScanResult): string;
125
+ /**
126
+ * Quick check if a description is safe (no critical issues).
127
+ *
128
+ * @param description - Description text to check
129
+ * @returns true if no critical issues found
130
+ */
131
+ export declare function isDescriptionSafe(description: string): boolean;
132
+ //# sourceMappingURL=description-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"description-scanner.d.ts","sourceRoot":"","sources":["../../src/security/description-scanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMxD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,QAAQ,EAAE,YAAY,CAAC;IACvB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;IACzC,8CAA8C;IAC9C,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;IACzC,2DAA2D;IAC3D,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,2BAA2B;IAC3B,OAAO,EAAE;QACP,6CAA6C;QAC7C,KAAK,EAAE,MAAM,CAAC;QACd,2BAA2B;QAC3B,KAAK,EAAE,MAAM,CAAC;QACd,sCAAsC;QACtC,OAAO,EAAE,MAAM,CAAC;QAChB,uCAAuC;QACvC,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AA+ND;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,cAAc,CAgChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EAAE,EACvB,UAAU,GAAE,MAAkB,GAC7B,gBAAgB,CAwBlB;AAgBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAgD7D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CA2BjE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAG9D"}