@devilsdev/rag-pipeline-utils 2.1.12 โ†’ 2.2.1

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 (113) hide show
  1. package/.ragrc.schema.json +218 -0
  2. package/README.md +178 -550
  3. package/bin/cli.js +8 -14
  4. package/contracts/reranker-contract.json +69 -0
  5. package/dist/index.d.ts +237 -0
  6. package/dist/index.mjs +22 -7
  7. package/package.json +18 -13
  8. package/src/ai/adaptive-retrieval.js +191 -0
  9. package/src/ai/federated-learning.js +214 -0
  10. package/src/ai/federation/federated-learning-coordinator.js +345 -0
  11. package/src/ai/federation.js +76 -0
  12. package/src/ai/index-fixed.js +509 -0
  13. package/src/ai/index.js +33 -0
  14. package/src/ai/model-trainer.js +217 -0
  15. package/src/ai/model-training.js +205 -0
  16. package/src/ai/module-template.js +37 -0
  17. package/src/ai/multimodal/multi-modal-processor.js +345 -0
  18. package/src/ai/multimodal-processing.js +268 -0
  19. package/src/ai/multimodal.js +71 -0
  20. package/src/ai/orchestrator.js +70 -0
  21. package/src/ai/retrieval/adaptive-retrieval-engine.js +398 -0
  22. package/src/ai/retrieval-engine.js +69 -0
  23. package/src/ai/training/model-training-orchestrator.js +228 -0
  24. package/src/ci/workflow-analyzer.js +71 -0
  25. package/src/cli/commands/ai-ml.js +967 -0
  26. package/src/cli/commands/docs.js +228 -0
  27. package/src/cli/commands/dx.js +538 -0
  28. package/src/cli/commands/plugin-hub.js +875 -0
  29. package/src/cli/doctor-command.js +639 -0
  30. package/src/cli/enhanced-cli-commands.js +945 -0
  31. package/src/cli/interactive-wizard.js +997 -0
  32. package/src/cli/plugin-marketplace-commands.js +869 -0
  33. package/src/cli.js +17 -0
  34. package/src/config/enhanced-ragrc-schema.js +632 -0
  35. package/src/config/load-config.js +54 -0
  36. package/src/config/load-plugin-config.js +69 -0
  37. package/src/config/normalize-config.js +105 -0
  38. package/src/config/schema-validator.js +315 -0
  39. package/src/config/validate-plugin-schema.js +35 -0
  40. package/src/config/validate-schema.js +113 -0
  41. package/src/contracts/plugin-contracts.js +33 -0
  42. package/src/core/create-pipeline.js +99 -0
  43. package/src/core/dependency-injection.js +242 -0
  44. package/src/core/observability/event-logger.js +241 -0
  45. package/src/core/observability/instrumented-pipeline.js +609 -0
  46. package/src/core/observability/metrics.js +497 -0
  47. package/src/core/observability/tracing.js +781 -0
  48. package/src/core/performance/benchmark.js +516 -0
  49. package/src/core/performance/parallel-processor.js +240 -0
  50. package/src/core/performance/streaming-safeguards.js +620 -0
  51. package/src/core/pipeline-factory.js +60 -0
  52. package/src/core/plugin-contracts.js +89 -0
  53. package/src/core/plugin-marketplace/plugin-metadata.js +485 -0
  54. package/src/core/plugin-marketplace/plugin-publisher.js +574 -0
  55. package/src/core/plugin-marketplace/plugin-registry-format.js +419 -0
  56. package/src/core/plugin-marketplace/version-resolver.js +61 -0
  57. package/src/core/plugin-registry.js +294 -0
  58. package/src/dag/dag-engine.js +954 -0
  59. package/src/dag/dag-node.js +76 -0
  60. package/src/dag/enhanced-dag-engine.js +822 -0
  61. package/src/dx/index.js +40 -0
  62. package/src/dx/integration-templates.js +665 -0
  63. package/src/dx/performance-profiler.js +968 -0
  64. package/src/dx/realtime-debugger.js +755 -0
  65. package/src/dx/visual-pipeline-builder.js +578 -0
  66. package/src/ecosystem/plugin-analytics-dashboard.js +778 -0
  67. package/src/ecosystem/plugin-certification.js +580 -0
  68. package/src/ecosystem/plugin-hub.js +821 -0
  69. package/src/enterprise/audit-logging.js +967 -0
  70. package/src/enterprise/data-governance.js +408 -0
  71. package/src/enterprise/multi-tenancy.js +496 -0
  72. package/src/enterprise/sso-integration.js +1030 -0
  73. package/src/evaluate/evaluator.js +52 -0
  74. package/src/evaluate/scoring.js +91 -0
  75. package/src/index.js +67 -0
  76. package/src/ingest.js +59 -0
  77. package/src/loader/csv-loader.js +38 -0
  78. package/src/loader/directory-loader.js +48 -0
  79. package/src/loader/html-loader.js +62 -0
  80. package/src/loader/markdown-loader.js +67 -0
  81. package/src/mocks/openai-embedder.js +119 -0
  82. package/src/mocks/openai-llm.js +77 -0
  83. package/src/mocks/pdf-loader.js +21 -0
  84. package/src/mocks/pinecone-retriever.js +106 -0
  85. package/src/observability/audit-logger.js +758 -0
  86. package/src/observability/dashboard-config.json +675 -0
  87. package/src/observability/event-logger.js +310 -0
  88. package/src/observability/metrics.js +691 -0
  89. package/src/observability/security-monitor.js +830 -0
  90. package/src/observability/slo-monitor.js +319 -0
  91. package/src/observability/telemetry.js +686 -0
  92. package/src/pipeline/pipeline.js +18 -0
  93. package/src/plugins/sample-embedder.js +53 -0
  94. package/src/plugins/sample-llm.js +30 -0
  95. package/src/plugins/sample-loader.js +24 -0
  96. package/src/plugins/sample-retriever.js +84 -0
  97. package/src/query.js +117 -0
  98. package/src/reranker/llm-reranker.js +111 -0
  99. package/src/scripts/script-utilities.js +36 -0
  100. package/src/security/plugin-sandbox.js +586 -0
  101. package/src/security/plugin-signature-verifier.js +414 -0
  102. package/src/security/validator.js +36 -0
  103. package/src/utils/ci/diagnostic-reporter.js +57 -0
  104. package/src/utils/logger.js +211 -0
  105. package/src/utils/performance-monitor.js +561 -0
  106. package/src/utils/plugin-scaffolder.js +447 -0
  107. package/src/utils/rate-limiter.js +244 -0
  108. package/src/utils/retry-policy.js +443 -0
  109. package/src/utils/retry.js +107 -0
  110. package/src/utils/safe-expression-evaluator.js +579 -0
  111. package/src/utils/secure-logging.js +338 -0
  112. package/src/utils/structured-logger.js +388 -0
  113. package/src/utils/validate-plugin-contract.js +42 -0
