@exaudeus/workrail 0.0.12 → 0.0.13

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.
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ 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 fs_1 = require("fs");
8
+ const storage_security_1 = require("../../utils/storage-security");
9
+ 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
+ class PluginWorkflowStorage {
31
+ config;
32
+ pluginCache = new Map();
33
+ lastScan = 0;
34
+ constructor(config = {}) {
35
+ this.config = this.validateAndNormalizeConfig(config);
36
+ }
37
+ validateAndNormalizeConfig(config) {
38
+ const securityOptions = (0, storage_security_1.validateSecurityOptions)({
39
+ maxFileSizeBytes: config.maxFileSize || 1024 * 1024 // 1MB default
40
+ });
41
+ const pluginPaths = (config.pluginPaths && config.pluginPaths.length > 0)
42
+ ? config.pluginPaths
43
+ : this.getDefaultPluginPaths();
44
+ // Validate all plugin paths are safe
45
+ for (const pluginPath of pluginPaths) {
46
+ try {
47
+ // Ensure plugin paths are within reasonable bounds
48
+ if (path_1.default.isAbsolute(pluginPath)) {
49
+ (0, storage_security_1.assertWithinBase)(pluginPath, '/'); // Basic sanity check for absolute paths
50
+ }
51
+ }
52
+ catch (error) {
53
+ throw new error_handler_1.SecurityError(`Unsafe plugin path: ${pluginPath}: ${error.message}`);
54
+ }
55
+ }
56
+ return {
57
+ pluginPaths,
58
+ scanInterval: Math.max(30000, config.scanInterval || 300000), // minimum 30 seconds
59
+ 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
62
+ };
63
+ }
64
+ getDefaultPluginPaths() {
65
+ const paths = [];
66
+ // Global npm modules
67
+ try {
68
+ const globalPath = require.resolve('npm').replace(/\/npm\/.*$/, '');
69
+ const globalNodeModules = path_1.default.join(globalPath, 'node_modules');
70
+ if ((0, fs_1.existsSync)(globalNodeModules)) {
71
+ paths.push(globalNodeModules);
72
+ }
73
+ }
74
+ catch {
75
+ // Fallback: try common global paths
76
+ const commonPaths = [
77
+ '/usr/local/lib/node_modules',
78
+ '/usr/lib/node_modules'
79
+ ];
80
+ for (const commonPath of commonPaths) {
81
+ if ((0, fs_1.existsSync)(commonPath)) {
82
+ paths.push(commonPath);
83
+ }
84
+ }
85
+ }
86
+ // Local project
87
+ const localNodeModules = path_1.default.join(process.cwd(), 'node_modules');
88
+ if ((0, fs_1.existsSync)(localNodeModules)) {
89
+ paths.push(localNodeModules);
90
+ }
91
+ return paths;
92
+ }
93
+ async loadAllWorkflows() {
94
+ try {
95
+ await this.scanPlugins();
96
+ const workflows = [];
97
+ for (const plugin of this.pluginCache.values()) {
98
+ workflows.push(...plugin.workflows);
99
+ }
100
+ return workflows;
101
+ }
102
+ catch (error) {
103
+ if (error instanceof error_handler_1.StorageError || error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
104
+ throw error;
105
+ }
106
+ throw new error_handler_1.StorageError(`Failed to load plugin workflows: ${error.message}`);
107
+ }
108
+ }
109
+ async getWorkflowById(id) {
110
+ const sanitizedId = (0, storage_security_1.sanitizeId)(id);
111
+ const workflows = await this.loadAllWorkflows();
112
+ return workflows.find(w => w.id === sanitizedId) || null;
113
+ }
114
+ async listWorkflowSummaries() {
115
+ const workflows = await this.loadAllWorkflows();
116
+ return workflows.map(workflow => ({
117
+ id: workflow.id,
118
+ name: workflow.name,
119
+ description: workflow.description,
120
+ category: 'plugin',
121
+ version: workflow.version
122
+ }));
123
+ }
124
+ async save() {
125
+ throw new error_handler_1.StorageError('Plugin-based storage is read-only. Publish workflows as npm packages instead.');
126
+ }
127
+ async scanPlugins() {
128
+ const now = Date.now();
129
+ if (now - this.lastScan < this.config.scanInterval) {
130
+ return;
131
+ }
132
+ this.pluginCache.clear();
133
+ let pluginCount = 0;
134
+ for (const pluginPath of this.config.pluginPaths) {
135
+ if (!(0, fs_1.existsSync)(pluginPath)) {
136
+ continue;
137
+ }
138
+ try {
139
+ // Security: Ensure we're scanning within expected directory
140
+ (0, storage_security_1.assertWithinBase)(pluginPath, pluginPath);
141
+ const entries = await promises_1.default.readdir(pluginPath);
142
+ for (const entry of entries) {
143
+ // Check plugin count limit
144
+ if (pluginCount >= this.config.maxPlugins) {
145
+ throw new error_handler_1.StorageError(`Too many plugins found (${pluginCount}), maximum allowed: ${this.config.maxPlugins}`);
146
+ }
147
+ if (this.isWorkflowPlugin(entry)) {
148
+ const fullPath = path_1.default.join(pluginPath, entry);
149
+ // Security: Ensure plugin path is within scan directory
150
+ (0, storage_security_1.assertWithinBase)(fullPath, pluginPath);
151
+ const plugin = await this.loadPlugin(fullPath);
152
+ if (plugin) {
153
+ this.pluginCache.set(plugin.name, plugin);
154
+ pluginCount++;
155
+ }
156
+ }
157
+ }
158
+ }
159
+ catch (error) {
160
+ if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.StorageError) {
161
+ throw error;
162
+ }
163
+ throw new error_handler_1.StorageError(`Failed to scan plugin directory ${pluginPath}: ${error.message}`);
164
+ }
165
+ }
166
+ this.lastScan = now;
167
+ }
168
+ isWorkflowPlugin(entry) {
169
+ return entry.startsWith('workrail-workflows-') || entry.startsWith('@workrail/workflows-');
170
+ }
171
+ async loadPlugin(pluginPath) {
172
+ try {
173
+ // Security: Ensure plugin path is safe
174
+ (0, storage_security_1.assertWithinBase)(pluginPath, path_1.default.dirname(pluginPath));
175
+ const packageJsonPath = path_1.default.join(pluginPath, 'package.json');
176
+ if (!(0, fs_1.existsSync)(packageJsonPath)) {
177
+ return null;
178
+ }
179
+ // Security: Ensure package.json is within plugin directory
180
+ (0, storage_security_1.assertWithinBase)(packageJsonPath, pluginPath);
181
+ // Validate package.json size
182
+ 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
184
+ const packageContent = await promises_1.default.readFile(packageJsonPath, 'utf-8');
185
+ let packageJson;
186
+ try {
187
+ packageJson = JSON.parse(packageContent);
188
+ }
189
+ catch (parseError) {
190
+ throw new error_handler_1.InvalidWorkflowError(pluginPath, `Invalid package.json: ${parseError.message}`);
191
+ }
192
+ // Validate it's a workflow plugin
193
+ if (!packageJson.workrail || !packageJson.workrail.workflows) {
194
+ return null;
195
+ }
196
+ // Validate package name
197
+ if (!packageJson.name || typeof packageJson.name !== 'string') {
198
+ throw new error_handler_1.InvalidWorkflowError(pluginPath, `Invalid package name`);
199
+ }
200
+ const workflowsPath = path_1.default.join(pluginPath, 'workflows');
201
+ if (!(0, fs_1.existsSync)(workflowsPath)) {
202
+ return null;
203
+ }
204
+ // Security: Ensure workflows directory is within plugin
205
+ (0, storage_security_1.assertWithinBase)(workflowsPath, pluginPath);
206
+ const workflows = await this.loadWorkflowsFromDirectory(workflowsPath);
207
+ return {
208
+ name: packageJson.name,
209
+ version: packageJson.version || '0.0.0',
210
+ workflows,
211
+ metadata: {
212
+ author: packageJson.author,
213
+ description: packageJson.description,
214
+ homepage: packageJson.homepage,
215
+ repository: packageJson.repository?.url || packageJson.repository
216
+ }
217
+ };
218
+ }
219
+ catch (error) {
220
+ if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
221
+ throw error;
222
+ }
223
+ throw new error_handler_1.StorageError(`Failed to load plugin from ${pluginPath}: ${error.message}`);
224
+ }
225
+ }
226
+ async loadWorkflowsFromDirectory(workflowsPath) {
227
+ const workflows = [];
228
+ try {
229
+ const files = await promises_1.default.readdir(workflowsPath);
230
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
231
+ if (jsonFiles.length > this.config.maxFiles) {
232
+ throw new error_handler_1.StorageError(`Too many workflow files in ${workflowsPath} (${jsonFiles.length}), maximum allowed: ${this.config.maxFiles}`);
233
+ }
234
+ for (const file of jsonFiles) {
235
+ try {
236
+ const filePath = path_1.default.join(workflowsPath, file);
237
+ // Security: Ensure file is within workflows directory
238
+ (0, storage_security_1.assertWithinBase)(filePath, workflowsPath);
239
+ // Validate file size
240
+ const stats = await promises_1.default.stat(filePath);
241
+ (0, storage_security_1.validateFileSize)(stats.size, this.config.maxFileSize, file);
242
+ const content = await promises_1.default.readFile(filePath, 'utf-8');
243
+ let workflow;
244
+ try {
245
+ workflow = JSON.parse(content);
246
+ }
247
+ catch (parseError) {
248
+ throw new error_handler_1.InvalidWorkflowError(file, `Invalid JSON in workflow file: ${parseError.message}`);
249
+ }
250
+ // Validate workflow ID
251
+ const sanitizedId = (0, storage_security_1.sanitizeId)(workflow.id);
252
+ if (workflow.id !== sanitizedId) {
253
+ throw new error_handler_1.InvalidWorkflowError(workflow.id, `Invalid workflow ID in file ${file}`);
254
+ }
255
+ workflows.push(workflow);
256
+ }
257
+ catch (error) {
258
+ if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
259
+ throw error;
260
+ }
261
+ throw new error_handler_1.StorageError(`Failed to load workflow from ${file}: ${error.message}`);
262
+ }
263
+ }
264
+ }
265
+ catch (error) {
266
+ if (error instanceof error_handler_1.StorageError || error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
267
+ throw error;
268
+ }
269
+ throw new error_handler_1.StorageError(`Failed to read workflows directory ${workflowsPath}: ${error.message}`);
270
+ }
271
+ return workflows;
272
+ }
273
+ getLoadedPlugins() {
274
+ return Array.from(this.pluginCache.values());
275
+ }
276
+ getConfig() {
277
+ return { ...this.config };
278
+ }
279
+ }
280
+ 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
+ exports.PLUGIN_WORKFLOW_CONFIGS = {
304
+ // Development environment with relaxed limits
305
+ development: {
306
+ scanInterval: 60000, // 1 minute
307
+ maxFileSize: 2 * 1024 * 1024, // 2MB
308
+ maxFiles: 100,
309
+ maxPlugins: 50
310
+ },
311
+ // Production environment with strict limits
312
+ production: {
313
+ scanInterval: 300000, // 5 minutes
314
+ maxFileSize: 1024 * 1024, // 1MB
315
+ maxFiles: 50,
316
+ maxPlugins: 20
317
+ }
318
+ };
319
+ //# sourceMappingURL=plugin-workflow-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-workflow-storage.js","sourceRoot":"","sources":["../../../src/infrastructure/storage/plugin-workflow-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { IWorkflowStorage } from '../../types/storage';
2
+ import { Workflow, WorkflowSummary } from '../../types/mcp-types';
3
+ import { StorageSecurityOptions } from '../../utils/storage-security';
4
+ export interface RemoteWorkflowRegistryConfig extends StorageSecurityOptions {
5
+ baseUrl: string;
6
+ apiKey?: string;
7
+ timeout?: number;
8
+ retryAttempts?: number;
9
+ userAgent?: string;
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
+ export declare class RemoteWorkflowStorage implements IWorkflowStorage {
17
+ private readonly config;
18
+ private readonly securityOptions;
19
+ constructor(config: RemoteWorkflowRegistryConfig);
20
+ private validateConfig;
21
+ loadAllWorkflows(): Promise<Workflow[]>;
22
+ getWorkflowById(id: string): Promise<Workflow | null>;
23
+ listWorkflowSummaries(): Promise<WorkflowSummary[]>;
24
+ save(workflow: Workflow): Promise<void>;
25
+ private fetchWithRetry;
26
+ private parseResponse;
27
+ private validateWorkflows;
28
+ private validateSummaries;
29
+ private validateWorkflowForSave;
30
+ }
31
+ /**
32
+ * Multi-source workflow storage that combines bundled, local, and remote workflows.
33
+ * Uses composition to cleanly separate concerns.
34
+ */
35
+ export declare class CommunityWorkflowStorage implements IWorkflowStorage {
36
+ private readonly sources;
37
+ private readonly remoteStorage;
38
+ constructor(bundledStorage: IWorkflowStorage, localStorage: IWorkflowStorage, remoteConfig: RemoteWorkflowRegistryConfig);
39
+ loadAllWorkflows(): Promise<Workflow[]>;
40
+ getWorkflowById(id: string): Promise<Workflow | null>;
41
+ listWorkflowSummaries(): Promise<WorkflowSummary[]>;
42
+ save(workflow: Workflow): Promise<void>;
43
+ }
44
+ //# sourceMappingURL=remote-workflow-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-workflow-storage.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/storage/remote-workflow-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAIL,sBAAsB,EACvB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,4BAA6B,SAAQ,sBAAsB;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;gBAEvD,MAAM,EAAE,4BAA4B;IAehD,OAAO,CAAC,cAAc;IAkBhB,gBAAgB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAqBvC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAwCrD,qBAAqB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAmBnD,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;YAkC/B,cAAc;YAwCd,aAAa;IAqB3B,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,iBAAiB;IAyBzB,OAAO,CAAC,uBAAuB;CAoBhC;AAED;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,gBAAgB;IAC/D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwB;gBAGpD,cAAc,EAAE,gBAAgB,EAChC,YAAY,EAAE,gBAAgB,EAC9B,YAAY,EAAE,4BAA4B;IAMtC,gBAAgB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAmCvC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAkCrD,qBAAqB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAYnD,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAI9C"}