@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.
Files changed (102) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -9
  3. package/dist/application/app.d.ts +0 -7
  4. package/dist/application/app.js +1 -18
  5. package/dist/application/services/enhanced-error-service.d.ts +0 -64
  6. package/dist/application/services/enhanced-error-service.js +11 -82
  7. package/dist/application/services/validation-engine.d.ts +0 -65
  8. package/dist/application/services/validation-engine.js +5 -91
  9. package/dist/application/services/workflow-service.d.ts +0 -11
  10. package/dist/application/services/workflow-service.js +0 -17
  11. package/dist/application/use-cases/get-next-step.d.ts +0 -9
  12. package/dist/application/use-cases/get-next-step.js +0 -9
  13. package/dist/application/use-cases/get-workflow.d.ts +0 -9
  14. package/dist/application/use-cases/get-workflow.js +0 -17
  15. package/dist/application/use-cases/list-workflows.d.ts +0 -9
  16. package/dist/application/use-cases/list-workflows.js +0 -9
  17. package/dist/application/use-cases/validate-step-output.d.ts +0 -9
  18. package/dist/application/use-cases/validate-step-output.js +0 -9
  19. package/dist/application/use-cases/validate-workflow-json.d.ts +0 -12
  20. package/dist/application/use-cases/validate-workflow-json.js +0 -21
  21. package/dist/application/validation.d.ts +0 -1
  22. package/dist/application/validation.js +6 -5
  23. package/dist/cli.d.ts +0 -1
  24. package/dist/cli.js +7 -12
  25. package/dist/container.d.ts +0 -11
  26. package/dist/container.js +0 -6
  27. package/dist/core/error-handler.d.ts +0 -43
  28. package/dist/core/error-handler.js +0 -65
  29. package/dist/domain/index.d.ts +0 -1
  30. package/dist/domain/index.js +16 -4
  31. package/dist/index.d.ts +0 -1
  32. package/dist/index.js +0 -2
  33. package/dist/infrastructure/index.d.ts +0 -1
  34. package/dist/infrastructure/index.js +16 -4
  35. package/dist/infrastructure/rpc/handler.d.ts +0 -9
  36. package/dist/infrastructure/rpc/handler.js +3 -16
  37. package/dist/infrastructure/rpc/index.d.ts +0 -1
  38. package/dist/infrastructure/rpc/index.js +15 -3
  39. package/dist/infrastructure/rpc/server.d.ts +0 -1
  40. package/dist/infrastructure/rpc/server.js +0 -3
  41. package/dist/infrastructure/storage/caching-workflow-storage.d.ts +0 -4
  42. package/dist/infrastructure/storage/caching-workflow-storage.js +2 -9
  43. package/dist/infrastructure/storage/file-workflow-storage.d.ts +0 -28
  44. package/dist/infrastructure/storage/file-workflow-storage.js +14 -57
  45. package/dist/infrastructure/storage/git-workflow-storage.d.ts +0 -14
  46. package/dist/infrastructure/storage/git-workflow-storage.js +19 -51
  47. package/dist/infrastructure/storage/in-memory-storage.d.ts +0 -6
  48. package/dist/infrastructure/storage/in-memory-storage.js +0 -7
  49. package/dist/infrastructure/storage/index.d.ts +0 -1
  50. package/dist/infrastructure/storage/index.js +19 -7
  51. package/dist/infrastructure/storage/multi-directory-workflow-storage.d.ts +0 -18
  52. package/dist/infrastructure/storage/multi-directory-workflow-storage.js +7 -36
  53. package/dist/infrastructure/storage/plugin-workflow-storage.d.ts +0 -43
  54. package/dist/infrastructure/storage/plugin-workflow-storage.js +17 -78
  55. package/dist/infrastructure/storage/remote-workflow-storage.d.ts +0 -10
  56. package/dist/infrastructure/storage/remote-workflow-storage.js +6 -39
  57. package/dist/infrastructure/storage/schema-validating-workflow-storage.d.ts +0 -5
  58. package/dist/infrastructure/storage/schema-validating-workflow-storage.js +7 -12
  59. package/dist/infrastructure/storage/storage.d.ts +0 -14
  60. package/dist/infrastructure/storage/storage.js +2 -21
  61. package/dist/mcp-server.d.ts +0 -1
  62. package/dist/mcp-server.js +2 -14
  63. package/dist/tools/mcp_initialize.d.ts +0 -1
  64. package/dist/tools/mcp_initialize.js +2 -9
  65. package/dist/tools/mcp_shutdown.d.ts +0 -1
  66. package/dist/tools/mcp_shutdown.js +0 -1
  67. package/dist/tools/mcp_tools_list.d.ts +0 -1
  68. package/dist/tools/mcp_tools_list.js +0 -1
  69. package/dist/types/mcp-types.d.ts +0 -1
  70. package/dist/types/mcp-types.js +0 -8
  71. package/dist/types/server.d.ts +0 -1
  72. package/dist/types/server.js +0 -1
  73. package/dist/types/storage.d.ts +0 -20
  74. package/dist/types/storage.js +0 -4
  75. package/dist/types/workflow-types.d.ts +0 -1
  76. package/dist/types/workflow-types.js +0 -3
  77. package/dist/utils/condition-evaluator.d.ts +0 -15
  78. package/dist/utils/condition-evaluator.js +0 -24
  79. package/dist/utils/config.d.ts +0 -55
  80. package/dist/utils/config.js +0 -84
  81. package/dist/utils/storage-security.d.ts +0 -62
  82. package/dist/utils/storage-security.js +6 -62
  83. package/dist/validation/request-validator.d.ts +0 -1
  84. package/dist/validation/request-validator.js +6 -6
  85. package/dist/validation/response-validator.d.ts +0 -1
  86. package/dist/validation/response-validator.js +4 -21
  87. package/dist/validation/schemas.d.ts +0 -5
  88. package/dist/validation/schemas.js +0 -5
  89. package/package.json +7 -14
  90. package/spec/mcp-protocol-handshake.md +4 -3
  91. package/workflows/coding-task-workflow.json +46 -8
  92. package/workflows/document-creation-workflow.json +235 -0
  93. package/workflows/exploration-workflow.json +254 -0
  94. package/workflows/presentation-creation.json +71 -0
  95. package/workflows/systemic-bug-investigation.json +32 -14
  96. package/workflows/systemic-bug-investigation.json.bak +196 -0
  97. package/dist/mcp-server-simple.js +0 -391
  98. package/dist/types/session-types.d.ts +0 -354
  99. package/dist/types/session-types.d.ts.map +0 -1
  100. package/dist/types/session-types.js +0 -89
  101. package/dist/types/session-types.js.map +0 -1
  102. package/workflows/example-agent-role-workflow.json +0 -83
