@riotprompt/riotprompt 0.0.20 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/MIGRATION.md +235 -0
  3. package/README.md +2 -0
  4. package/SECURITY.md +132 -0
  5. package/dist/builder.js +6 -0
  6. package/dist/builder.js.map +1 -1
  7. package/dist/{cli.cjs → cli.js} +658 -216
  8. package/dist/context-manager.js +1 -1
  9. package/dist/conversation-logger.d.ts +17 -1
  10. package/dist/conversation-logger.js +21 -17
  11. package/dist/conversation-logger.js.map +1 -1
  12. package/dist/conversation.js +1 -1
  13. package/dist/error-handling.d.ts +52 -0
  14. package/dist/error-handling.js +132 -0
  15. package/dist/error-handling.js.map +1 -0
  16. package/dist/formatter.js +1 -1
  17. package/dist/iteration-strategy.js +1 -1
  18. package/dist/loader.js +60 -12
  19. package/dist/loader.js.map +1 -1
  20. package/dist/logger.d.ts +52 -0
  21. package/dist/logger.js +114 -14
  22. package/dist/logger.js.map +1 -1
  23. package/dist/logging-config.d.ts +84 -0
  24. package/dist/logging-config.js +116 -0
  25. package/dist/logging-config.js.map +1 -0
  26. package/dist/message-builder.js +1 -1
  27. package/dist/model-config.js +1 -1
  28. package/dist/override.js +10 -4
  29. package/dist/override.js.map +1 -1
  30. package/dist/recipes.js +6 -0
  31. package/dist/recipes.js.map +1 -1
  32. package/dist/reflection.js +1 -1
  33. package/dist/riotprompt.d.ts +9 -0
  34. package/dist/riotprompt.js +8 -0
  35. package/dist/riotprompt.js.map +1 -1
  36. package/dist/security/audit-logger.d.ts +61 -0
  37. package/dist/security/audit-logger.js +281 -0
  38. package/dist/security/audit-logger.js.map +1 -0
  39. package/dist/security/cli-security.d.ts +143 -0
  40. package/dist/security/cli-security.js +302 -0
  41. package/dist/security/cli-security.js.map +1 -0
  42. package/dist/security/defaults.d.ts +31 -0
  43. package/dist/security/defaults.js +72 -0
  44. package/dist/security/defaults.js.map +1 -0
  45. package/dist/security/events.d.ts +8 -0
  46. package/dist/security/index.d.ts +27 -0
  47. package/dist/security/index.js +22 -0
  48. package/dist/security/index.js.map +1 -0
  49. package/dist/security/path-guard.d.ts +161 -0
  50. package/dist/security/path-guard.js +327 -0
  51. package/dist/security/path-guard.js.map +1 -0
  52. package/dist/security/rate-limiter.d.ts +117 -0
  53. package/dist/security/rate-limiter.js +165 -0
  54. package/dist/security/rate-limiter.js.map +1 -0
  55. package/dist/security/serialization-schemas.d.ts +183 -0
  56. package/dist/security/serialization-schemas.js +174 -0
  57. package/dist/security/serialization-schemas.js.map +1 -0
  58. package/dist/security/timeout-guard.d.ts +123 -0
  59. package/dist/security/timeout-guard.js +223 -0
  60. package/dist/security/timeout-guard.js.map +1 -0
  61. package/dist/security/types.d.ts +86 -0
  62. package/dist/security/types.js +80 -0
  63. package/dist/security/types.js.map +1 -0
  64. package/dist/token-budget.js +1 -1
  65. package/dist/tools.js +1 -1
  66. package/dist/util/storage.js.map +1 -1
  67. package/guide/index.md +2 -0
  68. package/guide/integration.md +1109 -0
  69. package/guide/security.md +237 -0
  70. package/package.json +23 -17
  71. package/vite.config.cli.ts +9 -18
  72. package/dist/riotprompt.cjs +0 -6169
  73. package/dist/riotprompt.cjs.map +0 -1
