@exaudeus/workrail 0.0.16 → 0.0.18
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/LICENSE +21 -0
- package/README.md +9 -9
- package/dist/application/app.d.ts +0 -7
- package/dist/application/app.js +1 -18
- package/dist/application/services/enhanced-error-service.d.ts +0 -64
- package/dist/application/services/enhanced-error-service.js +11 -82
- package/dist/application/services/validation-engine.d.ts +0 -65
- package/dist/application/services/validation-engine.js +5 -91
- package/dist/application/services/workflow-service.d.ts +0 -11
- package/dist/application/services/workflow-service.js +0 -17
- package/dist/application/use-cases/get-next-step.d.ts +0 -9
- package/dist/application/use-cases/get-next-step.js +0 -9
- package/dist/application/use-cases/get-workflow.d.ts +0 -9
- package/dist/application/use-cases/get-workflow.js +0 -17
- package/dist/application/use-cases/list-workflows.d.ts +0 -9
- package/dist/application/use-cases/list-workflows.js +0 -9
- package/dist/application/use-cases/validate-step-output.d.ts +0 -9
- package/dist/application/use-cases/validate-step-output.js +0 -9
- package/dist/application/use-cases/validate-workflow-json.d.ts +0 -12
- package/dist/application/use-cases/validate-workflow-json.js +0 -21
- package/dist/application/validation.d.ts +0 -1
- package/dist/application/validation.js +6 -5
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +7 -12
- package/dist/container.d.ts +0 -11
- package/dist/container.js +0 -6
- package/dist/core/error-handler.d.ts +0 -43
- package/dist/core/error-handler.js +0 -65
- package/dist/domain/index.d.ts +0 -1
- package/dist/domain/index.js +16 -4
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -2
- package/dist/infrastructure/index.d.ts +0 -1
- package/dist/infrastructure/index.js +16 -4
- package/dist/infrastructure/rpc/handler.d.ts +0 -9
- package/dist/infrastructure/rpc/handler.js +3 -16
- package/dist/infrastructure/rpc/index.d.ts +0 -1
- package/dist/infrastructure/rpc/index.js +15 -3
- package/dist/infrastructure/rpc/server.d.ts +0 -1
- package/dist/infrastructure/rpc/server.js +0 -3
- package/dist/infrastructure/storage/caching-workflow-storage.d.ts +0 -4
- package/dist/infrastructure/storage/caching-workflow-storage.js +2 -9
- package/dist/infrastructure/storage/file-workflow-storage.d.ts +0 -28
- package/dist/infrastructure/storage/file-workflow-storage.js +14 -57
- package/dist/infrastructure/storage/git-workflow-storage.d.ts +0 -14
- package/dist/infrastructure/storage/git-workflow-storage.js +19 -51
- package/dist/infrastructure/storage/in-memory-storage.d.ts +0 -6
- package/dist/infrastructure/storage/in-memory-storage.js +0 -7
- package/dist/infrastructure/storage/index.d.ts +0 -1
- package/dist/infrastructure/storage/index.js +19 -7
- package/dist/infrastructure/storage/multi-directory-workflow-storage.d.ts +0 -18
- package/dist/infrastructure/storage/multi-directory-workflow-storage.js +7 -36
- package/dist/infrastructure/storage/plugin-workflow-storage.d.ts +0 -43
- package/dist/infrastructure/storage/plugin-workflow-storage.js +17 -78
- package/dist/infrastructure/storage/remote-workflow-storage.d.ts +0 -10
- package/dist/infrastructure/storage/remote-workflow-storage.js +6 -39
- package/dist/infrastructure/storage/schema-validating-workflow-storage.d.ts +0 -5
- package/dist/infrastructure/storage/schema-validating-workflow-storage.js +7 -12
- package/dist/infrastructure/storage/storage.d.ts +0 -14
- package/dist/infrastructure/storage/storage.js +2 -21
- package/dist/mcp-server.d.ts +0 -1
- package/dist/mcp-server.js +2 -14
- package/dist/tools/mcp_initialize.d.ts +0 -1
- package/dist/tools/mcp_initialize.js +2 -9
- package/dist/tools/mcp_shutdown.d.ts +0 -1
- package/dist/tools/mcp_shutdown.js +0 -1
- package/dist/tools/mcp_tools_list.d.ts +0 -1
- package/dist/tools/mcp_tools_list.js +0 -1
- package/dist/types/mcp-types.d.ts +0 -1
- package/dist/types/mcp-types.js +0 -8
- package/dist/types/server.d.ts +0 -1
- package/dist/types/server.js +0 -1
- package/dist/types/storage.d.ts +0 -20
- package/dist/types/storage.js +0 -4
- package/dist/types/workflow-types.d.ts +0 -1
- package/dist/types/workflow-types.js +0 -3
- package/dist/utils/condition-evaluator.d.ts +0 -15
- package/dist/utils/condition-evaluator.js +0 -24
- package/dist/utils/config.d.ts +0 -55
- package/dist/utils/config.js +0 -84
- package/dist/utils/storage-security.d.ts +0 -62
- package/dist/utils/storage-security.js +6 -62
- package/dist/validation/request-validator.d.ts +0 -1
- package/dist/validation/request-validator.js +6 -6
- package/dist/validation/response-validator.d.ts +0 -1
- package/dist/validation/response-validator.js +4 -21
- package/dist/validation/schemas.d.ts +0 -5
- package/dist/validation/schemas.js +0 -5
- package/package.json +7 -14
- package/spec/mcp-protocol-handshake.md +4 -3
- package/workflows/coding-task-workflow.json +46 -8
- package/workflows/document-creation-workflow.json +235 -0
- package/workflows/exploration-workflow.json +254 -0
- package/workflows/presentation-creation.json +71 -0
- package/workflows/systemic-bug-investigation.json +32 -14
- package/workflows/systemic-bug-investigation.json.bak +196 -0
- package/dist/mcp-server-simple.js +0 -391
- package/dist/types/session-types.d.ts +0 -354
- package/dist/types/session-types.d.ts.map +0 -1
- package/dist/types/session-types.js +0 -89
- package/dist/types/session-types.js.map +0 -1
- package/workflows/example-agent-role-workflow.json +0 -83
package/dist/utils/config.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Configuration Management System
|
|
3
|
-
// Environment variable validation and type-safe configuration
|
|
4
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
3
|
exports.config = exports.Configuration = void 0;
|
|
6
4
|
exports.getConfig = getConfig;
|
|
@@ -8,66 +6,46 @@ exports.isFeatureEnabled = isFeatureEnabled;
|
|
|
8
6
|
exports.validateConfiguration = validateConfiguration;
|
|
9
7
|
exports.printConfigSummary = printConfigSummary;
|
|
10
8
|
const zod_1 = require("zod");
|
|
11
|
-
// =============================================================================
|
|
12
|
-
// CONFIGURATION SCHEMAS
|
|
13
|
-
// =============================================================================
|
|
14
9
|
const configSchema = zod_1.z.object({
|
|
15
|
-
// Core configuration
|
|
16
10
|
NODE_ENV: zod_1.z.enum(['development', 'production', 'test']).default('development'),
|
|
17
11
|
PORT: zod_1.z.string().transform(Number).pipe(zod_1.z.number().min(1).max(65535)).default('3000'),
|
|
18
12
|
HOST: zod_1.z.string().default('0.0.0.0'),
|
|
19
|
-
// MCP server configuration
|
|
20
13
|
MCP_SERVER_HOST: zod_1.z.string().default('localhost'),
|
|
21
14
|
MCP_SERVER_PORT: zod_1.z.string().transform(Number).pipe(zod_1.z.number().min(1).max(65535)).default('3000'),
|
|
22
|
-
// Workflow storage
|
|
23
15
|
WORKFLOW_STORAGE_PATH: zod_1.z.string().optional(),
|
|
24
16
|
WORKFLOW_STORAGE_TYPE: zod_1.z.enum(['file', 'database']).default('file'),
|
|
25
17
|
WORKFLOW_INCLUDE_BUNDLED: zod_1.z.string().transform(val => val !== 'false').default('true'),
|
|
26
18
|
WORKFLOW_INCLUDE_USER: zod_1.z.string().transform(val => val !== 'false').default('true'),
|
|
27
19
|
WORKFLOW_INCLUDE_PROJECT: zod_1.z.string().transform(val => val !== 'false').default('true'),
|
|
28
|
-
// Security settings
|
|
29
20
|
JWT_SECRET: zod_1.z.string().min(32, 'JWT secret must be at least 32 characters').default('your-super-secret-jwt-key-change-this-in-production'),
|
|
30
21
|
MCP_API_KEY: zod_1.z.string().optional(),
|
|
31
22
|
MAX_INPUT_SIZE: zod_1.z.string().transform(Number).pipe(zod_1.z.number().positive()).default('1048576'),
|
|
32
23
|
RATE_LIMIT_WINDOW: zod_1.z.string().transform(Number).pipe(zod_1.z.number().positive()).default('60000'),
|
|
33
24
|
RATE_LIMIT_MAX: zod_1.z.string().transform(Number).pipe(zod_1.z.number().positive()).default('100'),
|
|
34
|
-
// Performance settings
|
|
35
25
|
CACHE_TTL: zod_1.z.string().transform(Number).pipe(zod_1.z.number().positive()).default('300000'),
|
|
36
26
|
MAX_CONCURRENT_REQUESTS: zod_1.z.string().transform(Number).pipe(zod_1.z.number().positive()).default('1000'),
|
|
37
27
|
MEMORY_LIMIT: zod_1.z.string().default('100MB'),
|
|
38
|
-
// Logging & monitoring
|
|
39
28
|
LOG_LEVEL: zod_1.z.enum(['debug', 'info', 'warn', 'error']).default('info'),
|
|
40
29
|
METRICS_ENABLED: zod_1.z.string().transform(val => val === 'true').default('true'),
|
|
41
30
|
HEALTH_CHECK_INTERVAL: zod_1.z.string().transform(Number).pipe(zod_1.z.number().positive()).default('30000'),
|
|
42
|
-
// Database (optional)
|
|
43
31
|
DATABASE_URL: zod_1.z.string().optional(),
|
|
44
32
|
REDIS_URL: zod_1.z.string().optional(),
|
|
45
|
-
// Development settings
|
|
46
33
|
DEBUG: zod_1.z.string().transform(val => val === 'true').default('false'),
|
|
47
34
|
HOT_RELOAD: zod_1.z.string().transform(val => val === 'true').default('true'),
|
|
48
|
-
// Testing settings
|
|
49
35
|
TEST_DATABASE_URL: zod_1.z.string().default('sqlite::memory:'),
|
|
50
36
|
TEST_WORKFLOW_STORAGE_PATH: zod_1.z.string().default('./tests/fixtures/workflows'),
|
|
51
|
-
// Deployment settings
|
|
52
37
|
COMPRESSION_ENABLED: zod_1.z.string().transform(val => val === 'true').default('true'),
|
|
53
38
|
CORS_ORIGINS: zod_1.z.string().default('http://localhost:3000,http://localhost:3001'),
|
|
54
39
|
TRUST_PROXY: zod_1.z.string().transform(val => val === 'true').default('false'),
|
|
55
|
-
// Workflow specific settings
|
|
56
40
|
MAX_WORKFLOW_SIZE: zod_1.z.string().transform(Number).pipe(zod_1.z.number().positive()).default('1048576'),
|
|
57
41
|
MAX_WORKFLOW_STEPS: zod_1.z.string().transform(Number).pipe(zod_1.z.number().positive()).default('50'),
|
|
58
42
|
WORKFLOW_VALIDATION_ENABLED: zod_1.z.string().transform(val => val === 'true').default('true'),
|
|
59
43
|
WORKFLOW_VALIDATION_STRICT: zod_1.z.string().transform(val => val === 'true').default('true'),
|
|
60
|
-
// MCP protocol settings
|
|
61
44
|
MCP_PROTOCOL_VERSION: zod_1.z.string().default('2024-11-05'),
|
|
62
45
|
MCP_DEBUG: zod_1.z.string().transform(val => val === 'true').default('false'),
|
|
63
46
|
MCP_TIMEOUT: zod_1.z.string().transform(Number).pipe(zod_1.z.number().positive()).default('30000'),
|
|
64
47
|
});
|
|
65
|
-
// =============================================================================
|
|
66
|
-
// CONFIGURATION CLASS
|
|
67
|
-
// =============================================================================
|
|
68
48
|
class Configuration {
|
|
69
|
-
static instance;
|
|
70
|
-
config;
|
|
71
49
|
constructor() {
|
|
72
50
|
this.config = this.loadConfiguration();
|
|
73
51
|
}
|
|
@@ -77,14 +55,9 @@ class Configuration {
|
|
|
77
55
|
}
|
|
78
56
|
return Configuration.instance;
|
|
79
57
|
}
|
|
80
|
-
/**
|
|
81
|
-
* Load and validate configuration from environment variables
|
|
82
|
-
*/
|
|
83
58
|
loadConfiguration() {
|
|
84
59
|
try {
|
|
85
|
-
// Load environment variables
|
|
86
60
|
const envVars = process.env;
|
|
87
|
-
// Parse and validate configuration
|
|
88
61
|
const config = configSchema.parse(envVars);
|
|
89
62
|
return config;
|
|
90
63
|
}
|
|
@@ -99,15 +72,9 @@ class Configuration {
|
|
|
99
72
|
throw error;
|
|
100
73
|
}
|
|
101
74
|
}
|
|
102
|
-
/**
|
|
103
|
-
* Get the complete configuration object
|
|
104
|
-
*/
|
|
105
75
|
getConfig() {
|
|
106
76
|
return this.config;
|
|
107
77
|
}
|
|
108
|
-
/**
|
|
109
|
-
* Get server configuration
|
|
110
|
-
*/
|
|
111
78
|
getServerConfig() {
|
|
112
79
|
return {
|
|
113
80
|
port: this.config.PORT,
|
|
@@ -134,51 +101,27 @@ class Configuration {
|
|
|
134
101
|
},
|
|
135
102
|
};
|
|
136
103
|
}
|
|
137
|
-
/**
|
|
138
|
-
* Get a specific configuration value
|
|
139
|
-
*/
|
|
140
104
|
get(key) {
|
|
141
105
|
return this.config[key];
|
|
142
106
|
}
|
|
143
|
-
/**
|
|
144
|
-
* Check if running in development mode
|
|
145
|
-
*/
|
|
146
107
|
isDevelopment() {
|
|
147
108
|
return this.config.NODE_ENV === 'development';
|
|
148
109
|
}
|
|
149
|
-
/**
|
|
150
|
-
* Check if running in production mode
|
|
151
|
-
*/
|
|
152
110
|
isProduction() {
|
|
153
111
|
return this.config.NODE_ENV === 'production';
|
|
154
112
|
}
|
|
155
|
-
/**
|
|
156
|
-
* Check if running in test mode
|
|
157
|
-
*/
|
|
158
113
|
isTest() {
|
|
159
114
|
return this.config.NODE_ENV === 'test';
|
|
160
115
|
}
|
|
161
|
-
/**
|
|
162
|
-
* Check if debug mode is enabled
|
|
163
|
-
*/
|
|
164
116
|
isDebugEnabled() {
|
|
165
117
|
return this.config.DEBUG;
|
|
166
118
|
}
|
|
167
|
-
/**
|
|
168
|
-
* Check if metrics are enabled
|
|
169
|
-
*/
|
|
170
119
|
isMetricsEnabled() {
|
|
171
120
|
return this.config.METRICS_ENABLED;
|
|
172
121
|
}
|
|
173
|
-
/**
|
|
174
|
-
* Get CORS origins as array
|
|
175
|
-
*/
|
|
176
122
|
getCorsOrigins() {
|
|
177
123
|
return this.config.CORS_ORIGINS.split(',').map(origin => origin.trim());
|
|
178
124
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Get memory limit in bytes
|
|
181
|
-
*/
|
|
182
125
|
getMemoryLimitBytes() {
|
|
183
126
|
const memoryLimit = this.config.MEMORY_LIMIT;
|
|
184
127
|
const units = {
|
|
@@ -196,9 +139,6 @@ class Configuration {
|
|
|
196
139
|
const multiplier = units[unitUpper] ?? units['MB'];
|
|
197
140
|
return parseInt(value || '0') * (multiplier || 1);
|
|
198
141
|
}
|
|
199
|
-
/**
|
|
200
|
-
* Validate configuration for specific features
|
|
201
|
-
*/
|
|
202
142
|
validateFeatureConfig(feature) {
|
|
203
143
|
const errors = [];
|
|
204
144
|
switch (feature) {
|
|
@@ -228,9 +168,6 @@ class Configuration {
|
|
|
228
168
|
errors,
|
|
229
169
|
};
|
|
230
170
|
}
|
|
231
|
-
/**
|
|
232
|
-
* Get configuration summary for logging
|
|
233
|
-
*/
|
|
234
171
|
getConfigSummary() {
|
|
235
172
|
return {
|
|
236
173
|
environment: this.config.NODE_ENV,
|
|
@@ -262,27 +199,15 @@ class Configuration {
|
|
|
262
199
|
},
|
|
263
200
|
};
|
|
264
201
|
}
|
|
265
|
-
/**
|
|
266
|
-
* Reload configuration (useful for testing)
|
|
267
|
-
*/
|
|
268
202
|
reload() {
|
|
269
203
|
this.config = this.loadConfiguration();
|
|
270
204
|
}
|
|
271
205
|
}
|
|
272
206
|
exports.Configuration = Configuration;
|
|
273
|
-
// =============================================================================
|
|
274
|
-
// CONFIGURATION UTILITIES
|
|
275
|
-
// =============================================================================
|
|
276
207
|
exports.config = Configuration.getInstance();
|
|
277
|
-
/**
|
|
278
|
-
* Get configuration value with type safety
|
|
279
|
-
*/
|
|
280
208
|
function getConfig(key) {
|
|
281
209
|
return exports.config.get(key);
|
|
282
210
|
}
|
|
283
|
-
/**
|
|
284
|
-
* Check if feature is enabled
|
|
285
|
-
*/
|
|
286
211
|
function isFeatureEnabled(feature) {
|
|
287
212
|
switch (feature) {
|
|
288
213
|
case 'debug':
|
|
@@ -297,12 +222,8 @@ function isFeatureEnabled(feature) {
|
|
|
297
222
|
return false;
|
|
298
223
|
}
|
|
299
224
|
}
|
|
300
|
-
/**
|
|
301
|
-
* Validate all configuration
|
|
302
|
-
*/
|
|
303
225
|
function validateConfiguration() {
|
|
304
226
|
const errors = [];
|
|
305
|
-
// Validate core features
|
|
306
227
|
const features = ['database', 'redis', 'security', 'workflow-validation'];
|
|
307
228
|
for (const feature of features) {
|
|
308
229
|
const validation = exports.config.validateFeatureConfig(feature);
|
|
@@ -310,7 +231,6 @@ function validateConfiguration() {
|
|
|
310
231
|
errors.push(...validation.errors);
|
|
311
232
|
}
|
|
312
233
|
}
|
|
313
|
-
// Validate environment-specific requirements
|
|
314
234
|
if (exports.config.isProduction()) {
|
|
315
235
|
if (exports.config.get('JWT_SECRET') === 'your-super-secret-jwt-key-change-this-in-production') {
|
|
316
236
|
errors.push('JWT_SECRET must be changed in production');
|
|
@@ -324,12 +244,8 @@ function validateConfiguration() {
|
|
|
324
244
|
errors,
|
|
325
245
|
};
|
|
326
246
|
}
|
|
327
|
-
/**
|
|
328
|
-
* Print configuration summary
|
|
329
|
-
*/
|
|
330
247
|
function printConfigSummary() {
|
|
331
248
|
const summary = exports.config.getConfigSummary();
|
|
332
249
|
console.log('Configuration Summary:');
|
|
333
250
|
console.log(JSON.stringify(summary, null, 2));
|
|
334
251
|
}
|
|
335
|
-
//# sourceMappingURL=config.js.map
|
|
@@ -1,74 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Storage security utilities extracted from FileWorkflowStorage patterns
|
|
3
|
-
* for consistent security across all storage implementations.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Sanitize and validate workflow identifiers for security.
|
|
7
|
-
* Prevents null byte injection and enforces valid character set.
|
|
8
|
-
*
|
|
9
|
-
* @param id - The workflow identifier to validate
|
|
10
|
-
* @returns Normalized and validated identifier
|
|
11
|
-
* @throws SecurityError for null bytes
|
|
12
|
-
* @throws InvalidWorkflowError for invalid characters
|
|
13
|
-
*/
|
|
14
1
|
export declare function sanitizeId(id: string): string;
|
|
15
|
-
/**
|
|
16
|
-
* Assert that a resolved path stays within the specified base directory.
|
|
17
|
-
* Prevents path traversal attacks by ensuring no directory escape.
|
|
18
|
-
*
|
|
19
|
-
* @param resolvedPath - The fully resolved absolute path to check
|
|
20
|
-
* @param baseDir - The base directory that should contain the path
|
|
21
|
-
* @throws SecurityError if path escapes the base directory
|
|
22
|
-
*/
|
|
23
2
|
export declare function assertWithinBase(resolvedPath: string, baseDir: string): void;
|
|
24
|
-
/**
|
|
25
|
-
* Validate file size against security limits.
|
|
26
|
-
* Prevents resource exhaustion and DoS attacks via oversized files.
|
|
27
|
-
*
|
|
28
|
-
* @param fileSize - Size of the file in bytes
|
|
29
|
-
* @param maxSize - Maximum allowed size in bytes
|
|
30
|
-
* @param context - Context for error reporting (e.g., filename)
|
|
31
|
-
* @throws SecurityError if file exceeds size limit
|
|
32
|
-
*/
|
|
33
3
|
export declare function validateFileSize(fileSize: number, maxSize: number, context?: string): void;
|
|
34
|
-
/**
|
|
35
|
-
* Sanitize and resolve a file path safely within a base directory.
|
|
36
|
-
* Combines path resolution with base directory validation.
|
|
37
|
-
*
|
|
38
|
-
* @param basePath - The base directory
|
|
39
|
-
* @param relativePath - The relative path to resolve
|
|
40
|
-
* @returns Safely resolved absolute path
|
|
41
|
-
* @throws SecurityError if the resolved path escapes the base
|
|
42
|
-
*/
|
|
43
4
|
export declare function securePathResolve(basePath: string, relativePath: string): string;
|
|
44
|
-
/**
|
|
45
|
-
* Validate URL security for remote storage implementations.
|
|
46
|
-
* Ensures URLs use safe protocols and don't target local resources.
|
|
47
|
-
*
|
|
48
|
-
* @param url - The URL to validate
|
|
49
|
-
* @throws SecurityError for unsafe URLs
|
|
50
|
-
*/
|
|
51
5
|
export declare function validateSecureUrl(url: string): void;
|
|
52
|
-
/**
|
|
53
|
-
* Common security options interface for storage implementations.
|
|
54
|
-
*/
|
|
55
6
|
export interface StorageSecurityOptions {
|
|
56
|
-
/** Maximum file size in bytes (default: 1MB) */
|
|
57
7
|
maxFileSizeBytes?: number;
|
|
58
|
-
/** Whether to allow HTTP URLs (default: false, HTTPS only) */
|
|
59
8
|
allowHttp?: boolean;
|
|
60
|
-
/** Custom allowed URL patterns (advanced use) */
|
|
61
9
|
allowedUrlPatterns?: RegExp[];
|
|
62
10
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Default security configuration following FileWorkflowStorage patterns.
|
|
65
|
-
*/
|
|
66
11
|
export declare const DEFAULT_SECURITY_OPTIONS: Required<StorageSecurityOptions>;
|
|
67
|
-
/**
|
|
68
|
-
* Validate security options and apply defaults.
|
|
69
|
-
*
|
|
70
|
-
* @param options - User-provided security options
|
|
71
|
-
* @returns Validated options with defaults applied
|
|
72
|
-
*/
|
|
73
12
|
export declare function validateSecurityOptions(options?: StorageSecurityOptions): Required<StorageSecurityOptions>;
|
|
74
|
-
//# sourceMappingURL=storage-security.d.ts.map
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.DEFAULT_SECURITY_OPTIONS = void 0;
|
|
4
7
|
exports.sanitizeId = sanitizeId;
|
|
@@ -7,22 +10,8 @@ exports.validateFileSize = validateFileSize;
|
|
|
7
10
|
exports.securePathResolve = securePathResolve;
|
|
8
11
|
exports.validateSecureUrl = validateSecureUrl;
|
|
9
12
|
exports.validateSecurityOptions = validateSecurityOptions;
|
|
10
|
-
const
|
|
11
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
12
14
|
const error_handler_1 = require("../core/error-handler");
|
|
13
|
-
/**
|
|
14
|
-
* Storage security utilities extracted from FileWorkflowStorage patterns
|
|
15
|
-
* for consistent security across all storage implementations.
|
|
16
|
-
*/
|
|
17
|
-
/**
|
|
18
|
-
* Sanitize and validate workflow identifiers for security.
|
|
19
|
-
* Prevents null byte injection and enforces valid character set.
|
|
20
|
-
*
|
|
21
|
-
* @param id - The workflow identifier to validate
|
|
22
|
-
* @returns Normalized and validated identifier
|
|
23
|
-
* @throws SecurityError for null bytes
|
|
24
|
-
* @throws InvalidWorkflowError for invalid characters
|
|
25
|
-
*/
|
|
26
15
|
function sanitizeId(id) {
|
|
27
16
|
if (id.includes('\u0000')) {
|
|
28
17
|
throw new error_handler_1.SecurityError('Null byte detected in identifier', 'sanitizeId');
|
|
@@ -34,63 +23,28 @@ function sanitizeId(id) {
|
|
|
34
23
|
}
|
|
35
24
|
return normalised;
|
|
36
25
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Assert that a resolved path stays within the specified base directory.
|
|
39
|
-
* Prevents path traversal attacks by ensuring no directory escape.
|
|
40
|
-
*
|
|
41
|
-
* @param resolvedPath - The fully resolved absolute path to check
|
|
42
|
-
* @param baseDir - The base directory that should contain the path
|
|
43
|
-
* @throws SecurityError if path escapes the base directory
|
|
44
|
-
*/
|
|
45
26
|
function assertWithinBase(resolvedPath, baseDir) {
|
|
46
27
|
if (!resolvedPath.startsWith(baseDir + path_1.default.sep) && resolvedPath !== baseDir) {
|
|
47
28
|
throw new error_handler_1.SecurityError('Path escapes storage sandbox', 'file-access');
|
|
48
29
|
}
|
|
49
30
|
}
|
|
50
|
-
/**
|
|
51
|
-
* Validate file size against security limits.
|
|
52
|
-
* Prevents resource exhaustion and DoS attacks via oversized files.
|
|
53
|
-
*
|
|
54
|
-
* @param fileSize - Size of the file in bytes
|
|
55
|
-
* @param maxSize - Maximum allowed size in bytes
|
|
56
|
-
* @param context - Context for error reporting (e.g., filename)
|
|
57
|
-
* @throws SecurityError if file exceeds size limit
|
|
58
|
-
*/
|
|
59
31
|
function validateFileSize(fileSize, maxSize, context) {
|
|
60
32
|
if (fileSize > maxSize) {
|
|
61
33
|
const contextStr = context ? ` (${context})` : '';
|
|
62
34
|
throw new error_handler_1.SecurityError(`File exceeds size limit of ${maxSize} bytes${contextStr}`, 'file-size');
|
|
63
35
|
}
|
|
64
36
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Sanitize and resolve a file path safely within a base directory.
|
|
67
|
-
* Combines path resolution with base directory validation.
|
|
68
|
-
*
|
|
69
|
-
* @param basePath - The base directory
|
|
70
|
-
* @param relativePath - The relative path to resolve
|
|
71
|
-
* @returns Safely resolved absolute path
|
|
72
|
-
* @throws SecurityError if the resolved path escapes the base
|
|
73
|
-
*/
|
|
74
37
|
function securePathResolve(basePath, relativePath) {
|
|
75
38
|
const resolvedPath = path_1.default.resolve(basePath, relativePath);
|
|
76
39
|
assertWithinBase(resolvedPath, basePath);
|
|
77
40
|
return resolvedPath;
|
|
78
41
|
}
|
|
79
|
-
/**
|
|
80
|
-
* Validate URL security for remote storage implementations.
|
|
81
|
-
* Ensures URLs use safe protocols and don't target local resources.
|
|
82
|
-
*
|
|
83
|
-
* @param url - The URL to validate
|
|
84
|
-
* @throws SecurityError for unsafe URLs
|
|
85
|
-
*/
|
|
86
42
|
function validateSecureUrl(url) {
|
|
87
43
|
try {
|
|
88
44
|
const parsed = new URL(url);
|
|
89
|
-
// Only allow HTTPS and HTTP protocols
|
|
90
45
|
if (!['https:', 'http:'].includes(parsed.protocol)) {
|
|
91
46
|
throw new error_handler_1.SecurityError(`Unsafe protocol: ${parsed.protocol}. Only HTTP/HTTPS allowed`, 'url-validation');
|
|
92
47
|
}
|
|
93
|
-
// Prevent localhost and private IP access
|
|
94
48
|
const hostname = parsed.hostname.toLowerCase();
|
|
95
49
|
if (hostname === 'localhost' ||
|
|
96
50
|
hostname === '127.0.0.1' ||
|
|
@@ -107,28 +61,18 @@ function validateSecureUrl(url) {
|
|
|
107
61
|
throw new error_handler_1.SecurityError(`Invalid URL format: ${url}`, 'url-validation');
|
|
108
62
|
}
|
|
109
63
|
}
|
|
110
|
-
/**
|
|
111
|
-
* Default security configuration following FileWorkflowStorage patterns.
|
|
112
|
-
*/
|
|
113
64
|
exports.DEFAULT_SECURITY_OPTIONS = {
|
|
114
|
-
maxFileSizeBytes:
|
|
65
|
+
maxFileSizeBytes: 1000000,
|
|
115
66
|
allowHttp: false,
|
|
116
67
|
allowedUrlPatterns: []
|
|
117
68
|
};
|
|
118
|
-
/**
|
|
119
|
-
* Validate security options and apply defaults.
|
|
120
|
-
*
|
|
121
|
-
* @param options - User-provided security options
|
|
122
|
-
* @returns Validated options with defaults applied
|
|
123
|
-
*/
|
|
124
69
|
function validateSecurityOptions(options = {}) {
|
|
125
70
|
const validated = { ...exports.DEFAULT_SECURITY_OPTIONS, ...options };
|
|
126
71
|
if (validated.maxFileSizeBytes <= 0) {
|
|
127
72
|
throw new error_handler_1.SecurityError('maxFileSizeBytes must be positive', 'config-validation');
|
|
128
73
|
}
|
|
129
|
-
if (validated.maxFileSizeBytes >
|
|
74
|
+
if (validated.maxFileSizeBytes > 100000000) {
|
|
130
75
|
throw new error_handler_1.SecurityError('maxFileSizeBytes exceeds reasonable limit (100MB)', 'config-validation');
|
|
131
76
|
}
|
|
132
77
|
return validated;
|
|
133
78
|
}
|
|
134
|
-
//# sourceMappingURL=storage-security.js.map
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.requestValidator = void 0;
|
|
4
|
-
const
|
|
5
|
-
const ajv_1 = tslib_1.__importDefault(require("ajv"));
|
|
7
|
+
const ajv_1 = __importDefault(require("ajv"));
|
|
6
8
|
const schemas_1 = require("./schemas");
|
|
7
9
|
const error_handler_1 = require("../core/error-handler");
|
|
8
10
|
const mcp_types_1 = require("../types/mcp-types");
|
|
9
11
|
class RequestValidator {
|
|
10
|
-
ajv = new ajv_1.default({ allErrors: true, strict: false });
|
|
11
|
-
compiled = new Map();
|
|
12
12
|
constructor() {
|
|
13
|
+
this.ajv = new ajv_1.default({ allErrors: true, strict: false });
|
|
14
|
+
this.compiled = new Map();
|
|
13
15
|
for (const [method, schema] of Object.entries(schemas_1.methodParamSchemas)) {
|
|
14
16
|
this.compiled.set(method, this.ajv.compile(schema));
|
|
15
17
|
}
|
|
@@ -17,7 +19,6 @@ class RequestValidator {
|
|
|
17
19
|
validate(method, params) {
|
|
18
20
|
const validator = this.compiled.get(method);
|
|
19
21
|
if (!validator) {
|
|
20
|
-
// No schema registered – treat as allowed (for e.g., mcp handshake commands)
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
23
24
|
const valid = validator(params);
|
|
@@ -29,4 +30,3 @@ class RequestValidator {
|
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
exports.requestValidator = new RequestValidator();
|
|
32
|
-
//# sourceMappingURL=request-validator.js.map
|
|
@@ -4,9 +4,6 @@ exports.responseValidator = exports.ResponseValidator = exports.methodResultSche
|
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const error_handler_1 = require("../core/error-handler");
|
|
6
6
|
const idRegex = /^[A-Za-z0-9_-]+$/;
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
// Reusable fragments
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
7
|
const workflowSummarySchema = zod_1.z.object({
|
|
11
8
|
id: zod_1.z.string().regex(idRegex),
|
|
12
9
|
name: zod_1.z.string(),
|
|
@@ -34,7 +31,6 @@ const workflowSchema = zod_1.z.object({
|
|
|
34
31
|
steps: zod_1.z.array(workflowStepSchema),
|
|
35
32
|
metaGuidance: zod_1.z.array(zod_1.z.string()).optional()
|
|
36
33
|
});
|
|
37
|
-
// Mode parameter response schemas
|
|
38
34
|
const workflowMetadataSchema = zod_1.z.object({
|
|
39
35
|
id: zod_1.z.string().regex(idRegex),
|
|
40
36
|
name: zod_1.z.string(),
|
|
@@ -48,23 +44,16 @@ const workflowMetadataSchema = zod_1.z.object({
|
|
|
48
44
|
const workflowPreviewSchema = workflowMetadataSchema.extend({
|
|
49
45
|
firstStep: workflowStepSchema.nullable()
|
|
50
46
|
});
|
|
51
|
-
// Union schema for workflow_get that handles all three response types
|
|
52
47
|
const workflowGetResponseSchema = zod_1.z.union([
|
|
53
|
-
workflowSchema,
|
|
54
|
-
workflowMetadataSchema,
|
|
55
|
-
workflowPreviewSchema
|
|
48
|
+
workflowSchema,
|
|
49
|
+
workflowMetadataSchema,
|
|
50
|
+
workflowPreviewSchema
|
|
56
51
|
]);
|
|
57
|
-
// ---------------------------------------------------------------------------
|
|
58
|
-
// Method result schemas
|
|
59
|
-
// ---------------------------------------------------------------------------
|
|
60
52
|
exports.methodResultSchemas = {
|
|
61
|
-
// workflow_list → { workflows: WorkflowSummary[] }
|
|
62
53
|
workflow_list: zod_1.z.object({
|
|
63
54
|
workflows: zod_1.z.array(workflowSummarySchema)
|
|
64
55
|
}),
|
|
65
|
-
// workflow_get → Workflow | WorkflowMetadata | WorkflowPreview (union based on mode parameter)
|
|
66
56
|
workflow_get: workflowGetResponseSchema,
|
|
67
|
-
// workflow_next → { step, guidance, isComplete }
|
|
68
57
|
workflow_next: zod_1.z.object({
|
|
69
58
|
step: workflowStepSchema.nullable(),
|
|
70
59
|
guidance: zod_1.z.object({
|
|
@@ -75,25 +64,20 @@ exports.methodResultSchemas = {
|
|
|
75
64
|
}),
|
|
76
65
|
isComplete: zod_1.z.boolean()
|
|
77
66
|
}),
|
|
78
|
-
// workflow_validate → { valid, issues?, suggestions? }
|
|
79
67
|
workflow_validate: zod_1.z.object({
|
|
80
68
|
valid: zod_1.z.boolean(),
|
|
81
69
|
issues: zod_1.z.array(zod_1.z.string()).optional(),
|
|
82
70
|
suggestions: zod_1.z.array(zod_1.z.string()).optional()
|
|
83
71
|
})
|
|
84
72
|
};
|
|
85
|
-
// ---------------------------------------------------------------------------
|
|
86
|
-
// Validator class
|
|
87
|
-
// ---------------------------------------------------------------------------
|
|
88
73
|
class ResponseValidator {
|
|
89
|
-
compiled;
|
|
90
74
|
constructor(schemas) {
|
|
91
75
|
this.compiled = schemas;
|
|
92
76
|
}
|
|
93
77
|
validate(method, result) {
|
|
94
78
|
const schema = this.compiled[method];
|
|
95
79
|
if (!schema)
|
|
96
|
-
return;
|
|
80
|
+
return;
|
|
97
81
|
const parsed = schema.safeParse(result);
|
|
98
82
|
if (!parsed.success) {
|
|
99
83
|
throw new error_handler_1.ValidationError('Invalid response', undefined, parsed.error.format());
|
|
@@ -102,4 +86,3 @@ class ResponseValidator {
|
|
|
102
86
|
}
|
|
103
87
|
exports.ResponseValidator = ResponseValidator;
|
|
104
88
|
exports.responseValidator = new ResponseValidator(exports.methodResultSchemas);
|
|
105
|
-
//# sourceMappingURL=response-validator.js.map
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.methodParamSchemas = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Collection of per-method parameter schemas used for request validation.
|
|
6
|
-
* Using raw schema objects to keep typings simple.
|
|
7
|
-
*/
|
|
8
4
|
exports.methodParamSchemas = {
|
|
9
5
|
workflow_list: {
|
|
10
6
|
type: 'object',
|
|
@@ -55,4 +51,3 @@ exports.methodParamSchemas = {
|
|
|
55
51
|
additionalProperties: false
|
|
56
52
|
}
|
|
57
53
|
};
|
|
58
|
-
//# sourceMappingURL=schemas.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exaudeus/workrail",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "MCP server for structured workflow orchestration and step-by-step task guidance",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -12,10 +12,8 @@
|
|
|
12
12
|
"workflows"
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
|
-
"build": "tsc
|
|
15
|
+
"build": "tsc -p tsconfig.build.json",
|
|
16
16
|
"dev": "npm run build && node dist/mcp-server.js",
|
|
17
|
-
"test": "jest",
|
|
18
|
-
"test:performance": "jest --config jest.performance.config.cjs",
|
|
19
17
|
"prepare": "npm run build",
|
|
20
18
|
"watch": "tsc --watch"
|
|
21
19
|
},
|
|
@@ -30,15 +28,6 @@
|
|
|
30
28
|
"tslib": "^2.8.1",
|
|
31
29
|
"zod": "^3.22.4"
|
|
32
30
|
},
|
|
33
|
-
"devDependencies": {
|
|
34
|
-
"@types/jest": "^29.5.5",
|
|
35
|
-
"@types/node": "^20.6.3",
|
|
36
|
-
"jest": "^29.7.0",
|
|
37
|
-
"shx": "^0.3.4",
|
|
38
|
-
"ts-jest": "^29.1.1",
|
|
39
|
-
"ts-node": "^10.9.1",
|
|
40
|
-
"typescript": "^5.2.2"
|
|
41
|
-
},
|
|
42
31
|
"keywords": [
|
|
43
32
|
"mcp",
|
|
44
33
|
"model-context-protocol",
|
|
@@ -46,5 +35,9 @@
|
|
|
46
35
|
"orchestration",
|
|
47
36
|
"ai-assistant",
|
|
48
37
|
"task-management"
|
|
49
|
-
]
|
|
38
|
+
],
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.19.9",
|
|
41
|
+
"typescript": "^5.8.3"
|
|
42
|
+
}
|
|
50
43
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
# MCP Protocol Specification
|
|
1
|
+
# MCP Protocol Handshake Specification
|
|
2
2
|
|
|
3
|
-
> 🤝 **
|
|
3
|
+
> 🤝 **Specification for the MCP protocol handshake**
|
|
4
4
|
|
|
5
|
-
[](https://github.com/
|
|
5
|
+
[](https://github.com/EtienneBBeaulac/mcp)
|
|
6
|
+
[](specs/)
|
|
6
7
|
[](https://modelcontextprotocol.org)
|
|
7
8
|
[](https://www.jsonrpc.org/specification)
|
|
8
9
|
|