@@ -0,0 +1,574 @@
1
+ /**
2
+ * Plugin Publishing System
3
+ * Handles plugin packaging, validation, and publishing to registries
4
+ */
5
+
6
+ const fs = require('fs/promises');
7
+ // eslint-disable-line global-require
8
+ const path = require('path');
9
+ // eslint-disable-line global-require
10
+ const crypto = require('crypto');
11
+ // eslint-disable-line global-require
12
+ const { logger } = require('../../utils/structured-logger.js');
13
+ const {
14
+ metadataExtractor,
15
+ metadataValidator,
16
+ } = require('./plugin-metadata.js');
17
+ // eslint-disable-line global-require
18
+ const {
19
+ validatePluginRegistry,
20
+ createEmptyRegistry,
21
+ } = require('./plugin-registry-format.js');
22
+ // eslint-disable-line global-require
23
+ const { VersionUtils } = require('./version-resolver.js');
24
+ // eslint-disable-line global-require
25
+
26
+ /**
27
+ * Plugin publisher for marketplace publishing
28
+ */
29
+ class PluginPublisher {
30
+ constructor(_options = {}) {
31
+ this._options = {
32
+ registryUrl: _options.registryUrl || 'https://registry.rag-pipeline.dev',
33
+ authToken: _options.authToken,
34
+ timeout: _options.timeout || 30000,
35
+ dryRun: _options.dryRun || false,
36
+ ..._options,
37
+ };
38
+ }
39
+
40
+ /**
41
+ * Publish plugin to registry
42
+ * @param {string} pluginPath - Path to plugin directory
43
+ * @param {object} publishOptions - Publishing _options
44
+ * @returns {Promise<object>} Publishing result
45
+ */
46
+ async publishPlugin(pluginPath, publishOptions = {}) {
47
+ const startTime = Date.now();
48
+
49
+ try {
50
+ // Step 1: Validate plugin structure
51
+ logger.info('Validating plugin structure', { pluginPath });
52
+ const validation = await this.validatePluginStructure(pluginPath);
53
+ if (!validation.valid) {
54
+ throw new Error(
55
+ `Plugin validation failed: ${validation.errors.join(', ')}`,
56
+ );
57
+ }
58
+
59
+ // Step 2: Extract and validate metadata
60
+ logger.info('Extracting plugin metadata', { pluginPath });
61
+ const metadata = await this.extractPluginMetadata(pluginPath);
62
+
63
+ // Step 3: Package plugin
64
+ logger.info('Packaging plugin', {
65
+ pluginName: metadata.name,
66
+ version: metadata.version,
67
+ });
68
+ const packageInfo = await this.packagePlugin(
69
+ pluginPath,
70
+ metadata,
71
+ publishOptions,
72
+ );
73
+
74
+ // Step 4: Upload to registry (unless dry run)
75
+ if (this._options.dryRun) {
76
+ logger.info('Dry run - skipping actual upload');
77
+ return {
78
+ success: true,
79
+ dryRun: true,
80
+ metadata,
81
+ packageInfo,
82
+ duration: Date.now() - startTime,
83
+ };
84
+ }
85
+
86
+ logger.info('Publishing to registry', {
87
+ pluginName: metadata.name,
88
+ version: metadata.version,
89
+ });
90
+ const publishResult = await this.uploadToRegistry(
91
+ packageInfo,
92
+ metadata,
93
+ publishOptions,
94
+ );
95
+
96
+ logger.info('Plugin published successfully', {
97
+ pluginName: metadata.name,
98
+ version: metadata.version,
99
+ });
100
+
101
+ return {
102
+ success: true,
103
+ metadata,
104
+ packageInfo,
105
+ publishResult,
106
+ duration: Date.now() - startTime,
107
+ };
108
+ } catch (error) {
109
+ logger.error('Publishing failed', { error: error.message, pluginPath });
110
+ return {
111
+ success: false,
112
+ error: error.message,
113
+ duration: Date.now() - startTime,
114
+ };
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Validate plugin directory structure
120
+ * @param {string} pluginPath - Plugin directory path
121
+ * @returns {Promise<{valid: boolean, errors: Array<string>}>}
122
+ */
123
+ async validatePluginStructure(pluginPath) {
124
+ const errors = [];
125
+
126
+ try {
127
+ const stats = await fs.stat(pluginPath);
128
+ if (!stats.isDirectory()) {
129
+ errors.push('Plugin path must be a directory');
130
+ return { valid: false, errors };
131
+ }
132
+ } catch (error) {
133
+ errors.push(`Plugin directory not found: ${pluginPath}`);
134
+ return { valid: false, errors };
135
+ }
136
+
137
+ // Check for required files
138
+ const requiredFiles = ['index.js', 'package.json'];
139
+ for (const file of requiredFiles) {
140
+ const _filePath = path.join(pluginPath, file);
141
+ try {
142
+ await fs.access(_filePath);
143
+ } catch (error) {
144
+ errors.push(`Required file missing: ${file}`);
145
+ }
146
+ }
147
+
148
+ // Check for recommended files
149
+ const recommendedFiles = ['README.md', 'LICENSE'];
150
+ for (const file of recommendedFiles) {
151
+ const _filePath = path.join(pluginPath, file);
152
+ try {
153
+ await fs.access(_filePath);
154
+ } catch (error) {
155
+ logger.warn('Recommended file missing', { file });
156
+ }
157
+ }
158
+
159
+ // Validate package.json structure
160
+ try {
161
+ const packageJsonPath = path.join(pluginPath, 'package.json');
162
+ const packageJson = JSON.parse(
163
+ await fs.readFile(packageJsonPath, 'utf-8'),
164
+ );
165
+
166
+ if (!packageJson.name) {
167
+ errors.push('package.json missing name field');
168
+ }
169
+
170
+ if (!packageJson.version) {
171
+ errors.push('package.json missing version field');
172
+ }
173
+
174
+ if (!packageJson.main && !packageJson.exports) {
175
+ errors.push('package.json missing main or exports field');
176
+ }
177
+ } catch (error) {
178
+ errors.push(`Invalid package.json: ${error.message}`);
179
+ }
180
+
181
+ return { valid: errors.length === 0, errors };
182
+ }
183
+
184
+ /**
185
+ * Extract plugin metadata from directory
186
+ * @param {string} pluginPath - Plugin directory path
187
+ * @returns {Promise<object>} Plugin metadata
188
+ */
189
+ async extractPluginMetadata(pluginPath) {
190
+ // Load plugin module
191
+ const pluginIndexPath = path.join(pluginPath, 'index.js');
192
+ const pluginModule = await import(pluginIndexPath);
193
+
194
+ // Load package.json for additional metadata
195
+ const packageJsonPath = path.join(pluginPath, 'package.json');
196
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
197
+
198
+ // Determine plugin type from package.json or metadata
199
+ let pluginType = null;
200
+ if (packageJson.keywords) {
201
+ const typeKeywords = [
202
+ 'loader',
203
+ 'embedder',
204
+ 'retriever',
205
+ 'llm',
206
+ 'reranker',
207
+ ];
208
+ pluginType = packageJson.keywords.find((k) => typeKeywords.includes(k));
209
+ }
210
+
211
+ if (!pluginType) {
212
+ throw new Error(
213
+ 'Cannot determine plugin _type. Add plugin _type to package.json keywords or metadata.',
214
+ );
215
+ }
216
+
217
+ // Extract metadata using the extractor
218
+ const extractedMetadata = metadataExtractor.extractMetadata(
219
+ pluginModule,
220
+ pluginType,
221
+ );
222
+
223
+ // Merge with package.json data
224
+ const mergedMetadata = {
225
+ ...extractedMetadata,
226
+ name: packageJson.name || extractedMetadata.name,
227
+ version: packageJson.version || extractedMetadata.version,
228
+ description: packageJson.description || extractedMetadata.description,
229
+ author: packageJson.author || extractedMetadata.author,
230
+ homepage: packageJson.homepage || extractedMetadata.homepage,
231
+ repository: packageJson.repository || extractedMetadata.repository,
232
+ license: packageJson.license || extractedMetadata.license,
233
+ keywords: [
234
+ ...(packageJson.keywords || []),
235
+ ...(extractedMetadata.keywords || []),
236
+ ],
237
+ dependencies:
238
+ packageJson.dependencies || extractedMetadata.dependencies || {},
239
+ peerDependencies:
240
+ packageJson.peerDependencies ||
241
+ extractedMetadata.peerDependencies ||
242
+ {},
243
+ };
244
+
245
+ // Validate merged metadata
246
+ const validation = metadataValidator.validatePlugin(
247
+ pluginType,
248
+ mergedMetadata.name,
249
+ pluginModule,
250
+ );
251
+ if (!validation.valid) {
252
+ throw new Error(`Metadata validation failed: ${validation.error}`);
253
+ }
254
+
255
+ // Show warnings
256
+ if (validation.warnings.length > 0) {
257
+ logger.warn('Metadata validation warnings', {
258
+ warnings: validation.warnings,
259
+ });
260
+ }
261
+
262
+ return mergedMetadata;
263
+ }
264
+
265
+ /**
266
+ * Package plugin for distribution
267
+ * @param {string} pluginPath - Plugin directory path
268
+ * @param {object} metadata - Plugin metadata
269
+ * @param {object} _options - Packaging _options
270
+ * @returns {Promise<object>} Package information
271
+ */
272
+ async packagePlugin(pluginPath, metadata, _options) {
273
+ const packageName = `${metadata.name}-${metadata.version}.tgz`;
274
+ const packagePath = path.join(
275
+ _options.outputDir || pluginPath,
276
+ packageName,
277
+ );
278
+
279
+ // Create package archive (simplified - in real implementation would use tar)
280
+ const packageFiles = await this.collectPackageFiles(pluginPath, _options);
281
+
282
+ // Calculate package size and integrity hash
283
+ const packageSize = await this.calculatePackageSize(packageFiles);
284
+ const integrity = await this.calculateIntegrity(packageFiles);
285
+
286
+ return {
287
+ name: packageName,
288
+ path: packagePath,
289
+ size: packageSize,
290
+ integrity,
291
+ files: packageFiles.map((f) => f.relativePath),
292
+ };
293
+ }
294
+
295
+ /**
296
+ * Collect files to include in package
297
+ * @param {string} pluginPath - Plugin directory path
298
+ * @param {object} _options - Collection _options
299
+ * @returns {Promise<Array<object>>} Package files
300
+ */
301
+ async collectPackageFiles(pluginPath, _options) {
302
+ const files = [];
303
+ const excludePatterns = _options.exclude || [
304
+ 'node_modules',
305
+ '.git',
306
+ '.DS_Store',
307
+ '*.log',
308
+ 'coverage',
309
+ '.nyc_output',
310
+ 'test',
311
+ 'tests',
312
+ '__tests__',
313
+ '*.test.js',
314
+ '*.spec.js',
315
+ ];
316
+
317
+ const collectDir = async (dir, relativePath = '') => {
318
+ const entries = await fs.readdir(dir, { withFileTypes: true });
319
+
320
+ for (const entry of entries) {
321
+ const fullPath = path.join(dir, entry.name);
322
+ const relPath = path.join(relativePath, entry.name);
323
+
324
+ // Check exclude patterns
325
+ if (
326
+ excludePatterns.some((pattern) => {
327
+ if (pattern.includes('*')) {
328
+ return relPath.match(new RegExp(pattern.replace('*', '.*')));
329
+ }
330
+ return relPath.includes(pattern);
331
+ })
332
+ ) {
333
+ continue;
334
+ }
335
+
336
+ if (entry.isDirectory()) {
337
+ await collectDir(fullPath, relPath);
338
+ } else {
339
+ const stats = await fs.stat(fullPath);
340
+ files.push({
341
+ fullPath,
342
+ relativePath: relPath,
343
+ size: stats.size,
344
+ });
345
+ }
346
+ }
347
+ };
348
+
349
+ await collectDir(pluginPath);
350
+ return files;
351
+ }
352
+
353
+ /**
354
+ * Calculate total package size
355
+ * @param {Array<object>} files - Package files
356
+ * @returns {number} Total size in bytes
357
+ */
358
+ async calculatePackageSize(files) {
359
+ return files.reduce((total, file) => total + file.size, 0);
360
+ }
361
+
362
+ /**
363
+ * Calculate package integrity hash
364
+ * @param {Array<object>} files - Package files
365
+ * @returns {Promise<string>} SHA-256 hash
366
+ */
367
+ async calculateIntegrity(files) {
368
+ const hash = crypto.createHash('sha256');
369
+
370
+ // Sort files by path for consistent hashing
371
+ const sortedFiles = files.sort((a, b) =>
372
+ a.relativePath.localeCompare(b.relativePath),
373
+ );
374
+
375
+ for (const file of sortedFiles) {
376
+ const content = await fs.readFile(file.fullPath);
377
+ hash.update(file.relativePath);
378
+ hash.update(content);
379
+ }
380
+
381
+ return `sha256-${hash.digest('base64')}`;
382
+ }
383
+
384
+ /**
385
+ * Upload package to registry
386
+ * @param {object} packageInfo - Package information
387
+ * @param {object} metadata - Plugin metadata
388
+ * @param {object} _options - Upload _options
389
+ * @returns {Promise<object>} Upload result
390
+ */
391
+ async uploadToRegistry(packageInfo, metadata, _options) {
392
+ // In a real implementation, this would make HTTP requests to the registry API
393
+ // For now, we'll simulate the upload process
394
+
395
+ const uploadUrl = `${this._options.registryUrl}/api/plugins/${metadata.name}/versions/${metadata.version}`;
396
+
397
+ // Simulate upload delay
398
+ await new Promise((resolve) => setTimeout(resolve, 1000));
399
+
400
+ return {
401
+ uploadUrl,
402
+ downloadUrl: `${this._options.registryUrl}/packages/${metadata.name}/${packageInfo.name}`,
403
+ publishedAt: new Date().toISOString(),
404
+ integrity: packageInfo.integrity,
405
+ size: packageInfo.size,
406
+ };
407
+ }
408
+
409
+ /**
410
+ * Update local registry with published plugin
411
+ * @param {string} registryPath - Local registry file path
412
+ * @param {object} metadata - Plugin metadata
413
+ * @param {object} publishResult - Publishing result
414
+ * @returns {Promise<void>}
415
+ */
416
+ async updateLocalRegistry(registryPath, metadata, publishResult) {
417
+ let registry;
418
+
419
+ try {
420
+ const registryContent = await fs.readFile(registryPath, 'utf-8');
421
+ registry = JSON.parse(registryContent);
422
+ } catch (error) {
423
+ // Create new registry if file doesn't exist
424
+ registry = createEmptyRegistry();
425
+ }
426
+
427
+ // Add or update plugin entry
428
+ if (!registry.plugins[metadata.name]) {
429
+ registry.plugins[metadata.name] = {
430
+ metadata,
431
+ versions: {},
432
+ latest: metadata.version,
433
+ createdAt: new Date().toISOString(),
434
+ updatedAt: new Date().toISOString(),
435
+ };
436
+ }
437
+
438
+ const pluginEntry = registry.plugins[metadata.name];
439
+
440
+ // Add new version
441
+ pluginEntry.versions[metadata.version] = {
442
+ version: metadata.version,
443
+ publishedAt: publishResult.publishedAt,
444
+ downloadUrl: publishResult.downloadUrl,
445
+ integrity: publishResult.integrity,
446
+ size: publishResult.size,
447
+ };
448
+
449
+ // Update latest version if this is newer
450
+ if (
451
+ !pluginEntry.latest ||
452
+ VersionUtils.compareVersions(metadata.version, pluginEntry.latest) > 0
453
+ ) {
454
+ pluginEntry.latest = metadata.version;
455
+ }
456
+
457
+ // Update timestamps
458
+ pluginEntry.updatedAt = new Date().toISOString();
459
+ registry.updatedAt = new Date().toISOString();
460
+
461
+ // Validate registry before saving
462
+ const validation = validatePluginRegistry(registry);
463
+ if (!validation.valid) {
464
+ throw new Error(
465
+ `Registry validation failed: ${validation.errors.map((e) => e.message).join(', ')}`,
466
+ );
467
+ }
468
+
469
+ // Save updated registry
470
+ await fs.writeFile(registryPath, JSON.stringify(registry, null, 2));
471
+ }
472
+ }
473
+
474
+ /**
475
+ * Plugin publishing utilities
476
+ */
477
+ const PublishingUtils = {
478
+ /**
479
+ * Generate GitHub Action workflow for automated publishing
480
+ * @param {object} _options - Workflow _options
481
+ * @returns {string} GitHub Action YAML
482
+ */
483
+ generateGitHubAction(_options = {}) {
484
+ return `name: Publish Plugin
485
+
486
+ on:
487
+ release:
488
+ types: [published]
489
+ workflow_dispatch:
490
+ inputs:
491
+ version:
492
+ description: 'Version to publish'
493
+ required: true
494
+ default: 'latest'
495
+
496
+ jobs:
497
+ publish:
498
+ runs-on: ubuntu-latest
499
+
500
+ steps:
501
+ - name: Checkout code
502
+ uses: actions/checkout@v3
503
+
504
+ - name: Setup Node.js
505
+ uses: actions/setup-node@v3
506
+ with:
507
+ node-version: '18'
508
+
509
+ - name: Install dependencies
510
+ run: npm ci
511
+
512
+ - name: Run tests
513
+ run: npm test
514
+
515
+ - name: Publish plugin
516
+ run: |
517
+ npx rag-pipeline publish \\
518
+ --registry-url \${{ secrets.REGISTRY_URL || 'https://registry.rag-pipeline.dev' }} \\
519
+ --auth-token \${{ secrets.REGISTRY_TOKEN }} \\
520
+ --version \${{ github.event.inputs.version || github.event.release.tag_name }}
521
+ env:
522
+ NODE_ENV: production
523
+ `;
524
+ },
525
+
526
+ /**
527
+ * Generate plugin publishing checklist
528
+ * @param {object} metadata - Plugin metadata
529
+ * @returns {Array<string>} Checklist items
530
+ */
531
+ generatePublishingChecklist(_metadata) {
532
+ return [
533
+ '๐Ÿ“‹ Plugin metadata is complete and valid',
534
+ '๐Ÿงช All tests are passing',
535
+ '๐Ÿ“š Documentation is up to date',
536
+ '๐Ÿ”– Version number follows semantic versioning',
537
+ '๐Ÿ“„ LICENSE file is present',
538
+ '๐Ÿ“– README.md includes usage examples',
539
+ '๐Ÿท๏ธ Keywords are relevant and descriptive',
540
+ '๐Ÿ”— Repository URL is accessible',
541
+ '๐Ÿ  Homepage URL is valid (if provided)',
542
+ '๐Ÿ“ฆ Package size is reasonable (< 10MB recommended)',
543
+ '๐Ÿ”’ No sensitive information in code',
544
+ 'โœ… Plugin works with latest rag-pipeline-utils version',
545
+ ];
546
+ },
547
+
548
+ /**
549
+ * Validate plugin before publishing
550
+ * @param {string} pluginPath - Plugin directory path
551
+ * @returns {Promise<{ready: boolean, issues: Array<string>}>}
552
+ */
553
+ async validateForPublishing(pluginPath) {
554
+ const publisher = new PluginPublisher({ dryRun: true });
555
+ const result = await publisher.publishPlugin(pluginPath);
556
+
557
+ if (result.success) {
558
+ return { ready: true, issues: [] };
559
+ } else {
560
+ return { ready: false, issues: [result.error] };
561
+ }
562
+ },
563
+ };
564
+
565
+ // Export default publisher instance
566
+ const pluginPublisher = new PluginPublisher();
567
+
568
+ // Default export
569
+
570
+ module.exports = {
571
+ PluginPublisher,
572
+ PublishingUtils,
573
+ pluginPublisher,
574
+ };