convoke-agents 2.3.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/INSTALLATION.md +109 -86
- package/README.md +236 -104
- package/UPDATE-GUIDE.md +63 -23
- package/_bmad/bme/_enhance/config.yaml +8 -0
- package/_bmad/bme/_enhance/extensions/bmm-pm.yaml +9 -0
- package/_bmad/bme/_enhance/guides/.gitkeep +0 -0
- package/_bmad/bme/_enhance/guides/ENHANCE-GUIDE.md +252 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/SKILL.md +6 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-c/.gitkeep +0 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-c/step-c-01-init.md +106 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-c/step-c-02-gather.md +136 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-c/step-c-03-score.md +146 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-c/step-c-04-prioritize.md +181 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-r/.gitkeep +0 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-r/step-r-01-load.md +120 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-r/step-r-02-rescore.md +141 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-r/step-r-03-update.md +154 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-t/.gitkeep +0 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-t/step-t-01-ingest.md +86 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-t/step-t-02-extract.md +169 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-t/step-t-03-score.md +147 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/steps-t/step-t-04-update.md +155 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/templates/backlog-format-spec.md +219 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/templates/rice-scoring-guide.md +154 -0
- package/_bmad/bme/_enhance/workflows/initiatives-backlog/workflow.md +88 -0
- package/_bmad/bme/_gyre/README.md +100 -0
- package/_bmad/bme/_gyre/agents/.gitkeep +0 -0
- package/_bmad/bme/_gyre/agents/model-curator.md +128 -0
- package/_bmad/bme/_gyre/agents/readiness-analyst.md +127 -0
- package/_bmad/bme/_gyre/agents/review-coach.md +130 -0
- package/_bmad/bme/_gyre/agents/stack-detective.md +125 -0
- package/_bmad/bme/_gyre/compass-routing-reference.md +168 -0
- package/_bmad/bme/_gyre/config.yaml +22 -0
- package/_bmad/bme/_gyre/contracts/.gitkeep +0 -0
- package/_bmad/bme/_gyre/contracts/gc1-stack-profile.md +152 -0
- package/_bmad/bme/_gyre/contracts/gc2-capabilities-manifest.md +189 -0
- package/_bmad/bme/_gyre/contracts/gc3-findings-report.md +197 -0
- package/_bmad/bme/_gyre/contracts/gc4-feedback-loop.md +209 -0
- package/_bmad/bme/_gyre/guides/ATLAS-USER-GUIDE.md +177 -0
- package/_bmad/bme/_gyre/guides/COACH-USER-GUIDE.md +172 -0
- package/_bmad/bme/_gyre/guides/LENS-USER-GUIDE.md +181 -0
- package/_bmad/bme/_gyre/guides/SCOUT-USER-GUIDE.md +158 -0
- package/_bmad/bme/_gyre/workflows/.gitkeep +0 -0
- package/_bmad/bme/_gyre/workflows/accuracy-validation/steps/step-01-select-repos.md +55 -0
- package/_bmad/bme/_gyre/workflows/accuracy-validation/steps/step-02-run-validation.md +78 -0
- package/_bmad/bme/_gyre/workflows/accuracy-validation/steps/step-03-score-results.md +143 -0
- package/_bmad/bme/_gyre/workflows/accuracy-validation/workflow.md +41 -0
- package/_bmad/bme/_gyre/workflows/delta-report/steps/step-01-load-history.md +63 -0
- package/_bmad/bme/_gyre/workflows/delta-report/steps/step-02-compute-delta.md +72 -0
- package/_bmad/bme/_gyre/workflows/delta-report/steps/step-03-present-delta.md +143 -0
- package/_bmad/bme/_gyre/workflows/delta-report/workflow.md +34 -0
- package/_bmad/bme/_gyre/workflows/full-analysis/steps/step-01-initialize.md +68 -0
- package/_bmad/bme/_gyre/workflows/full-analysis/steps/step-02-detect-stack.md +49 -0
- package/_bmad/bme/_gyre/workflows/full-analysis/steps/step-03-generate-model.md +52 -0
- package/_bmad/bme/_gyre/workflows/full-analysis/steps/step-04-analyze-gaps.md +42 -0
- package/_bmad/bme/_gyre/workflows/full-analysis/steps/step-05-review-findings.md +128 -0
- package/_bmad/bme/_gyre/workflows/full-analysis/workflow.md +39 -0
- package/_bmad/bme/_gyre/workflows/gap-analysis/steps/step-01-load-manifest.md +70 -0
- package/_bmad/bme/_gyre/workflows/gap-analysis/steps/step-02-observability-analysis.md +110 -0
- package/_bmad/bme/_gyre/workflows/gap-analysis/steps/step-03-deployment-analysis.md +87 -0
- package/_bmad/bme/_gyre/workflows/gap-analysis/steps/step-04-cross-domain-correlation.md +105 -0
- package/_bmad/bme/_gyre/workflows/gap-analysis/steps/step-05-present-findings.md +172 -0
- package/_bmad/bme/_gyre/workflows/gap-analysis/workflow.md +38 -0
- package/_bmad/bme/_gyre/workflows/model-generation/steps/step-01-load-profile.md +74 -0
- package/_bmad/bme/_gyre/workflows/model-generation/steps/step-02-generate-capabilities.md +116 -0
- package/_bmad/bme/_gyre/workflows/model-generation/steps/step-03-web-enrichment.md +89 -0
- package/_bmad/bme/_gyre/workflows/model-generation/steps/step-04-write-manifest.md +122 -0
- package/_bmad/bme/_gyre/workflows/model-generation/workflow.md +40 -0
- package/_bmad/bme/_gyre/workflows/model-review/steps/step-01-load-context.md +86 -0
- package/_bmad/bme/_gyre/workflows/model-review/steps/step-02-walkthrough.md +116 -0
- package/_bmad/bme/_gyre/workflows/model-review/steps/step-03-apply-amendments.md +92 -0
- package/_bmad/bme/_gyre/workflows/model-review/steps/step-04-capture-feedback.md +107 -0
- package/_bmad/bme/_gyre/workflows/model-review/steps/step-05-summary.md +60 -0
- package/_bmad/bme/_gyre/workflows/model-review/workflow.md +41 -0
- package/_bmad/bme/_gyre/workflows/stack-detection/steps/step-01-scan-filesystem.md +176 -0
- package/_bmad/bme/_gyre/workflows/stack-detection/steps/step-02-classify-stack.md +111 -0
- package/_bmad/bme/_gyre/workflows/stack-detection/steps/step-03-guard-questions.md +117 -0
- package/_bmad/bme/_gyre/workflows/stack-detection/workflow.md +42 -0
- package/_bmad/bme/_vortex/config.yaml +1 -1
- package/package.json +7 -2
- package/scripts/archive.js +304 -0
- package/scripts/convoke-doctor.js +146 -132
- package/scripts/docs-audit.js +21 -5
- package/scripts/install-gyre-agents.js +140 -0
- package/scripts/install-vortex-agents.js +0 -0
- package/scripts/update/lib/agent-registry.js +70 -0
- package/scripts/update/lib/refresh-installation.js +290 -29
- package/scripts/update/lib/validator.js +281 -1
|
@@ -44,6 +44,9 @@ async function validateInstallation(preMigrationData = {}, projectRoot) {
|
|
|
44
44
|
// 7. Workflow step structure validation (P17 count + P20 filenames)
|
|
45
45
|
checks.push(await validateWorkflowStepStructure(projectRoot));
|
|
46
46
|
|
|
47
|
+
// 8. Enhance module validation (optional — passes if not installed)
|
|
48
|
+
checks.push(await validateEnhanceModule(projectRoot));
|
|
49
|
+
|
|
47
50
|
const allPassed = checks.every(c => c.passed);
|
|
48
51
|
|
|
49
52
|
return {
|
|
@@ -348,6 +351,278 @@ async function validateWorkflowStepStructure(projectRoot) {
|
|
|
348
351
|
return check;
|
|
349
352
|
}
|
|
350
353
|
|
|
354
|
+
/**
|
|
355
|
+
* Validate Enhance module installation (optional — passes if not installed)
|
|
356
|
+
* Performs 5-point verification: directory, entry point, menu patch, config, filesystem consistency
|
|
357
|
+
* @param {string} projectRoot - Absolute path to project root
|
|
358
|
+
* @returns {Promise<object>} Validation check result
|
|
359
|
+
*/
|
|
360
|
+
async function validateEnhanceModule(projectRoot) {
|
|
361
|
+
const check = {
|
|
362
|
+
name: 'Enhance module',
|
|
363
|
+
passed: false,
|
|
364
|
+
error: null
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
try {
|
|
368
|
+
const enhanceDir = path.join(projectRoot, '_bmad/bme/_enhance');
|
|
369
|
+
|
|
370
|
+
// Check 1: Directory exists — if not, Enhance is simply not installed (optional)
|
|
371
|
+
if (!fs.existsSync(enhanceDir)) {
|
|
372
|
+
check.passed = true;
|
|
373
|
+
check.info = 'Enhance module not installed (optional)';
|
|
374
|
+
return check;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const failures = [];
|
|
378
|
+
|
|
379
|
+
// Check 4 (first — needed by checks 2, 3, 5): Config valid
|
|
380
|
+
const configPath = path.join(enhanceDir, 'config.yaml');
|
|
381
|
+
let config = null;
|
|
382
|
+
|
|
383
|
+
if (!fs.existsSync(configPath)) {
|
|
384
|
+
failures.push('config.yaml not found');
|
|
385
|
+
} else {
|
|
386
|
+
try {
|
|
387
|
+
config = yaml.load(fs.readFileSync(configPath, 'utf8'));
|
|
388
|
+
} catch (err) {
|
|
389
|
+
failures.push(`config.yaml parse error: ${err.message}`);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (config) {
|
|
393
|
+
const missing = [];
|
|
394
|
+
if (!config.name) missing.push('name');
|
|
395
|
+
if (!config.version) missing.push('version');
|
|
396
|
+
if (!config.description) missing.push('description');
|
|
397
|
+
if (!Array.isArray(config.workflows) || config.workflows.length === 0) {
|
|
398
|
+
missing.push('workflows (must be non-empty array)');
|
|
399
|
+
} else {
|
|
400
|
+
config.workflows.forEach((wf, i) => {
|
|
401
|
+
const wfMissing = [];
|
|
402
|
+
if (!wf.name) wfMissing.push('name');
|
|
403
|
+
if (!wf.entry) wfMissing.push('entry');
|
|
404
|
+
if (!wf.target_agent) wfMissing.push('target_agent');
|
|
405
|
+
if (!wf.menu_patch_name) wfMissing.push('menu_patch_name');
|
|
406
|
+
if (wfMissing.length > 0) {
|
|
407
|
+
missing.push(`workflows[${i}] missing: ${wfMissing.join(', ')}`);
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
if (missing.length > 0) {
|
|
412
|
+
failures.push(`config missing fields: ${missing.join('; ')}`);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Checks 2, 3, 5 require a valid config with workflows
|
|
418
|
+
if (config && Array.isArray(config.workflows)) {
|
|
419
|
+
for (const wf of config.workflows) {
|
|
420
|
+
// Check 2: Workflow entry point resolves
|
|
421
|
+
if (wf.entry) {
|
|
422
|
+
const entryPath = path.join(enhanceDir, wf.entry);
|
|
423
|
+
if (!fs.existsSync(entryPath)) {
|
|
424
|
+
failures.push(`workflow entry point not found: ${wf.entry}`);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Check 3: Menu patch present in target agent
|
|
429
|
+
if (wf.target_agent) {
|
|
430
|
+
const agentPath = path.join(projectRoot, '_bmad', wf.target_agent);
|
|
431
|
+
if (fs.existsSync(agentPath)) {
|
|
432
|
+
const agentContent = fs.readFileSync(agentPath, 'utf8');
|
|
433
|
+
const patchName = wf.menu_patch_name || wf.name;
|
|
434
|
+
if (!agentContent.includes(patchName)) {
|
|
435
|
+
failures.push(`menu patch "${patchName}" not found in ${wf.target_agent}`);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
// If agent file doesn't exist, that's already caught by agent validation — not an Enhance-specific failure
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Check 5: Config-to-filesystem consistency — workflow directory exists
|
|
442
|
+
if (wf.name) {
|
|
443
|
+
const wfDir = path.join(enhanceDir, 'workflows', wf.name);
|
|
444
|
+
if (!fs.existsSync(wfDir)) {
|
|
445
|
+
failures.push(`workflow directory not found for registered workflow: ${wf.name}`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Check 6: Skill wrapper exists for workflow
|
|
450
|
+
if (wf.name) {
|
|
451
|
+
const skillWrapperPath = path.join(projectRoot, '.claude', 'skills', `bmad-enhance-${wf.name}`, 'SKILL.md');
|
|
452
|
+
if (!fs.existsSync(skillWrapperPath)) {
|
|
453
|
+
failures.push(`skill wrapper not found: .claude/skills/bmad-enhance-${wf.name}/SKILL.md`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if (failures.length > 0) {
|
|
460
|
+
check.error = `Enhance: ${failures.join('; ')}`;
|
|
461
|
+
} else {
|
|
462
|
+
check.passed = true;
|
|
463
|
+
}
|
|
464
|
+
} catch (error) {
|
|
465
|
+
check.error = error.message;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return check;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Validate a SKILL.md file has required frontmatter fields
|
|
473
|
+
* @param {string} skillMdPath - Absolute path to SKILL.md file
|
|
474
|
+
* @returns {Promise<object>} Validation result { valid, errors }
|
|
475
|
+
*/
|
|
476
|
+
async function validateSkillMd(skillMdPath) {
|
|
477
|
+
const errors = [];
|
|
478
|
+
|
|
479
|
+
if (!fs.existsSync(skillMdPath)) {
|
|
480
|
+
errors.push(`SKILL.md not found: ${skillMdPath}`);
|
|
481
|
+
return { valid: false, errors };
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const content = fs.readFileSync(skillMdPath, 'utf8');
|
|
485
|
+
|
|
486
|
+
// Extract YAML frontmatter between --- delimiters
|
|
487
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
488
|
+
if (!fmMatch) {
|
|
489
|
+
errors.push('SKILL.md missing YAML frontmatter (--- delimiters)');
|
|
490
|
+
return { valid: false, errors };
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
let frontmatter;
|
|
494
|
+
try {
|
|
495
|
+
frontmatter = yaml.load(fmMatch[1]);
|
|
496
|
+
} catch (err) {
|
|
497
|
+
errors.push(`SKILL.md frontmatter parse error: ${err.message}`);
|
|
498
|
+
return { valid: false, errors };
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (!frontmatter || typeof frontmatter !== 'object') {
|
|
502
|
+
errors.push('SKILL.md frontmatter is empty or not an object');
|
|
503
|
+
return { valid: false, errors };
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (!frontmatter.name || typeof frontmatter.name !== 'string') {
|
|
507
|
+
errors.push('SKILL.md missing required field: name');
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (!frontmatter.description || typeof frontmatter.description !== 'string') {
|
|
511
|
+
errors.push('SKILL.md missing required field: description');
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
return { valid: errors.length === 0, errors };
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Validate step files in a skill directory follow sequential numbering
|
|
519
|
+
* @param {string} skillDir - Absolute path to skill directory
|
|
520
|
+
* @returns {Promise<object>} Validation result { valid, errors }
|
|
521
|
+
*/
|
|
522
|
+
async function validateStepFiles(skillDir) {
|
|
523
|
+
const errors = [];
|
|
524
|
+
|
|
525
|
+
if (!fs.existsSync(skillDir)) {
|
|
526
|
+
errors.push(`Skill directory not found: ${skillDir}`);
|
|
527
|
+
return { valid: false, errors };
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Collect step files from skill dir and steps/ subdirectory
|
|
531
|
+
const stepFiles = [];
|
|
532
|
+
const entries = fs.readdirSync(skillDir);
|
|
533
|
+
|
|
534
|
+
for (const entry of entries) {
|
|
535
|
+
if (/^step-\d+-/.test(entry) && entry.endsWith('.md')) {
|
|
536
|
+
stepFiles.push(entry);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
const stepsSubdir = path.join(skillDir, 'steps');
|
|
541
|
+
if (fs.existsSync(stepsSubdir)) {
|
|
542
|
+
const subEntries = fs.readdirSync(stepsSubdir);
|
|
543
|
+
for (const entry of subEntries) {
|
|
544
|
+
if (/^step-\d+-/.test(entry) && entry.endsWith('.md')) {
|
|
545
|
+
stepFiles.push(entry);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
if (stepFiles.length === 0) {
|
|
551
|
+
// No step files is valid — some skills are single-file (agent-activation type)
|
|
552
|
+
return { valid: true, errors };
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// Extract step numbers and check for sequential numbering
|
|
556
|
+
const stepNumbers = stepFiles
|
|
557
|
+
.map(f => {
|
|
558
|
+
const match = f.match(/^step-(\d+)-/);
|
|
559
|
+
return match ? parseInt(match[1], 10) : null;
|
|
560
|
+
})
|
|
561
|
+
.filter(n => n !== null)
|
|
562
|
+
.sort((a, b) => a - b);
|
|
563
|
+
|
|
564
|
+
// Remove duplicates (same step number in root and steps/)
|
|
565
|
+
const uniqueSteps = [...new Set(stepNumbers)];
|
|
566
|
+
|
|
567
|
+
// Check for gaps in sequence
|
|
568
|
+
for (let i = 0; i < uniqueSteps.length - 1; i++) {
|
|
569
|
+
if (uniqueSteps[i + 1] - uniqueSteps[i] > 1) {
|
|
570
|
+
errors.push(
|
|
571
|
+
`Step numbering gap: step-${String(uniqueSteps[i]).padStart(2, '0')} to step-${String(uniqueSteps[i + 1]).padStart(2, '0')} (missing step-${String(uniqueSteps[i] + 1).padStart(2, '0')})`
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return { valid: errors.length === 0, errors };
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Validate skill cohesion — workflow.md exists if step files exist
|
|
581
|
+
* @param {string} skillDir - Absolute path to skill directory
|
|
582
|
+
* @returns {Promise<object>} Validation result { valid, errors }
|
|
583
|
+
*/
|
|
584
|
+
async function validateSkillCohesion(skillDir) {
|
|
585
|
+
const errors = [];
|
|
586
|
+
|
|
587
|
+
if (!fs.existsSync(skillDir)) {
|
|
588
|
+
errors.push(`Skill directory not found: ${skillDir}`);
|
|
589
|
+
return { valid: false, errors };
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const entries = fs.readdirSync(skillDir);
|
|
593
|
+
const hasStepFiles = entries.some(e => /^step-\d+-/.test(e) && e.endsWith('.md'));
|
|
594
|
+
const hasStepsSubdir = fs.existsSync(path.join(skillDir, 'steps'));
|
|
595
|
+
const hasWorkflow = entries.includes('workflow.md');
|
|
596
|
+
|
|
597
|
+
// If step files or steps/ subdirectory exist, workflow.md should too
|
|
598
|
+
if ((hasStepFiles || hasStepsSubdir) && !hasWorkflow) {
|
|
599
|
+
errors.push('Skill has step files but no workflow.md');
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
return { valid: errors.length === 0, errors };
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Validate a complete skill package (SKILL.md + step files + cohesion)
|
|
607
|
+
* @param {string} skillDir - Absolute path to skill directory
|
|
608
|
+
* @returns {Promise<object>} Validation result { valid, errors }
|
|
609
|
+
*/
|
|
610
|
+
async function validateSkill(skillDir) {
|
|
611
|
+
const allErrors = [];
|
|
612
|
+
|
|
613
|
+
const skillMdPath = path.join(skillDir, 'SKILL.md');
|
|
614
|
+
const skillMdResult = await validateSkillMd(skillMdPath);
|
|
615
|
+
allErrors.push(...skillMdResult.errors);
|
|
616
|
+
|
|
617
|
+
const stepResult = await validateStepFiles(skillDir);
|
|
618
|
+
allErrors.push(...stepResult.errors);
|
|
619
|
+
|
|
620
|
+
const cohesionResult = await validateSkillCohesion(skillDir);
|
|
621
|
+
allErrors.push(...cohesionResult.errors);
|
|
622
|
+
|
|
623
|
+
return { valid: allErrors.length === 0, errors: allErrors };
|
|
624
|
+
}
|
|
625
|
+
|
|
351
626
|
module.exports = {
|
|
352
627
|
validateInstallation,
|
|
353
628
|
validateConfigStructure,
|
|
@@ -356,5 +631,10 @@ module.exports = {
|
|
|
356
631
|
validateManifest,
|
|
357
632
|
validateUserDataIntegrity,
|
|
358
633
|
validateDeprecatedWorkflows,
|
|
359
|
-
validateWorkflowStepStructure
|
|
634
|
+
validateWorkflowStepStructure,
|
|
635
|
+
validateEnhanceModule,
|
|
636
|
+
validateSkillMd,
|
|
637
|
+
validateStepFiles,
|
|
638
|
+
validateSkillCohesion,
|
|
639
|
+
validateSkill
|
|
360
640
|
};
|