@@ -0,0 +1,281 @@
1
+ import { wrapLogger, DEFAULT_LOGGER } from '../logger.js';
2
+
3
+ function _define_property(obj, key, value) {
4
+ if (key in obj) {
5
+ Object.defineProperty(obj, key, {
6
+ value: value,
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true
10
+ });
11
+ } else {
12
+ obj[key] = value;
13
+ }
14
+ return obj;
15
+ }
16
+ const DEFAULT_CONFIG = {
17
+ enabled: true,
18
+ logLevel: 'warning',
19
+ includeContext: true,
20
+ maxContextSize: 1000
21
+ };
22
+ class SecurityAuditLogger {
23
+ /**
24
+ * Log a security event
25
+ */ log(event) {
26
+ var // Always call event handler for monitoring (before log level filter)
27
+ _this_config_onEvent, _this_config;
28
+ if (!this.config.enabled) return;
29
+ const fullEvent = {
30
+ ...event,
31
+ timestamp: new Date(),
32
+ context: this.sanitizeContext(event.context)
33
+ };
34
+ // Track event counts
35
+ const count = this.eventCount.get(event.type) || 0;
36
+ this.eventCount.set(event.type, count + 1);
37
+ (_this_config_onEvent = (_this_config = this.config).onEvent) === null || _this_config_onEvent === void 0 ? void 0 : _this_config_onEvent.call(_this_config, fullEvent);
38
+ // Check log level for actual logging output
39
+ if (!this.shouldLog(event.severity)) return;
40
+ // Log the event
41
+ const logMessage = this.formatEvent(fullEvent);
42
+ switch(event.severity){
43
+ case 'critical':
44
+ this.logger.error(`[CRITICAL] ${logMessage}`);
45
+ break;
46
+ case 'error':
47
+ this.logger.error(logMessage);
48
+ break;
49
+ case 'warning':
50
+ this.logger.warn(logMessage);
51
+ break;
52
+ case 'info':
53
+ this.logger.info(logMessage);
54
+ break;
55
+ }
56
+ }
57
+ /**
58
+ * Convenience methods for common events
59
+ */ pathTraversalBlocked(path, reason) {
60
+ this.log({
61
+ type: 'path_traversal_blocked',
62
+ severity: 'warning',
63
+ message: `Path traversal attempt blocked: ${reason}`,
64
+ context: {
65
+ attemptedPath: this.sanitizePath(path)
66
+ }
67
+ });
68
+ }
69
+ pathValidationFailed(path, reason) {
70
+ this.log({
71
+ type: 'path_validation_failed',
72
+ severity: 'warning',
73
+ message: `Path validation failed: ${reason}`,
74
+ context: {
75
+ attemptedPath: this.sanitizePath(path)
76
+ }
77
+ });
78
+ }
79
+ toolValidationFailed(toolName, reason) {
80
+ this.log({
81
+ type: 'tool_validation_failed',
82
+ severity: 'warning',
83
+ message: `Tool parameter validation failed for "${toolName}": ${reason}`,
84
+ context: {
85
+ toolName
86
+ }
87
+ });
88
+ }
89
+ toolExecutionBlocked(toolName, reason) {
90
+ this.log({
91
+ type: 'tool_execution_blocked',
92
+ severity: 'error',
93
+ message: `Tool execution blocked for "${toolName}": ${reason}`,
94
+ context: {
95
+ toolName
96
+ }
97
+ });
98
+ }
99
+ toolTimeout(toolName, timeoutMs) {
100
+ this.log({
101
+ type: 'tool_timeout',
102
+ severity: 'warning',
103
+ message: `Tool "${toolName}" timed out after ${timeoutMs}ms`,
104
+ context: {
105
+ toolName,
106
+ timeoutMs
107
+ }
108
+ });
109
+ }
110
+ secretRedacted(source) {
111
+ this.log({
112
+ type: 'secret_redacted',
113
+ severity: 'info',
114
+ message: `Sensitive data redacted from ${source}`,
115
+ context: {
116
+ source
117
+ }
118
+ });
119
+ }
120
+ apiKeyUsed(provider) {
121
+ this.log({
122
+ type: 'api_key_used',
123
+ severity: 'info',
124
+ message: `API key accessed for provider: ${provider}`,
125
+ context: {
126
+ provider
127
+ }
128
+ });
129
+ }
130
+ deserializationFailed(source, reason) {
131
+ this.log({
132
+ type: 'deserialization_failed',
133
+ severity: 'warning',
134
+ message: `Deserialization failed from ${source}: ${reason}`,
135
+ context: {
136
+ source
137
+ }
138
+ });
139
+ }
140
+ regexTimeout(pattern, timeoutMs) {
141
+ this.log({
142
+ type: 'regex_timeout',
143
+ severity: 'warning',
144
+ message: `Regex operation timed out after ${timeoutMs}ms`,
145
+ context: {
146
+ patternLength: pattern.length,
147
+ timeoutMs
148
+ }
149
+ });
150
+ }
151
+ requestTimeout(operation, timeoutMs) {
152
+ this.log({
153
+ type: 'request_timeout',
154
+ severity: 'warning',
155
+ message: `Operation "${operation}" timed out after ${timeoutMs}ms`,
156
+ context: {
157
+ operation,
158
+ timeoutMs
159
+ }
160
+ });
161
+ }
162
+ rateLimitExceeded(resource, limit) {
163
+ this.log({
164
+ type: 'rate_limit_exceeded',
165
+ severity: 'warning',
166
+ message: `Rate limit exceeded for ${resource}: limit is ${limit}`,
167
+ context: {
168
+ resource,
169
+ limit
170
+ }
171
+ });
172
+ }
173
+ /**
174
+ * Get event statistics
175
+ */ getStats() {
176
+ return new Map(this.eventCount);
177
+ }
178
+ /**
179
+ * Get total event count
180
+ */ getTotalEventCount() {
181
+ let total = 0;
182
+ for (const count of this.eventCount.values()){
183
+ total += count;
184
+ }
185
+ return total;
186
+ }
187
+ /**
188
+ * Reset statistics
189
+ */ resetStats() {
190
+ this.eventCount.clear();
191
+ }
192
+ /**
193
+ * Check if any events of a specific type have been logged
194
+ */ hasEventsOfType(type) {
195
+ return (this.eventCount.get(type) || 0) > 0;
196
+ }
197
+ /**
198
+ * Get count for a specific event type
199
+ */ getEventCount(type) {
200
+ return this.eventCount.get(type) || 0;
201
+ }
202
+ shouldLog(severity) {
203
+ const levels = [
204
+ 'info',
205
+ 'warning',
206
+ 'error',
207
+ 'critical'
208
+ ];
209
+ const configLevel = levels.indexOf(this.config.logLevel === 'all' ? 'info' : this.config.logLevel);
210
+ const eventLevel = levels.indexOf(severity);
211
+ return eventLevel >= configLevel;
212
+ }
213
+ formatEvent(event) {
214
+ let message = `[${event.type}] ${event.message}`;
215
+ if (this.config.includeContext && event.context) {
216
+ message += ` | Context: ${JSON.stringify(event.context)}`;
217
+ }
218
+ return message;
219
+ }
220
+ sanitizeContext(context) {
221
+ if (!context || !this.config.includeContext) return undefined;
222
+ const sanitized = {};
223
+ let size = 0;
224
+ for (const [key, value] of Object.entries(context)){
225
+ const stringValue = String(value);
226
+ if (size + stringValue.length > this.config.maxContextSize) break;
227
+ // Never log sensitive-looking values
228
+ if (this.looksLikeSensitiveKey(key)) {
229
+ sanitized[key] = '[REDACTED]';
230
+ } else {
231
+ sanitized[key] = value;
232
+ }
233
+ size += stringValue.length;
234
+ }
235
+ return sanitized;
236
+ }
237
+ sanitizePath(path) {
238
+ // Only show last component and length
239
+ const parts = path.split(/[/\\]/);
240
+ const lastPart = parts[parts.length - 1];
241
+ return `.../${lastPart} (${path.length} chars)`;
242
+ }
243
+ looksLikeSensitiveKey(key) {
244
+ const sensitivePatterns = [
245
+ /key/i,
246
+ /secret/i,
247
+ /password/i,
248
+ /token/i,
249
+ /auth/i,
250
+ /credential/i
251
+ ];
252
+ return sensitivePatterns.some((p)=>p.test(key));
253
+ }
254
+ constructor(config = {}, logger){
255
+ _define_property(this, "config", void 0);
256
+ _define_property(this, "logger", void 0);
257
+ _define_property(this, "eventCount", new Map());
258
+ this.config = {
259
+ ...DEFAULT_CONFIG,
260
+ ...config
261
+ };
262
+ this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'SecurityAudit');
263
+ }
264
+ }
265
+ // Global instance for convenience
266
+ let globalAuditLogger = null;
267
+ function getAuditLogger() {
268
+ if (!globalAuditLogger) {
269
+ globalAuditLogger = new SecurityAuditLogger();
270
+ }
271
+ return globalAuditLogger;
272
+ }
273
+ function configureAuditLogger(config, logger) {
274
+ globalAuditLogger = new SecurityAuditLogger(config, logger);
275
+ }
276
+ function resetAuditLogger() {
277
+ globalAuditLogger = null;
278
+ }
279
+
280
+ export { SecurityAuditLogger, configureAuditLogger, getAuditLogger, resetAuditLogger };
281
+ //# sourceMappingURL=audit-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-logger.js","sources":["../../src/security/audit-logger.ts"],"sourcesContent":["import { SecurityEvent, SecurityEventType } from './events';\nimport { Logger, DEFAULT_LOGGER, wrapLogger } from '../logger';\n\nexport interface AuditLoggerConfig {\n enabled: boolean;\n logLevel: 'all' | 'warning' | 'error' | 'critical';\n includeContext: boolean;\n maxContextSize: number;\n onEvent?: (event: SecurityEvent) => void;\n}\n\nconst DEFAULT_CONFIG: AuditLoggerConfig = {\n enabled: true,\n logLevel: 'warning',\n includeContext: true,\n maxContextSize: 1000,\n};\n\nexport class SecurityAuditLogger {\n private config: AuditLoggerConfig;\n private logger: Logger;\n private eventCount: Map<SecurityEventType, number> = new Map();\n\n constructor(config: Partial<AuditLoggerConfig> = {}, logger?: Logger) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'SecurityAudit');\n }\n\n /**\n * Log a security event\n */\n log(event: Omit<SecurityEvent, 'timestamp'>): void {\n if (!this.config.enabled) return;\n\n const fullEvent: SecurityEvent = {\n ...event,\n timestamp: new Date(),\n context: this.sanitizeContext(event.context),\n };\n\n // Track event counts\n const count = this.eventCount.get(event.type) || 0;\n this.eventCount.set(event.type, count + 1);\n\n // Always call event handler for monitoring (before log level filter)\n this.config.onEvent?.(fullEvent);\n\n // Check log level for actual logging output\n if (!this.shouldLog(event.severity)) return;\n\n // Log the event\n const logMessage = this.formatEvent(fullEvent);\n \n switch (event.severity) {\n case 'critical':\n this.logger.error(`[CRITICAL] ${logMessage}`);\n break;\n case 'error':\n this.logger.error(logMessage);\n break;\n case 'warning':\n this.logger.warn(logMessage);\n break;\n case 'info':\n this.logger.info(logMessage);\n break;\n }\n }\n\n /**\n * Convenience methods for common events\n */\n pathTraversalBlocked(path: string, reason: string): void {\n this.log({\n type: 'path_traversal_blocked',\n severity: 'warning',\n message: `Path traversal attempt blocked: ${reason}`,\n context: { attemptedPath: this.sanitizePath(path) },\n });\n }\n\n pathValidationFailed(path: string, reason: string): void {\n this.log({\n type: 'path_validation_failed',\n severity: 'warning',\n message: `Path validation failed: ${reason}`,\n context: { attemptedPath: this.sanitizePath(path) },\n });\n }\n\n toolValidationFailed(toolName: string, reason: string): void {\n this.log({\n type: 'tool_validation_failed',\n severity: 'warning',\n message: `Tool parameter validation failed for \"${toolName}\": ${reason}`,\n context: { toolName },\n });\n }\n\n toolExecutionBlocked(toolName: string, reason: string): void {\n this.log({\n type: 'tool_execution_blocked',\n severity: 'error',\n message: `Tool execution blocked for \"${toolName}\": ${reason}`,\n context: { toolName },\n });\n }\n\n toolTimeout(toolName: string, timeoutMs: number): void {\n this.log({\n type: 'tool_timeout',\n severity: 'warning',\n message: `Tool \"${toolName}\" timed out after ${timeoutMs}ms`,\n context: { toolName, timeoutMs },\n });\n }\n\n secretRedacted(source: string): void {\n this.log({\n type: 'secret_redacted',\n severity: 'info',\n message: `Sensitive data redacted from ${source}`,\n context: { source },\n });\n }\n\n apiKeyUsed(provider: string): void {\n this.log({\n type: 'api_key_used',\n severity: 'info',\n message: `API key accessed for provider: ${provider}`,\n context: { provider },\n });\n }\n\n deserializationFailed(source: string, reason: string): void {\n this.log({\n type: 'deserialization_failed',\n severity: 'warning',\n message: `Deserialization failed from ${source}: ${reason}`,\n context: { source },\n });\n }\n\n regexTimeout(pattern: string, timeoutMs: number): void {\n this.log({\n type: 'regex_timeout',\n severity: 'warning',\n message: `Regex operation timed out after ${timeoutMs}ms`,\n context: { patternLength: pattern.length, timeoutMs },\n });\n }\n\n requestTimeout(operation: string, timeoutMs: number): void {\n this.log({\n type: 'request_timeout',\n severity: 'warning',\n message: `Operation \"${operation}\" timed out after ${timeoutMs}ms`,\n context: { operation, timeoutMs },\n });\n }\n\n rateLimitExceeded(resource: string, limit: number): void {\n this.log({\n type: 'rate_limit_exceeded',\n severity: 'warning',\n message: `Rate limit exceeded for ${resource}: limit is ${limit}`,\n context: { resource, limit },\n });\n }\n\n /**\n * Get event statistics\n */\n getStats(): Map<SecurityEventType, number> {\n return new Map(this.eventCount);\n }\n\n /**\n * Get total event count\n */\n getTotalEventCount(): number {\n let total = 0;\n for (const count of this.eventCount.values()) {\n total += count;\n }\n return total;\n }\n\n /**\n * Reset statistics\n */\n resetStats(): void {\n this.eventCount.clear();\n }\n\n /**\n * Check if any events of a specific type have been logged\n */\n hasEventsOfType(type: SecurityEventType): boolean {\n return (this.eventCount.get(type) || 0) > 0;\n }\n\n /**\n * Get count for a specific event type\n */\n getEventCount(type: SecurityEventType): number {\n return this.eventCount.get(type) || 0;\n }\n\n private shouldLog(severity: SecurityEvent['severity']): boolean {\n const levels = ['info', 'warning', 'error', 'critical'];\n const configLevel = levels.indexOf(this.config.logLevel === 'all' ? 'info' : this.config.logLevel);\n const eventLevel = levels.indexOf(severity);\n return eventLevel >= configLevel;\n }\n\n private formatEvent(event: SecurityEvent): string {\n let message = `[${event.type}] ${event.message}`;\n if (this.config.includeContext && event.context) {\n message += ` | Context: ${JSON.stringify(event.context)}`;\n }\n return message;\n }\n\n private sanitizeContext(context?: Record<string, unknown>): Record<string, unknown> | undefined {\n if (!context || !this.config.includeContext) return undefined;\n\n const sanitized: Record<string, unknown> = {};\n let size = 0;\n\n for (const [key, value] of Object.entries(context)) {\n const stringValue = String(value);\n if (size + stringValue.length > this.config.maxContextSize) break;\n \n // Never log sensitive-looking values\n if (this.looksLikeSensitiveKey(key)) {\n sanitized[key] = '[REDACTED]';\n } else {\n sanitized[key] = value;\n }\n size += stringValue.length;\n }\n\n return sanitized;\n }\n\n private sanitizePath(path: string): string {\n // Only show last component and length\n const parts = path.split(/[/\\\\]/);\n const lastPart = parts[parts.length - 1];\n return `.../${lastPart} (${path.length} chars)`;\n }\n\n private looksLikeSensitiveKey(key: string): boolean {\n const sensitivePatterns = [\n /key/i, /secret/i, /password/i, /token/i, /auth/i, /credential/i\n ];\n return sensitivePatterns.some(p => p.test(key));\n }\n}\n\n// Global instance for convenience\nlet globalAuditLogger: SecurityAuditLogger | null = null;\n\nexport function getAuditLogger(): SecurityAuditLogger {\n if (!globalAuditLogger) {\n globalAuditLogger = new SecurityAuditLogger();\n }\n return globalAuditLogger;\n}\n\nexport function configureAuditLogger(config: Partial<AuditLoggerConfig>, logger?: Logger): void {\n globalAuditLogger = new SecurityAuditLogger(config, logger);\n}\n\nexport function resetAuditLogger(): void {\n globalAuditLogger = null;\n}\n\n"],"names":["DEFAULT_CONFIG","enabled","logLevel","includeContext","maxContextSize","SecurityAuditLogger","log","event","config","fullEvent","timestamp","Date","context","sanitizeContext","count","eventCount","get","type","set","onEvent","shouldLog","severity","logMessage","formatEvent","logger","error","warn","info","pathTraversalBlocked","path","reason","message","attemptedPath","sanitizePath","pathValidationFailed","toolValidationFailed","toolName","toolExecutionBlocked","toolTimeout","timeoutMs","secretRedacted","source","apiKeyUsed","provider","deserializationFailed","regexTimeout","pattern","patternLength","length","requestTimeout","operation","rateLimitExceeded","resource","limit","getStats","Map","getTotalEventCount","total","values","resetStats","clear","hasEventsOfType","getEventCount","levels","configLevel","indexOf","eventLevel","JSON","stringify","undefined","sanitized","size","key","value","Object","entries","stringValue","String","looksLikeSensitiveKey","parts","split","lastPart","sensitivePatterns","some","p","test","wrapLogger","DEFAULT_LOGGER","globalAuditLogger","getAuditLogger","configureAuditLogger","resetAuditLogger"],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ import { z } from 'zod';
2
+ import { PathGuard, PathSecurityConfig } from './path-guard';
3
+ /**
4
+ * CLI Security configuration
5
+ */
6
+ export interface CLISecurityConfig {
7
+ /** Enable CLI security validation */
8
+ enabled: boolean;
9
+ /** Path security configuration */
10
+ paths: Partial<PathSecurityConfig>;
11
+ /** Allowed file extensions for input files */
12
+ allowedExtensions: string[];
13
+ /** Maximum string length for inputs */
14
+ maxStringLength: number;
15
+ /** Allow null bytes in strings */
16
+ allowNullBytes: boolean;
17
+ /** Allow control characters in strings */
18
+ allowControlChars: boolean;
19
+ }
20
+ /**
21
+ * Default CLI security configuration
22
+ */
23
+ export declare const DEFAULT_CLI_SECURITY: CLISecurityConfig;
24
+ /**
25
+ * String validation result
26
+ */
27
+ export interface StringValidationResult {
28
+ valid: boolean;
29
+ sanitized?: string;
30
+ error?: string;
31
+ violation?: string;
32
+ }
33
+ /**
34
+ * CLIValidator provides security validation for CLI inputs.
35
+ *
36
+ * Features:
37
+ * - Path validation with traversal prevention
38
+ * - String sanitization
39
+ * - Extension filtering
40
+ * - Audit logging
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const validator = new CLIValidator();
45
+ *
46
+ * // Validate a path argument
47
+ * const pathResult = validator.validatePath('../../../etc/passwd');
48
+ * if (!pathResult.valid) {
49
+ * console.error(pathResult.error);
50
+ * process.exit(1);
51
+ * }
52
+ *
53
+ * // Validate a string argument
54
+ * const stringResult = validator.validateString(userInput);
55
+ * ```
56
+ */
57
+ export declare class CLIValidator {
58
+ private config;
59
+ private pathGuard;
60
+ private auditLogger;
61
+ constructor(config?: Partial<CLISecurityConfig>);
62
+ /**
63
+ * Validate a path argument
64
+ *
65
+ * @param inputPath - The path to validate
66
+ * @param options - Additional validation options
67
+ * @returns Validation result
68
+ */
69
+ validatePath(inputPath: string, options?: {
70
+ checkExtension?: boolean;
71
+ operation?: string;
72
+ }): {
73
+ valid: boolean;
74
+ normalizedPath?: string;
75
+ error?: string;
76
+ };
77
+ /**
78
+ * Validate a string argument
79
+ *
80
+ * @param input - The string to validate
81
+ * @returns Validation result with sanitized string
82
+ */
83
+ validateString(input: string): StringValidationResult;
84
+ /**
85
+ * Validate a numeric argument
86
+ *
87
+ * @param input - The number to validate
88
+ * @param options - Validation options
89
+ * @returns Validation result
90
+ */
91
+ validateNumber(input: number, options?: {
92
+ min?: number;
93
+ max?: number;
94
+ integer?: boolean;
95
+ allowNaN?: boolean;
96
+ allowInfinity?: boolean;
97
+ }): {
98
+ valid: boolean;
99
+ error?: string;
100
+ };
101
+ /**
102
+ * Create a Zod schema for secure path validation
103
+ */
104
+ securePathSchema(options?: {
105
+ checkExtension?: boolean;
106
+ }): z.ZodString;
107
+ /**
108
+ * Create a Zod schema for secure string validation
109
+ */
110
+ secureStringSchema(): z.ZodString;
111
+ /**
112
+ * Create a Zod schema for secure number validation
113
+ */
114
+ secureNumberSchema(options?: {
115
+ min?: number;
116
+ max?: number;
117
+ integer?: boolean;
118
+ }): z.ZodNumber;
119
+ /**
120
+ * Get the underlying PathGuard
121
+ */
122
+ getPathGuard(): PathGuard;
123
+ /**
124
+ * Add a base path for path validation
125
+ */
126
+ addBasePath(basePath: string): void;
127
+ }
128
+ /**
129
+ * Create a CLI validator with RiotPrompt defaults
130
+ */
131
+ export declare function createRiotPromptValidator(basePaths?: string[]): CLIValidator;
132
+ /**
133
+ * Get the global CLI validator
134
+ */
135
+ export declare function getCLIValidator(): CLIValidator;
136
+ /**
137
+ * Configure the global CLI validator
138
+ */
139
+ export declare function configureCLIValidator(config: Partial<CLISecurityConfig>): void;
140
+ /**
141
+ * Reset the global CLI validator
142
+ */
143
+ export declare function resetCLIValidator(): void;