@@ -25,26 +25,6 @@ export interface ValidatedPluginWorkflowConfig extends Required<PluginWorkflowCo
25
25
  maxFiles: number;
26
26
  maxPlugins: number;
27
27
  }
28
- /**
29
- * Plugin-based workflow storage that loads workflows from npm packages
30
- * Workflows are distributed as npm packages with a specific structure
31
- *
32
- * Security features:
33
- * - Path traversal prevention
34
- * - File size limits
35
- * - Plugin count limits
36
- * - Safe package.json parsing
37
- *
38
- * Example package structure:
39
- * ```
40
- * my-workflow-pack/
41
- * ├── package.json
42
- * ├── index.js
43
- * └── workflows/
44
- * ├── my-workflow-1.json
45
- * └── my-workflow-2.json
46
- * ```
47
- */
48
28
  export declare class PluginWorkflowStorage implements IWorkflowStorage {
49
29
  private readonly config;
50
30
  private pluginCache;
@@ -63,28 +43,6 @@ export declare class PluginWorkflowStorage implements IWorkflowStorage {
63
43
  getLoadedPlugins(): WorkflowPlugin[];
64
44
  getConfig(): ValidatedPluginWorkflowConfig;
65
45
  }
66
- /**
67
- * Example package.json for a workflow plugin:
68
- *
69
- * ```json
70
- * {
71
- * "name": "workrail-workflows-ai-coding",
72
- * "version": "1.0.0",
73
- * "description": "AI-powered coding workflows for Workrail",
74
- * "main": "index.js",
75
- * "workrail": {
76
- * "workflows": true,
77
- * "category": "coding"
78
- * },
79
- * "keywords": ["workrail", "workflow", "ai", "coding"],
80
- * "author": "Your Name",
81
- * "license": "MIT"
82
- * }
83
- * ```
84
- */
85
- /**
86
- * Example configuration for different environments
87
- */
88
46
  export declare const PLUGIN_WORKFLOW_CONFIGS: {
89
47
  development: {
90
48
  scanInterval: number;
@@ -99,4 +57,3 @@ export declare const PLUGIN_WORKFLOW_CONFIGS: {
99
57
  maxPlugins: number;
100
58
  };
101
59
  };
102
- //# sourceMappingURL=plugin-workflow-storage.d.ts.map
@@ -1,52 +1,31 @@
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.PLUGIN_WORKFLOW_CONFIGS = exports.PluginWorkflowStorage = void 0;
4
- const tslib_1 = require("tslib");
5
- const path_1 = tslib_1.__importDefault(require("path"));
6
- const promises_1 = tslib_1.__importDefault(require("fs/promises"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const promises_1 = __importDefault(require("fs/promises"));
7
9
  const fs_1 = require("fs");
8
10
  const storage_security_1 = require("../../utils/storage-security");
9
11
  const error_handler_1 = require("../../core/error-handler");
10
- /**
11
- * Plugin-based workflow storage that loads workflows from npm packages
12
- * Workflows are distributed as npm packages with a specific structure
13
- *
14
- * Security features:
15
- * - Path traversal prevention
16
- * - File size limits
17
- * - Plugin count limits
18
- * - Safe package.json parsing
19
- *
20
- * Example package structure:
21
- * ```
22
- * my-workflow-pack/
23
- * ├── package.json
24
- * ├── index.js
25
- * └── workflows/
26
- * ├── my-workflow-1.json
27
- * └── my-workflow-2.json
28
- * ```
29
- */
30
12
  class PluginWorkflowStorage {
31
- config;
32
- pluginCache = new Map();
33
- lastScan = 0;
34
13
  constructor(config = {}) {
14
+ this.pluginCache = new Map();
15
+ this.lastScan = 0;
35
16
  this.config = this.validateAndNormalizeConfig(config);
36
17
  }
37
18
  validateAndNormalizeConfig(config) {
38
19
  const securityOptions = (0, storage_security_1.validateSecurityOptions)({
39
- maxFileSizeBytes: config.maxFileSize || 1024 * 1024 // 1MB default
20
+ maxFileSizeBytes: config.maxFileSize || 1024 * 1024
40
21
  });
41
22
  const pluginPaths = (config.pluginPaths && config.pluginPaths.length > 0)
42
23
  ? config.pluginPaths
43
24
  : this.getDefaultPluginPaths();
44
- // Validate all plugin paths are safe
45
25
  for (const pluginPath of pluginPaths) {
46
26
  try {
47
- // Ensure plugin paths are within reasonable bounds
48
27
  if (path_1.default.isAbsolute(pluginPath)) {
49
- (0, storage_security_1.assertWithinBase)(pluginPath, '/'); // Basic sanity check for absolute paths
28
+ (0, storage_security_1.assertWithinBase)(pluginPath, '/');
50
29
  }
51
30
  }
52
31
  catch (error) {
@@ -55,15 +34,14 @@ class PluginWorkflowStorage {
55
34
  }
56
35
  return {
57
36
  pluginPaths,
58
- scanInterval: Math.max(30000, config.scanInterval || 300000), // minimum 30 seconds
37
+ scanInterval: Math.max(30000, config.scanInterval || 300000),
59
38
  maxFileSize: securityOptions.maxFileSizeBytes,
60
- maxFiles: Math.max(1, config.maxFiles || 50), // minimum 1 file
61
- maxPlugins: Math.max(1, config.maxPlugins || 20) // maximum 20 plugins
39
+ maxFiles: Math.max(1, config.maxFiles || 50),
40
+ maxPlugins: Math.max(1, config.maxPlugins || 20)
62
41
  };
63
42
  }
64
43
  getDefaultPluginPaths() {
65
44
  const paths = [];
66
- // Global npm modules
67
45
  try {
68
46
  const globalPath = require.resolve('npm').replace(/\/npm\/.*$/, '');
69
47
  const globalNodeModules = path_1.default.join(globalPath, 'node_modules');
@@ -72,7 +50,6 @@ class PluginWorkflowStorage {
72
50
  }
73
51
  }
74
52
  catch {
75
- // Fallback: try common global paths
76
53
  const commonPaths = [
77
54
  '/usr/local/lib/node_modules',
78
55
  '/usr/lib/node_modules'
@@ -83,7 +60,6 @@ class PluginWorkflowStorage {
83
60
  }
84
61
  }
85
62
  }
86
- // Local project
87
63
  const localNodeModules = path_1.default.join(process.cwd(), 'node_modules');
88
64
  if ((0, fs_1.existsSync)(localNodeModules)) {
89
65
  paths.push(localNodeModules);
@@ -136,17 +112,14 @@ class PluginWorkflowStorage {
136
112
  continue;
137
113
  }
138
114
  try {
139
- // Security: Ensure we're scanning within expected directory
140
115
  (0, storage_security_1.assertWithinBase)(pluginPath, pluginPath);
141
116
  const entries = await promises_1.default.readdir(pluginPath);
142
117
  for (const entry of entries) {
143
- // Check plugin count limit
144
118
  if (pluginCount >= this.config.maxPlugins) {
145
119
  throw new error_handler_1.StorageError(`Too many plugins found (${pluginCount}), maximum allowed: ${this.config.maxPlugins}`);
146
120
  }
147
121
  if (this.isWorkflowPlugin(entry)) {
148
122
  const fullPath = path_1.default.join(pluginPath, entry);
149
- // Security: Ensure plugin path is within scan directory
150
123
  (0, storage_security_1.assertWithinBase)(fullPath, pluginPath);
151
124
  const plugin = await this.loadPlugin(fullPath);
152
125
  if (plugin) {
@@ -170,17 +143,14 @@ class PluginWorkflowStorage {
170
143
  }
171
144
  async loadPlugin(pluginPath) {
172
145
  try {
173
- // Security: Ensure plugin path is safe
174
146
  (0, storage_security_1.assertWithinBase)(pluginPath, path_1.default.dirname(pluginPath));
175
147
  const packageJsonPath = path_1.default.join(pluginPath, 'package.json');
176
148
  if (!(0, fs_1.existsSync)(packageJsonPath)) {
177
149
  return null;
178
150
  }
179
- // Security: Ensure package.json is within plugin directory
180
151
  (0, storage_security_1.assertWithinBase)(packageJsonPath, pluginPath);
181
- // Validate package.json size
182
152
  const packageStats = await promises_1.default.stat(packageJsonPath);
183
- (0, storage_security_1.validateFileSize)(packageStats.size, Math.min(this.config.maxFileSize, 64 * 1024), 'package.json'); // Max 64KB for package.json
153
+ (0, storage_security_1.validateFileSize)(packageStats.size, Math.min(this.config.maxFileSize, 64 * 1024), 'package.json');
184
154
  const packageContent = await promises_1.default.readFile(packageJsonPath, 'utf-8');
185
155
  let packageJson;
186
156
  try {
@@ -189,11 +159,9 @@ class PluginWorkflowStorage {
189
159
  catch (parseError) {
190
160
  throw new error_handler_1.InvalidWorkflowError(pluginPath, `Invalid package.json: ${parseError.message}`);
191
161
  }
192
- // Validate it's a workflow plugin
193
162
  if (!packageJson.workrail || !packageJson.workrail.workflows) {
194
163
  return null;
195
164
  }
196
- // Validate package name
197
165
  if (!packageJson.name || typeof packageJson.name !== 'string') {
198
166
  throw new error_handler_1.InvalidWorkflowError(pluginPath, `Invalid package name`);
199
167
  }
@@ -201,7 +169,6 @@ class PluginWorkflowStorage {
201
169
  if (!(0, fs_1.existsSync)(workflowsPath)) {
202
170
  return null;
203
171
  }
204
- // Security: Ensure workflows directory is within plugin
205
172
  (0, storage_security_1.assertWithinBase)(workflowsPath, pluginPath);
206
173
  const workflows = await this.loadWorkflowsFromDirectory(workflowsPath);
207
174
  return {
@@ -234,9 +201,7 @@ class PluginWorkflowStorage {
234
201
  for (const file of jsonFiles) {
235
202
  try {
236
203
  const filePath = path_1.default.join(workflowsPath, file);
237
- // Security: Ensure file is within workflows directory
238
204
  (0, storage_security_1.assertWithinBase)(filePath, workflowsPath);
239
- // Validate file size
240
205
  const stats = await promises_1.default.stat(filePath);
241
206
  (0, storage_security_1.validateFileSize)(stats.size, this.config.maxFileSize, file);
242
207
  const content = await promises_1.default.readFile(filePath, 'utf-8');
@@ -247,7 +212,6 @@ class PluginWorkflowStorage {
247
212
  catch (parseError) {
248
213
  throw new error_handler_1.InvalidWorkflowError(file, `Invalid JSON in workflow file: ${parseError.message}`);
249
214
  }
250
- // Validate workflow ID
251
215
  const sanitizedId = (0, storage_security_1.sanitizeId)(workflow.id);
252
216
  if (workflow.id !== sanitizedId) {
253
217
  throw new error_handler_1.InvalidWorkflowError(workflow.id, `Invalid workflow ID in file ${file}`);
@@ -278,42 +242,17 @@ class PluginWorkflowStorage {
278
242
  }
279
243
  }
280
244
  exports.PluginWorkflowStorage = PluginWorkflowStorage;
281
- /**
282
- * Example package.json for a workflow plugin:
283
- *
284
- * ```json
285
- * {
286
- * "name": "workrail-workflows-ai-coding",
287
- * "version": "1.0.0",
288
- * "description": "AI-powered coding workflows for Workrail",
289
- * "main": "index.js",
290
- * "workrail": {
291
- * "workflows": true,
292
- * "category": "coding"
293
- * },
294
- * "keywords": ["workrail", "workflow", "ai", "coding"],
295
- * "author": "Your Name",
296
- * "license": "MIT"
297
- * }
298
- * ```
299
- */
300
- /**
301
- * Example configuration for different environments
302
- */
303
245
  exports.PLUGIN_WORKFLOW_CONFIGS = {
304
- // Development environment with relaxed limits
305
246
  development: {
306
- scanInterval: 60000, // 1 minute
307
- maxFileSize: 2 * 1024 * 1024, // 2MB
247
+ scanInterval: 60000,
248
+ maxFileSize: 2 * 1024 * 1024,
308
249
  maxFiles: 100,
309
250
  maxPlugins: 50
310
251
  },
311
- // Production environment with strict limits
312
252
  production: {
313
- scanInterval: 300000, // 5 minutes
314
- maxFileSize: 1024 * 1024, // 1MB
253
+ scanInterval: 300000,
254
+ maxFileSize: 1024 * 1024,
315
255
  maxFiles: 50,
316
256
  maxPlugins: 20
317
257
  }
318
258
  };
319
- //# sourceMappingURL=plugin-workflow-storage.js.map
@@ -8,11 +8,6 @@ export interface RemoteWorkflowRegistryConfig extends StorageSecurityOptions {
8
8
  retryAttempts?: number;
9
9
  userAgent?: string;
10
10
  }
11
- /**
12
- * Remote workflow storage that fetches workflows from a community registry.
13
- * Implements security best practices and proper error handling.
14
- * Similar to npm registry but for workflows.
15
- */
16
11
  export declare class RemoteWorkflowStorage implements IWorkflowStorage {
17
12
  private readonly config;
18
13
  private readonly securityOptions;
@@ -28,10 +23,6 @@ export declare class RemoteWorkflowStorage implements IWorkflowStorage {
28
23
  private validateSummaries;
29
24
  private validateWorkflowForSave;
30
25
  }
31
- /**
32
- * Multi-source workflow storage that combines bundled, local, and remote workflows.
33
- * Uses composition to cleanly separate concerns.
34
- */
35
26
  export declare class CommunityWorkflowStorage implements IWorkflowStorage {
36
27
  private readonly sources;
37
28
  private readonly remoteStorage;
@@ -41,4 +32,3 @@ export declare class CommunityWorkflowStorage implements IWorkflowStorage {
41
32
  listWorkflowSummaries(): Promise<WorkflowSummary[]>;
42
33
  save(workflow: Workflow): Promise<void>;
43
34
  }
44
- //# sourceMappingURL=remote-workflow-storage.d.ts.map
@@ -3,21 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CommunityWorkflowStorage = exports.RemoteWorkflowStorage = void 0;
4
4
  const storage_security_1 = require("../../utils/storage-security");
5
5
  const error_handler_1 = require("../../core/error-handler");
6
- /**
7
- * Remote workflow storage that fetches workflows from a community registry.
8
- * Implements security best practices and proper error handling.
9
- * Similar to npm registry but for workflows.
10
- */
11
6
  class RemoteWorkflowStorage {
12
- config;
13
- securityOptions;
14
7
  constructor(config) {
15
- // Validate and secure the configuration
16
8
  this.validateConfig(config);
17
9
  this.securityOptions = (0, storage_security_1.validateSecurityOptions)(config);
18
10
  this.config = {
19
11
  ...this.securityOptions,
20
- baseUrl: config.baseUrl.replace(/\/$/, ''), // Remove trailing slash
12
+ baseUrl: config.baseUrl.replace(/\/$/, ''),
21
13
  apiKey: config.apiKey || '',
22
14
  timeout: config.timeout || 10000,
23
15
  retryAttempts: config.retryAttempts || 3,
@@ -28,9 +20,7 @@ class RemoteWorkflowStorage {
28
20
  if (!config.baseUrl) {
29
21
  throw new error_handler_1.SecurityError('baseUrl is required for remote storage', 'config-validation');
30
22
  }
31
- // Validate URL security
32
23
  (0, storage_security_1.validateSecureUrl)(config.baseUrl);
33
- // Validate timeout and retry settings (allow shorter timeouts for testing)
34
24
  if (config.timeout && (config.timeout < 100 || config.timeout > 60000)) {
35
25
  throw new error_handler_1.SecurityError('timeout must be between 100ms and 60000ms', 'config-validation');
36
26
  }
@@ -42,15 +32,13 @@ class RemoteWorkflowStorage {
42
32
  try {
43
33
  const response = await this.fetchWithRetry('/workflows');
44
34
  const data = await this.parseResponse(response);
45
- // Handle different response formats
46
35
  const workflows = data.workflows || data.data || [];
47
36
  return this.validateWorkflows(workflows);
48
37
  }
49
38
  catch (error) {
50
39
  if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.StorageError) {
51
- throw error; // Re-throw known errors
40
+ throw error;
52
41
  }
53
- // Transform unknown errors to storage errors for graceful degradation
54
42
  throw new error_handler_1.StorageError(`Failed to load workflows from remote registry: ${error.message}`, 'remote-fetch');
55
43
  }
56
44
  }
@@ -60,12 +48,11 @@ class RemoteWorkflowStorage {
60
48
  const response = await this.fetchWithRetry(`/workflows/${encodeURIComponent(sanitizedId)}`);
61
49
  if (!response.ok) {
62
50
  if (response.status === 404) {
63
- return null; // Workflow not found
51
+ return null;
64
52
  }
65
53
  throw new error_handler_1.StorageError(`Remote registry returned ${response.status}: ${response.statusText}`, 'remote-fetch');
66
54
  }
67
55
  const workflow = await this.parseResponse(response);
68
- // Verify the returned workflow ID matches what we requested
69
56
  if (workflow.id !== sanitizedId) {
70
57
  throw new error_handler_1.InvalidWorkflowError(sanitizedId, `Registry returned workflow with mismatched ID: ${workflow.id}`);
71
58
  }
@@ -141,9 +128,8 @@ class RemoteWorkflowStorage {
141
128
  catch (error) {
142
129
  lastError = error;
143
130
  if (attempt === this.config.retryAttempts) {
144
- break; // Don't wait after the last attempt
131
+ break;
145
132
  }
146
- // Exponential backoff with jitter
147
133
  const delay = Math.pow(2, attempt) * 1000 + Math.random() * 1000;
148
134
  await new Promise(resolve => setTimeout(resolve, delay));
149
135
  }
@@ -171,7 +157,6 @@ class RemoteWorkflowStorage {
171
157
  }
172
158
  return workflows.filter((workflow) => {
173
159
  try {
174
- // Basic validation - detailed validation should be handled by schema validator decorator
175
160
  if (!workflow || typeof workflow !== 'object') {
176
161
  return false;
177
162
  }
@@ -179,12 +164,11 @@ class RemoteWorkflowStorage {
179
164
  if (!wf.id || !wf.name || !wf.steps) {
180
165
  return false;
181
166
  }
182
- // Validate the ID is safe
183
167
  (0, storage_security_1.sanitizeId)(wf.id);
184
168
  return true;
185
169
  }
186
170
  catch {
187
- return false; // Skip invalid workflows
171
+ return false;
188
172
  }
189
173
  });
190
174
  }
@@ -201,7 +185,6 @@ class RemoteWorkflowStorage {
201
185
  if (!s.id || !s.name) {
202
186
  return false;
203
187
  }
204
- // Validate the ID is safe
205
188
  (0, storage_security_1.sanitizeId)(s.id);
206
189
  return true;
207
190
  }
@@ -217,7 +200,6 @@ class RemoteWorkflowStorage {
217
200
  if (!workflow.id || !workflow.name || !workflow.steps) {
218
201
  throw new error_handler_1.InvalidWorkflowError(workflow.id || 'unknown', 'Workflow must have id, name, and steps');
219
202
  }
220
- // Sanitize the ID
221
203
  const sanitizedId = (0, storage_security_1.sanitizeId)(workflow.id);
222
204
  return {
223
205
  ...workflow,
@@ -226,13 +208,7 @@ class RemoteWorkflowStorage {
226
208
  }
227
209
  }
228
210
  exports.RemoteWorkflowStorage = RemoteWorkflowStorage;
229
- /**
230
- * Multi-source workflow storage that combines bundled, local, and remote workflows.
231
- * Uses composition to cleanly separate concerns.
232
- */
233
211
  class CommunityWorkflowStorage {
234
- sources;
235
- remoteStorage;
236
212
  constructor(bundledStorage, localStorage, remoteConfig) {
237
213
  this.remoteStorage = new RemoteWorkflowStorage(remoteConfig);
238
214
  this.sources = [bundledStorage, localStorage, this.remoteStorage];
@@ -240,13 +216,11 @@ class CommunityWorkflowStorage {
240
216
  async loadAllWorkflows() {
241
217
  const allWorkflows = [];
242
218
  const seenIds = new Set();
243
- // Load from all sources, with later sources taking precedence
244
219
  for (const source of this.sources) {
245
220
  try {
246
221
  const workflows = await source.loadAllWorkflows();
247
222
  for (const workflow of workflows) {
248
223
  if (seenIds.has(workflow.id)) {
249
- // Replace existing workflow with same ID
250
224
  const existingIndex = allWorkflows.findIndex(wf => wf.id === workflow.id);
251
225
  if (existingIndex >= 0) {
252
226
  allWorkflows[existingIndex] = workflow;
@@ -259,8 +233,6 @@ class CommunityWorkflowStorage {
259
233
  }
260
234
  }
261
235
  catch (error) {
262
- // For storage sources, we want to continue even if one fails
263
- // This is intentional graceful degradation behavior
264
236
  if (error instanceof error_handler_1.StorageError) {
265
237
  console.warn(`Storage source failed (graceful degradation):`, error.message);
266
238
  }
@@ -274,7 +246,6 @@ class CommunityWorkflowStorage {
274
246
  async getWorkflowById(id) {
275
247
  try {
276
248
  const sanitizedId = (0, storage_security_1.sanitizeId)(id);
277
- // Search in reverse order (later sources take precedence)
278
249
  for (let i = this.sources.length - 1; i >= 0; i--) {
279
250
  try {
280
251
  const workflow = await this.sources[i].getWorkflowById(sanitizedId);
@@ -283,7 +254,6 @@ class CommunityWorkflowStorage {
283
254
  }
284
255
  }
285
256
  catch (error) {
286
- // Continue searching other sources if one fails
287
257
  if (error instanceof error_handler_1.StorageError) {
288
258
  console.warn(`Storage source failed for workflow ${sanitizedId}:`, error.message);
289
259
  }
@@ -296,13 +266,12 @@ class CommunityWorkflowStorage {
296
266
  }
297
267
  catch (error) {
298
268
  if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
299
- throw error; // Don't continue with invalid IDs
269
+ throw error;
300
270
  }
301
271
  throw new error_handler_1.StorageError(`Failed to retrieve workflow ${id}: ${error.message}`, 'multi-source-error');
302
272
  }
303
273
  }
304
274
  async listWorkflowSummaries() {
305
- // Reuse loadAllWorkflows for consistency and caching benefits
306
275
  const workflows = await this.loadAllWorkflows();
307
276
  return workflows.map(workflow => ({
308
277
  id: workflow.id,
@@ -313,9 +282,7 @@ class CommunityWorkflowStorage {
313
282
  }));
314
283
  }
315
284
  async save(workflow) {
316
- // Delegate to remote storage for publishing
317
285
  return this.remoteStorage.save(workflow);
318
286
  }
319
287
  }
320
288
  exports.CommunityWorkflowStorage = CommunityWorkflowStorage;
321
- //# sourceMappingURL=remote-workflow-storage.js.map
@@ -1,9 +1,5 @@
1
1
  import { IWorkflowStorage } from '../../types/storage';
2
2
  import { Workflow } from '../../types/mcp-types';
3
- /**
4
- * Decorator that filters or throws when underlying storage returns workflows
5
- * that do not conform to the JSON schema.
6
- */
7
3
  export declare class SchemaValidatingWorkflowStorage implements IWorkflowStorage {
8
4
  private readonly inner;
9
5
  private validator;
@@ -20,4 +16,3 @@ export declare class SchemaValidatingWorkflowStorage implements IWorkflowStorage
20
16
  }[]>;
21
17
  save?(workflow: Workflow): Promise<void>;
22
18
  }
23
- //# sourceMappingURL=schema-validating-workflow-storage.d.ts.map
@@ -1,18 +1,14 @@
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.SchemaValidatingWorkflowStorage = void 0;
4
- const tslib_1 = require("tslib");
5
- const fs_1 = tslib_1.__importDefault(require("fs"));
6
- const path_1 = tslib_1.__importDefault(require("path"));
7
- const ajv_1 = tslib_1.__importDefault(require("ajv"));
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const ajv_1 = __importDefault(require("ajv"));
8
10
  const error_handler_1 = require("../../core/error-handler");
9
- /**
10
- * Decorator that filters or throws when underlying storage returns workflows
11
- * that do not conform to the JSON schema.
12
- */
13
11
  class SchemaValidatingWorkflowStorage {
14
- inner;
15
- validator;
16
12
  constructor(inner) {
17
13
  this.inner = inner;
18
14
  const schemaPath = path_1.default.resolve(__dirname, '../../../spec/workflow.schema.json');
@@ -34,7 +30,7 @@ class SchemaValidatingWorkflowStorage {
34
30
  return this.ensureValid(wf);
35
31
  }
36
32
  catch {
37
- return false; // Skip invalid workflows
33
+ return false;
38
34
  }
39
35
  });
40
36
  }
@@ -67,4 +63,3 @@ class SchemaValidatingWorkflowStorage {
67
63
  }
68
64
  }
69
65
  exports.SchemaValidatingWorkflowStorage = SchemaValidatingWorkflowStorage;
70
- //# sourceMappingURL=schema-validating-workflow-storage.js.map
@@ -2,20 +2,6 @@ import { FileWorkflowStorage } from './file-workflow-storage';
2
2
  import { SchemaValidatingWorkflowStorage } from './schema-validating-workflow-storage';
3
3
  import { CachingWorkflowStorage } from './caching-workflow-storage';
4
4
  import { MultiDirectoryWorkflowStorage, createMultiDirectoryWorkflowStorage } from './multi-directory-workflow-storage';
5
- /**
6
- * Create the default, production-grade storage stack consisting of:
7
- * 1. Multi-directory workflow storage (bundled + user + project + custom)
8
- * 2. JSON-Schema validation decorator
9
- * 3. In-memory TTL cache decorator
10
- *
11
- * The function is intentionally side-effect-free – each invocation returns a
12
- * brand-new, fully-composed instance so that callers can choose whether to
13
- * share or isolate storage state.
14
- */
15
5
  export declare function createDefaultWorkflowStorage(): CachingWorkflowStorage;
16
- /**
17
- * Create the legacy single-directory storage (for backward compatibility)
18
- */
19
6
  export declare function createLegacyWorkflowStorage(): CachingWorkflowStorage;
20
7
  export { FileWorkflowStorage, SchemaValidatingWorkflowStorage, CachingWorkflowStorage, MultiDirectoryWorkflowStorage, createMultiDirectoryWorkflowStorage };
21
- //# sourceMappingURL=storage.d.ts.map
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- // Re-export new modular storage pieces and compose them to keep backward compatibility
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.createMultiDirectoryWorkflowStorage = exports.MultiDirectoryWorkflowStorage = exports.CachingWorkflowStorage = exports.SchemaValidatingWorkflowStorage = exports.FileWorkflowStorage = void 0;
5
4
  exports.createDefaultWorkflowStorage = createDefaultWorkflowStorage;
@@ -13,33 +12,15 @@ Object.defineProperty(exports, "CachingWorkflowStorage", { enumerable: true, get
13
12
  const multi_directory_workflow_storage_1 = require("./multi-directory-workflow-storage");
14
13
  Object.defineProperty(exports, "MultiDirectoryWorkflowStorage", { enumerable: true, get: function () { return multi_directory_workflow_storage_1.MultiDirectoryWorkflowStorage; } });
15
14
  Object.defineProperty(exports, "createMultiDirectoryWorkflowStorage", { enumerable: true, get: function () { return multi_directory_workflow_storage_1.createMultiDirectoryWorkflowStorage; } });
16
- // (intentionally left blank – no direct dependency on Workflow types here)
17
- // -----------------------------------------------------------------------------
18
- // Default composition helper – now exposed as a factory for DI friendliness
19
- // -----------------------------------------------------------------------------
20
- /**
21
- * Create the default, production-grade storage stack consisting of:
22
- * 1. Multi-directory workflow storage (bundled + user + project + custom)
23
- * 2. JSON-Schema validation decorator
24
- * 3. In-memory TTL cache decorator
25
- *
26
- * The function is intentionally side-effect-free – each invocation returns a
27
- * brand-new, fully-composed instance so that callers can choose whether to
28
- * share or isolate storage state.
29
- */
30
15
  function createDefaultWorkflowStorage() {
31
16
  const baseStorage = (0, multi_directory_workflow_storage_1.createMultiDirectoryWorkflowStorage)();
32
17
  const validatingStorage = new schema_validating_workflow_storage_1.SchemaValidatingWorkflowStorage(baseStorage);
33
- const cacheTtlMs = Number(process.env['CACHE_TTL'] ?? 300_000); // 5 minutes default
18
+ const cacheTtlMs = Number(process.env['CACHE_TTL'] ?? 300000);
34
19
  return new caching_workflow_storage_1.CachingWorkflowStorage(validatingStorage, cacheTtlMs);
35
20
  }
36
- /**
37
- * Create the legacy single-directory storage (for backward compatibility)
38
- */
39
21
  function createLegacyWorkflowStorage() {
40
22
  const baseStorage = (0, file_workflow_storage_1.createDefaultFileWorkflowStorage)();
41
23
  const validatingStorage = new schema_validating_workflow_storage_1.SchemaValidatingWorkflowStorage(baseStorage);
42
- const cacheTtlMs = Number(process.env['CACHE_TTL'] ?? 300_000); // 5 minutes default
24
+ const cacheTtlMs = Number(process.env['CACHE_TTL'] ?? 300000);
43
25
  return new caching_workflow_storage_1.CachingWorkflowStorage(validatingStorage, cacheTtlMs);
44
26
  }
45
- //# sourceMappingURL=storage.js.map
@@ -1,3 +1,2 @@
1
1
  #!/usr/bin/env node
2
2
  export {};
3
- //# sourceMappingURL=mcp-server.d.ts.map