convoke-agents 2.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 +920 -0
- package/INSTALLATION.md +230 -0
- package/LICENSE +21 -0
- package/README.md +330 -0
- package/UPDATE-GUIDE.md +220 -0
- package/_bmad/bme/_vortex/README.md +150 -0
- package/_bmad/bme/_vortex/agents/contextualization-expert.md +100 -0
- package/_bmad/bme/_vortex/agents/discovery-empathy-expert.md +117 -0
- package/_bmad/bme/_vortex/agents/hypothesis-engineer.md +117 -0
- package/_bmad/bme/_vortex/agents/lean-experiments-specialist.md +118 -0
- package/_bmad/bme/_vortex/agents/learning-decision-expert.md +117 -0
- package/_bmad/bme/_vortex/agents/production-intelligence-specialist.md +117 -0
- package/_bmad/bme/_vortex/agents/research-convergence-specialist.md +117 -0
- package/_bmad/bme/_vortex/compass-routing-reference.md +312 -0
- package/_bmad/bme/_vortex/config.yaml +46 -0
- package/_bmad/bme/_vortex/contracts/hc1-empathy-artifacts.md +152 -0
- package/_bmad/bme/_vortex/contracts/hc2-problem-definition.md +125 -0
- package/_bmad/bme/_vortex/contracts/hc3-hypothesis-contract.md +112 -0
- package/_bmad/bme/_vortex/contracts/hc4-experiment-context.md +140 -0
- package/_bmad/bme/_vortex/contracts/hc5-signal-report.md +130 -0
- package/_bmad/bme/_vortex/examples/hc2-example-problem-definition.md +85 -0
- package/_bmad/bme/_vortex/examples/hc3-example-hypothesis-contract.md +103 -0
- package/_bmad/bme/_vortex/examples/hc5-example-signal-report.md +76 -0
- package/_bmad/bme/_vortex/guides/EMMA-USER-GUIDE.md +232 -0
- package/_bmad/bme/_vortex/guides/ISLA-USER-GUIDE.md +208 -0
- package/_bmad/bme/_vortex/guides/LIAM-USER-GUIDE.md +255 -0
- package/_bmad/bme/_vortex/guides/MAX-USER-GUIDE.md +213 -0
- package/_bmad/bme/_vortex/guides/MILA-USER-GUIDE.md +235 -0
- package/_bmad/bme/_vortex/guides/NOAH-USER-GUIDE.md +258 -0
- package/_bmad/bme/_vortex/guides/WADE-USER-GUIDE.md +245 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/empathy-map/empathy-map.template.md +143 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/empathy-map/steps/step-01-define-user.md +60 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/empathy-map/steps/step-02-says-thinks.md +67 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/empathy-map/steps/step-03-does-feels.md +79 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/empathy-map/steps/step-04-pain-points.md +87 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/empathy-map/steps/step-05-gains.md +103 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/empathy-map/steps/step-06-synthesize.md +104 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/empathy-map/validate.md +117 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/empathy-map/workflow.md +44 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/wireframe/steps/step-01-define-requirements.md +85 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/wireframe/steps/step-02-user-flows.md +59 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/wireframe/steps/step-03-information-architecture.md +68 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/wireframe/steps/step-04-wireframe-sketch.md +97 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/wireframe/steps/step-05-components.md +128 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/wireframe/steps/step-06-synthesize.md +83 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/wireframe/wireframe.template.md +287 -0
- package/_bmad/bme/_vortex/workflows/_deprecated/wireframe/workflow.md +44 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/steps/step-01-setup.md +66 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/steps/step-02-context.md +93 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/steps/step-03-risk-mapping.md +103 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/steps/step-04-synthesize.md +101 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/workflow.md +49 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-01-setup.md +81 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-02-context.md +67 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-03-classification.md +98 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-04-evidence.md +100 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-05-synthesize.md +174 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/contextualize-scope.template.md +67 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/steps/step-01-list-opportunities.md +47 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/steps/step-02-define-criteria.md +36 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/steps/step-03-evaluate-opportunities.md +30 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/steps/step-04-define-boundaries.md +32 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/steps/step-05-validate-fit.md +28 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/steps/step-06-synthesize.md +36 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/validate.md +30 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/workflow.md +59 -0
- package/_bmad/bme/_vortex/workflows/empathy-map/empathy-map.template.md +143 -0
- package/_bmad/bme/_vortex/workflows/empathy-map/steps/step-01-define-user.md +60 -0
- package/_bmad/bme/_vortex/workflows/empathy-map/steps/step-02-says-thinks.md +67 -0
- package/_bmad/bme/_vortex/workflows/empathy-map/steps/step-03-does-feels.md +79 -0
- package/_bmad/bme/_vortex/workflows/empathy-map/steps/step-04-pain-points.md +87 -0
- package/_bmad/bme/_vortex/workflows/empathy-map/steps/step-05-gains.md +103 -0
- package/_bmad/bme/_vortex/workflows/empathy-map/steps/step-06-synthesize.md +107 -0
- package/_bmad/bme/_vortex/workflows/empathy-map/validate.md +117 -0
- package/_bmad/bme/_vortex/workflows/empathy-map/workflow.md +45 -0
- package/_bmad/bme/_vortex/workflows/experiment-design/steps/step-01-setup.md +66 -0
- package/_bmad/bme/_vortex/workflows/experiment-design/steps/step-02-context.md +77 -0
- package/_bmad/bme/_vortex/workflows/experiment-design/steps/step-03-design.md +114 -0
- package/_bmad/bme/_vortex/workflows/experiment-design/steps/step-04-synthesize.md +128 -0
- package/_bmad/bme/_vortex/workflows/experiment-design/workflow.md +51 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-01-setup.md +66 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-02-context.md +80 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-03-brainwriting.md +79 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-04-assumption-mapping.md +102 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-05-synthesize.md +130 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/lean-experiment.template.md +29 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/steps/step-01-hypothesis.md +58 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/steps/step-02-design.md +68 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/steps/step-03-metrics.md +73 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/steps/step-04-run.md +75 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/steps/step-05-analyze.md +84 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/steps/step-06-decide.md +111 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/validate.md +30 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/workflow.md +26 -0
- package/_bmad/bme/_vortex/workflows/lean-persona/lean-persona.template.md +163 -0
- package/_bmad/bme/_vortex/workflows/lean-persona/steps/step-01-define-job.md +72 -0
- package/_bmad/bme/_vortex/workflows/lean-persona/steps/step-02-current-solution.md +83 -0
- package/_bmad/bme/_vortex/workflows/lean-persona/steps/step-03-problem-contexts.md +90 -0
- package/_bmad/bme/_vortex/workflows/lean-persona/steps/step-04-forces-anxieties.md +98 -0
- package/_bmad/bme/_vortex/workflows/lean-persona/steps/step-05-success-criteria.md +103 -0
- package/_bmad/bme/_vortex/workflows/lean-persona/steps/step-06-synthesize.md +129 -0
- package/_bmad/bme/_vortex/workflows/lean-persona/validate.md +30 -0
- package/_bmad/bme/_vortex/workflows/lean-persona/workflow.md +50 -0
- package/_bmad/bme/_vortex/workflows/learning-card/learning-card.template.md +179 -0
- package/_bmad/bme/_vortex/workflows/learning-card/steps/step-01-experiment-context.md +100 -0
- package/_bmad/bme/_vortex/workflows/learning-card/steps/step-02-raw-results.md +125 -0
- package/_bmad/bme/_vortex/workflows/learning-card/steps/step-03-analysis.md +125 -0
- package/_bmad/bme/_vortex/workflows/learning-card/steps/step-04-validated-learning.md +139 -0
- package/_bmad/bme/_vortex/workflows/learning-card/steps/step-05-implications.md +134 -0
- package/_bmad/bme/_vortex/workflows/learning-card/steps/step-06-synthesize.md +121 -0
- package/_bmad/bme/_vortex/workflows/learning-card/validate.md +134 -0
- package/_bmad/bme/_vortex/workflows/learning-card/workflow.md +51 -0
- package/_bmad/bme/_vortex/workflows/mvp/mvp.template.md +40 -0
- package/_bmad/bme/_vortex/workflows/mvp/steps/step-01-riskiest-assumption.md +17 -0
- package/_bmad/bme/_vortex/workflows/mvp/steps/step-02-success-criteria.md +13 -0
- package/_bmad/bme/_vortex/workflows/mvp/steps/step-03-smallest-test.md +13 -0
- package/_bmad/bme/_vortex/workflows/mvp/steps/step-04-scope-features.md +13 -0
- package/_bmad/bme/_vortex/workflows/mvp/steps/step-05-build-measure-learn.md +13 -0
- package/_bmad/bme/_vortex/workflows/mvp/steps/step-06-synthesize.md +28 -0
- package/_bmad/bme/_vortex/workflows/mvp/validate.md +30 -0
- package/_bmad/bme/_vortex/workflows/mvp/workflow.md +36 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-01-setup.md +102 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-02-context.md +81 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-03-pattern-identification.md +88 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-04-theme-clustering.md +100 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-05-synthesize.md +135 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/workflow.md +58 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/pivot-patch-persevere.template.md +201 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/steps/step-01-evidence-review.md +125 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/steps/step-02-hypothesis-assessment.md +132 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/steps/step-03-option-analysis.md +167 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/steps/step-04-stakeholder-input.md +141 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/steps/step-05-decision.md +161 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/steps/step-06-action-plan.md +188 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/validate.md +159 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/workflow.md +51 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-01-setup.md +97 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-02-context.md +86 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-03-jtbd-reframing.md +88 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-04-pains-gains-revision.md +76 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-05-synthesize.md +158 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/product-vision/product-vision.template.md +147 -0
- package/_bmad/bme/_vortex/workflows/product-vision/steps/step-01-define-problem.md +89 -0
- package/_bmad/bme/_vortex/workflows/product-vision/steps/step-02-target-market.md +91 -0
- package/_bmad/bme/_vortex/workflows/product-vision/steps/step-03-unique-approach.md +87 -0
- package/_bmad/bme/_vortex/workflows/product-vision/steps/step-04-future-state.md +100 -0
- package/_bmad/bme/_vortex/workflows/product-vision/steps/step-05-principles.md +92 -0
- package/_bmad/bme/_vortex/workflows/product-vision/steps/step-06-synthesize.md +170 -0
- package/_bmad/bme/_vortex/workflows/product-vision/validate.md +30 -0
- package/_bmad/bme/_vortex/workflows/product-vision/workflow.md +55 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-01-setup.md +84 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-02-context.md +66 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-03-monitoring.md +74 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-04-prioritization.md +97 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-05-synthesize.md +183 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/proof-of-concept.template.md +25 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/steps/step-01-risk.md +79 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/steps/step-02-scope.md +105 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/steps/step-03-build.md +92 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/steps/step-04-test.md +103 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/steps/step-05-evaluate.md +114 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/steps/step-06-document.md +125 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/validate.md +30 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/workflow.md +26 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/proof-of-value.template.md +29 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/steps/step-01-value-hypothesis.md +75 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/steps/step-02-validation-design.md +94 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/steps/step-03-willingness.md +96 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/steps/step-04-test.md +107 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/steps/step-05-analyze.md +116 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/steps/step-06-document.md +147 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/validate.md +30 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/workflow.md +26 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-01-setup.md +69 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-02-context.md +70 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-03-jtbd-framing.md +81 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-04-pains-gains.md +77 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-05-synthesize.md +147 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/workflow.md +50 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-01-setup.md +68 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-02-context.md +67 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-03-signal-analysis.md +85 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-04-anomaly-detection.md +93 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-05-synthesize.md +163 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/steps/step-01-discovery-scope.md +77 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/steps/step-02-research-methods.md +152 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/steps/step-03-research-plan.md +159 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/steps/step-04-execute.md +169 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/steps/step-05-organize-data.md +149 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/steps/step-06-synthesize.md +159 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/user-discovery.template.md +231 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/validate.md +153 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/workflow.md +45 -0
- package/_bmad/bme/_vortex/workflows/user-interview/steps/step-01-research-goals.md +100 -0
- package/_bmad/bme/_vortex/workflows/user-interview/steps/step-02-interview-script.md +123 -0
- package/_bmad/bme/_vortex/workflows/user-interview/steps/step-03-recruitment.md +144 -0
- package/_bmad/bme/_vortex/workflows/user-interview/steps/step-04-conduct.md +154 -0
- package/_bmad/bme/_vortex/workflows/user-interview/steps/step-05-findings.md +163 -0
- package/_bmad/bme/_vortex/workflows/user-interview/steps/step-06-synthesize.md +171 -0
- package/_bmad/bme/_vortex/workflows/user-interview/user-interview.template.md +250 -0
- package/_bmad/bme/_vortex/workflows/user-interview/validate.md +142 -0
- package/_bmad/bme/_vortex/workflows/user-interview/workflow.md +51 -0
- package/_bmad/bme/_vortex/workflows/vortex-navigation/steps/step-01-current-state.md +56 -0
- package/_bmad/bme/_vortex/workflows/vortex-navigation/steps/step-02-evidence-inventory.md +70 -0
- package/_bmad/bme/_vortex/workflows/vortex-navigation/steps/step-03-gap-analysis.md +76 -0
- package/_bmad/bme/_vortex/workflows/vortex-navigation/steps/step-04-stream-evaluation.md +57 -0
- package/_bmad/bme/_vortex/workflows/vortex-navigation/steps/step-05-recommendation.md +65 -0
- package/_bmad/bme/_vortex/workflows/vortex-navigation/steps/step-06-navigation-plan.md +72 -0
- package/_bmad/bme/_vortex/workflows/vortex-navigation/validate.md +75 -0
- package/_bmad/bme/_vortex/workflows/vortex-navigation/vortex-navigation.template.md +105 -0
- package/_bmad/bme/_vortex/workflows/vortex-navigation/workflow.md +54 -0
- package/index.js +56 -0
- package/package.json +77 -0
- package/scripts/README.md +226 -0
- package/scripts/convoke-doctor.js +322 -0
- package/scripts/docs-audit.js +584 -0
- package/scripts/install-all-agents.js +9 -0
- package/scripts/install-vortex-agents.js +208 -0
- package/scripts/postinstall.js +104 -0
- package/scripts/update/convoke-migrate.js +169 -0
- package/scripts/update/convoke-update.js +272 -0
- package/scripts/update/convoke-version.js +134 -0
- package/scripts/update/lib/agent-registry.js +144 -0
- package/scripts/update/lib/backup-manager.js +243 -0
- package/scripts/update/lib/config-merger.js +242 -0
- package/scripts/update/lib/migration-runner.js +367 -0
- package/scripts/update/lib/refresh-installation.js +171 -0
- package/scripts/update/lib/utils.js +96 -0
- package/scripts/update/lib/validator.js +360 -0
- package/scripts/update/lib/version-detector.js +241 -0
- package/scripts/update/migrations/1.0.x-to-1.3.0.js +128 -0
- package/scripts/update/migrations/1.1.x-to-1.3.0.js +29 -0
- package/scripts/update/migrations/1.2.x-to-1.3.0.js +29 -0
- package/scripts/update/migrations/1.3.x-to-1.5.0.js +29 -0
- package/scripts/update/migrations/1.4.x-to-1.5.0.js +29 -0
- package/scripts/update/migrations/1.5.x-to-1.6.0.js +95 -0
- package/scripts/update/migrations/1.6.x-to-1.7.0.js +29 -0
- package/scripts/update/migrations/1.7.x-to-2.0.0.js +31 -0
- package/scripts/update/migrations/registry.js +194 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { countUserDataFiles } = require('./utils');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Backup Manager for Convoke
|
|
9
|
+
* Creates backups before migrations and restores on failure
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create a backup of critical installation files
|
|
14
|
+
* @param {string} version - Current version being backed up
|
|
15
|
+
* @param {string} projectRoot - Absolute path to project root
|
|
16
|
+
* @returns {Promise<object>} Backup metadata
|
|
17
|
+
*/
|
|
18
|
+
async function createBackup(version, projectRoot) {
|
|
19
|
+
const timestamp = Date.now();
|
|
20
|
+
const backupDir = path.join(
|
|
21
|
+
projectRoot,
|
|
22
|
+
'_bmad-output/.backups',
|
|
23
|
+
`backup-${version}-${timestamp}`
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
console.log(`Creating backup in: ${backupDir}`);
|
|
27
|
+
|
|
28
|
+
// Ensure backup directory exists
|
|
29
|
+
await ensureBackupDirectory(projectRoot);
|
|
30
|
+
|
|
31
|
+
// Create backup directory
|
|
32
|
+
await fs.ensureDir(backupDir);
|
|
33
|
+
|
|
34
|
+
const filesToBackup = getFilesToBackup();
|
|
35
|
+
const backedUpFiles = [];
|
|
36
|
+
|
|
37
|
+
// Copy each file/directory to backup
|
|
38
|
+
for (const file of filesToBackup) {
|
|
39
|
+
const sourcePath = path.join(projectRoot, file.path);
|
|
40
|
+
|
|
41
|
+
if (!fs.existsSync(sourcePath)) {
|
|
42
|
+
console.log(` Skipping ${file.path} (does not exist)`);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const destPath = path.join(backupDir, file.name);
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
await fs.copy(sourcePath, destPath);
|
|
50
|
+
backedUpFiles.push(file.path);
|
|
51
|
+
console.log(` ✓ Backed up: ${file.path}`);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error(` ✗ Failed to backup ${file.path}:`, error.message);
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Count user data files (for integrity check)
|
|
59
|
+
const userDataCount = await countUserDataFiles(projectRoot);
|
|
60
|
+
|
|
61
|
+
// Create backup manifest
|
|
62
|
+
const manifest = {
|
|
63
|
+
version,
|
|
64
|
+
timestamp: new Date().toISOString(),
|
|
65
|
+
timestampMs: timestamp,
|
|
66
|
+
files_backed_up: backedUpFiles,
|
|
67
|
+
user_data_count: userDataCount,
|
|
68
|
+
backup_dir: backupDir
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
await fs.writeJson(path.join(backupDir, 'backup-manifest.json'), manifest, { spaces: 2 });
|
|
72
|
+
|
|
73
|
+
console.log(` ✓ Backup manifest created`);
|
|
74
|
+
console.log(` ✓ Backup complete: ${backedUpFiles.length} items backed up`);
|
|
75
|
+
|
|
76
|
+
return manifest;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Restore from backup after migration failure
|
|
81
|
+
* @param {object} backupMetadata - Metadata from createBackup
|
|
82
|
+
* @param {string} projectRoot - Absolute path to project root
|
|
83
|
+
* @returns {Promise<void>}
|
|
84
|
+
*/
|
|
85
|
+
async function restoreBackup(backupMetadata, projectRoot) {
|
|
86
|
+
const backupDir = backupMetadata.backup_dir;
|
|
87
|
+
|
|
88
|
+
console.log('');
|
|
89
|
+
console.log(`Restoring from backup: ${backupDir}`);
|
|
90
|
+
|
|
91
|
+
if (!fs.existsSync(backupDir)) {
|
|
92
|
+
throw new Error(`Backup directory not found: ${backupDir}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const filesToRestore = getFilesToBackup();
|
|
96
|
+
|
|
97
|
+
for (const file of filesToRestore) {
|
|
98
|
+
const sourcePath = path.join(backupDir, file.name);
|
|
99
|
+
|
|
100
|
+
if (!fs.existsSync(sourcePath)) {
|
|
101
|
+
console.log(` Skipping ${file.name} (not in backup)`);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const destPath = path.join(projectRoot, file.path);
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
// Remove existing file/directory first
|
|
109
|
+
if (fs.existsSync(destPath)) {
|
|
110
|
+
await fs.remove(destPath);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Restore from backup
|
|
114
|
+
await fs.copy(sourcePath, destPath);
|
|
115
|
+
console.log(` ✓ Restored: ${file.path}`);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error(` ✗ Failed to restore ${file.path}:`, error.message);
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
console.log(` ✓ Restoration complete`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* List available backups
|
|
127
|
+
* @param {string} projectRoot - Absolute path to project root
|
|
128
|
+
* @returns {Promise<Array>} List of backup metadata
|
|
129
|
+
*/
|
|
130
|
+
async function listBackups(projectRoot) {
|
|
131
|
+
const backupsDir = path.join(projectRoot, '_bmad-output/.backups');
|
|
132
|
+
|
|
133
|
+
if (!fs.existsSync(backupsDir)) {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const entries = await fs.readdir(backupsDir);
|
|
138
|
+
const backups = [];
|
|
139
|
+
|
|
140
|
+
for (const entry of entries) {
|
|
141
|
+
const backupPath = path.join(backupsDir, entry);
|
|
142
|
+
const manifestPath = path.join(backupPath, 'backup-manifest.json');
|
|
143
|
+
|
|
144
|
+
if (fs.existsSync(manifestPath)) {
|
|
145
|
+
try {
|
|
146
|
+
const manifest = await fs.readJson(manifestPath);
|
|
147
|
+
backups.push(manifest);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.warn(`Could not read manifest for ${entry}:`, error.message);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Sort by timestamp (newest first)
|
|
155
|
+
backups.sort((a, b) => b.timestampMs - a.timestampMs);
|
|
156
|
+
|
|
157
|
+
return backups;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Clean up old backups, keeping only the most recent N
|
|
162
|
+
* @param {number} keepCount - Number of backups to keep
|
|
163
|
+
* @param {string} projectRoot - Absolute path to project root
|
|
164
|
+
* @returns {Promise<number>} Number of backups deleted
|
|
165
|
+
*/
|
|
166
|
+
async function cleanupOldBackups(keepCount = 5, projectRoot) {
|
|
167
|
+
const backups = await listBackups(projectRoot);
|
|
168
|
+
|
|
169
|
+
if (backups.length <= keepCount) {
|
|
170
|
+
return 0; // Nothing to clean up
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const toDelete = backups.slice(keepCount);
|
|
174
|
+
let deletedCount = 0;
|
|
175
|
+
|
|
176
|
+
for (const backup of toDelete) {
|
|
177
|
+
try {
|
|
178
|
+
await fs.remove(backup.backup_dir);
|
|
179
|
+
console.log(` Deleted old backup: ${path.basename(backup.backup_dir)}`);
|
|
180
|
+
deletedCount++;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.warn(` Could not delete backup ${backup.backup_dir}:`, error.message);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return deletedCount;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Ensure backup directory exists
|
|
191
|
+
* @param {string} projectRoot - Absolute path to project root
|
|
192
|
+
* @returns {Promise<void>}
|
|
193
|
+
*/
|
|
194
|
+
async function ensureBackupDirectory(projectRoot) {
|
|
195
|
+
const backupDir = path.join(projectRoot, '_bmad-output/.backups');
|
|
196
|
+
|
|
197
|
+
if (!fs.existsSync(backupDir)) {
|
|
198
|
+
const outputDir = path.join(projectRoot, '_bmad-output');
|
|
199
|
+
|
|
200
|
+
if (!fs.existsSync(outputDir)) {
|
|
201
|
+
throw new Error('_bmad-output directory not found. Is BMAD Method installed?');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
await fs.ensureDir(backupDir);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Get list of files/directories to backup
|
|
210
|
+
* @returns {Array} List of file/directory definitions
|
|
211
|
+
*/
|
|
212
|
+
function getFilesToBackup() {
|
|
213
|
+
return [
|
|
214
|
+
{
|
|
215
|
+
name: 'config.yaml',
|
|
216
|
+
path: '_bmad/bme/_vortex/config.yaml',
|
|
217
|
+
type: 'file'
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: 'agents',
|
|
221
|
+
path: '_bmad/bme/_vortex/agents',
|
|
222
|
+
type: 'directory'
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: 'workflows',
|
|
226
|
+
path: '_bmad/bme/_vortex/workflows',
|
|
227
|
+
type: 'directory'
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
name: 'agent-manifest.csv',
|
|
231
|
+
path: '_bmad/_config/agent-manifest.csv',
|
|
232
|
+
type: 'file'
|
|
233
|
+
}
|
|
234
|
+
];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
module.exports = {
|
|
238
|
+
createBackup,
|
|
239
|
+
restoreBackup,
|
|
240
|
+
listBackups,
|
|
241
|
+
cleanupOldBackups,
|
|
242
|
+
ensureBackupDirectory
|
|
243
|
+
};
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const yaml = require('js-yaml');
|
|
5
|
+
const { AGENT_IDS, WORKFLOW_NAMES } = require('./agent-registry');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Config Merger for Convoke
|
|
9
|
+
* Smart YAML merging preserving user settings
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Merge current config with new template while preserving user preferences.
|
|
14
|
+
* Agents and workflows use smart-merge: canonical entries in registry order
|
|
15
|
+
* first, then any user-added entries (not in AGENT_IDS/WORKFLOW_NAMES)
|
|
16
|
+
* appended and deduplicated.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} currentConfigPath - Path to current config.yaml
|
|
19
|
+
* @param {string} newVersion - New version to set
|
|
20
|
+
* @param {object} updates - Updates to apply (agents, workflows, etc.)
|
|
21
|
+
* @returns {Promise<object>} Merged config object
|
|
22
|
+
*/
|
|
23
|
+
async function mergeConfig(currentConfigPath, newVersion, updates = {}) {
|
|
24
|
+
let current = {};
|
|
25
|
+
|
|
26
|
+
// Read current config if it exists
|
|
27
|
+
if (fs.existsSync(currentConfigPath)) {
|
|
28
|
+
try {
|
|
29
|
+
const currentContent = fs.readFileSync(currentConfigPath, 'utf8');
|
|
30
|
+
const parsed = yaml.load(currentContent);
|
|
31
|
+
current = (parsed && typeof parsed === 'object') ? parsed : {};
|
|
32
|
+
} catch (_error) {
|
|
33
|
+
console.warn('Warning: Could not parse current config.yaml, using defaults');
|
|
34
|
+
current = {};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Extract user preferences
|
|
39
|
+
const userPrefs = extractUserPreferences(current);
|
|
40
|
+
|
|
41
|
+
// Seed with required structural defaults for fresh installs
|
|
42
|
+
const defaults = {
|
|
43
|
+
submodule_name: '_vortex',
|
|
44
|
+
description: 'Vortex Pattern - Contextualize, Empathize, Synthesize, Hypothesize, Externalize, Sensitize, and Systematize streams',
|
|
45
|
+
module: 'bme',
|
|
46
|
+
output_folder: '{project-root}/_bmad-output/vortex-artifacts',
|
|
47
|
+
agents: [...AGENT_IDS],
|
|
48
|
+
workflows: [...WORKFLOW_NAMES]
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Start with defaults, overlay current config (preserves existing values)
|
|
52
|
+
const merged = { ...defaults, ...current };
|
|
53
|
+
|
|
54
|
+
// Update version (system field)
|
|
55
|
+
merged.version = newVersion;
|
|
56
|
+
|
|
57
|
+
// Smart-merge agents: canonical agents in order, then unique user-added agents appended.
|
|
58
|
+
// Core agents are always restored to canonical order. User-added agents (not in AGENT_IDS)
|
|
59
|
+
// are preserved and deduplicated. Deliberately removed core agents are restored on upgrade.
|
|
60
|
+
if (updates.agents) {
|
|
61
|
+
const userAgents = Array.isArray(current.agents)
|
|
62
|
+
? [...new Set(current.agents.filter(a => !AGENT_IDS.includes(a)))]
|
|
63
|
+
: [];
|
|
64
|
+
merged.agents = [...updates.agents, ...userAgents];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Smart-merge workflows: canonical workflows in order, then unique user-added appended
|
|
68
|
+
if (updates.workflows) {
|
|
69
|
+
const userWorkflows = Array.isArray(current.workflows)
|
|
70
|
+
? [...new Set(current.workflows.filter(w => !WORKFLOW_NAMES.includes(w)))]
|
|
71
|
+
: [];
|
|
72
|
+
merged.workflows = [...updates.workflows, ...userWorkflows];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Preserve user preferences
|
|
76
|
+
Object.assign(merged, userPrefs);
|
|
77
|
+
|
|
78
|
+
// Ensure migration_history exists
|
|
79
|
+
if (!merged.migration_history) {
|
|
80
|
+
merged.migration_history = [];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return merged;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Extract user-specific preferences from config
|
|
88
|
+
* @param {object} config - Config object
|
|
89
|
+
* @returns {object} User preferences
|
|
90
|
+
*/
|
|
91
|
+
function extractUserPreferences(config) {
|
|
92
|
+
const prefs = {};
|
|
93
|
+
|
|
94
|
+
// Preserve these fields if they exist and are not default placeholders
|
|
95
|
+
if (config.user_name && config.user_name !== '{user}') {
|
|
96
|
+
prefs.user_name = config.user_name;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (config.communication_language) {
|
|
100
|
+
prefs.communication_language = config.communication_language;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (config.output_folder && config.output_folder !== '{project-root}/_bmad-output/vortex-artifacts') {
|
|
104
|
+
prefs.output_folder = config.output_folder;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (Object.prototype.hasOwnProperty.call(config, 'party_mode_enabled')) {
|
|
108
|
+
prefs.party_mode_enabled = config.party_mode_enabled;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (config.migration_history) {
|
|
112
|
+
prefs.migration_history = config.migration_history;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return prefs;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Declarative config schema.
|
|
120
|
+
* Each entry declares a field's type, whether it's required, and an optional
|
|
121
|
+
* validation function that receives the value and returns an error string or null.
|
|
122
|
+
*/
|
|
123
|
+
const CONFIG_SCHEMA = [
|
|
124
|
+
{ field: 'submodule_name', type: 'string', required: true },
|
|
125
|
+
{ field: 'description', type: 'string', required: true },
|
|
126
|
+
{ field: 'module', type: 'string', required: true },
|
|
127
|
+
{ field: 'version', type: 'string', required: true,
|
|
128
|
+
validate: v => /^\d+\.\d+\.\d+$/.test(v) ? null : `Invalid version format: ${v} (expected x.x.x)` },
|
|
129
|
+
{ field: 'output_folder', type: 'string', required: true },
|
|
130
|
+
{ field: 'agents', type: 'array', required: true, items: 'string' },
|
|
131
|
+
{ field: 'workflows', type: 'array', required: true, items: 'string' },
|
|
132
|
+
{ field: 'communication_language', type: 'string', required: false },
|
|
133
|
+
{ field: 'party_mode_enabled', type: 'boolean', required: false },
|
|
134
|
+
{ field: 'migration_history', type: 'array', required: false,
|
|
135
|
+
validate: (arr) => {
|
|
136
|
+
for (let i = 0; i < arr.length; i++) {
|
|
137
|
+
const e = arr[i];
|
|
138
|
+
if (!e.timestamp || !e.from_version || !e.to_version) {
|
|
139
|
+
return `migration_history[${i}] missing required fields`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}},
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Validate merged config structure
|
|
148
|
+
* @param {object} config - Config to validate
|
|
149
|
+
* @returns {object} Validation result { valid: boolean, errors: [] }
|
|
150
|
+
*/
|
|
151
|
+
function validateConfig(config) {
|
|
152
|
+
const errors = [];
|
|
153
|
+
|
|
154
|
+
for (const rule of CONFIG_SCHEMA) {
|
|
155
|
+
const has = Object.prototype.hasOwnProperty.call(config, rule.field);
|
|
156
|
+
|
|
157
|
+
if (!has) {
|
|
158
|
+
if (rule.required) errors.push(`Missing required field: ${rule.field}`);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const value = config[rule.field];
|
|
163
|
+
|
|
164
|
+
// Type check
|
|
165
|
+
if (rule.type === 'array') {
|
|
166
|
+
if (!Array.isArray(value)) {
|
|
167
|
+
errors.push(`${rule.field} must be an array`);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
// Item type check
|
|
171
|
+
if (rule.items) {
|
|
172
|
+
for (let i = 0; i < value.length; i++) {
|
|
173
|
+
if (typeof value[i] !== rule.items) {
|
|
174
|
+
errors.push(`${rule.field}[${i}] must be a ${rule.items}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} else if (typeof value !== rule.type) {
|
|
179
|
+
errors.push(`${rule.field} must be a ${rule.type}`);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Custom validation
|
|
184
|
+
if (rule.validate) {
|
|
185
|
+
const err = rule.validate(value);
|
|
186
|
+
if (err) errors.push(err);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
valid: errors.length === 0,
|
|
192
|
+
errors
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Write config to file
|
|
198
|
+
* @param {string} configPath - Path to write config
|
|
199
|
+
* @param {object} config - Config object
|
|
200
|
+
* @returns {Promise<void>}
|
|
201
|
+
*/
|
|
202
|
+
async function writeConfig(configPath, config) {
|
|
203
|
+
const yamlContent = yaml.dump(config, {
|
|
204
|
+
indent: 2,
|
|
205
|
+
lineWidth: -1, // Don't wrap long lines
|
|
206
|
+
noRefs: true
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
await fs.writeFile(configPath, yamlContent, 'utf8');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Add migration history entry
|
|
214
|
+
* @param {object} config - Config object
|
|
215
|
+
* @param {string} fromVersion - Version migrating from
|
|
216
|
+
* @param {string} toVersion - Version migrating to
|
|
217
|
+
* @param {Array<string>} migrationsApplied - List of migration names applied
|
|
218
|
+
* @returns {object} Updated config
|
|
219
|
+
*/
|
|
220
|
+
function addMigrationHistory(config, fromVersion, toVersion, migrationsApplied) {
|
|
221
|
+
if (!config.migration_history) {
|
|
222
|
+
config.migration_history = [];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
config.migration_history.push({
|
|
226
|
+
timestamp: new Date().toISOString(),
|
|
227
|
+
from_version: fromVersion,
|
|
228
|
+
to_version: toVersion,
|
|
229
|
+
migrations_applied: migrationsApplied
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
return config;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
module.exports = {
|
|
236
|
+
CONFIG_SCHEMA,
|
|
237
|
+
mergeConfig,
|
|
238
|
+
extractUserPreferences,
|
|
239
|
+
validateConfig,
|
|
240
|
+
writeConfig,
|
|
241
|
+
addMigrationHistory
|
|
242
|
+
};
|