convoke-agents 3.0.4 → 3.1.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.
@@ -0,0 +1,138 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const yaml = require('js-yaml');
4
+
5
+ /**
6
+ * Platform-canonical taxonomy defaults.
7
+ * Mirrors migrate-artifacts.js constants (separate module boundary).
8
+ */
9
+ const PLATFORM_INITIATIVES = ['vortex', 'gyre', 'bmm', 'forge', 'helm', 'enhance', 'loom', 'convoke'];
10
+
11
+ const DEFAULT_ARTIFACT_TYPES = [
12
+ 'prd', 'epic', 'arch', 'adr', 'persona', 'lean-persona', 'empathy-map',
13
+ 'problem-def', 'hypothesis', 'experiment', 'signal', 'decision', 'scope',
14
+ 'pre-reg', 'sprint', 'brief', 'vision', 'report', 'research', 'story', 'spec'
15
+ ];
16
+
17
+ const DEFAULT_ALIASES = {
18
+ 'strategy-perimeter': 'helm',
19
+ 'strategy': 'helm',
20
+ 'strategic': 'helm',
21
+ 'strategic-navigator': 'helm',
22
+ 'strategic-practitioner': 'helm',
23
+ 'team-factory': 'loom'
24
+ };
25
+
26
+ const TAXONOMY_HEADER = [
27
+ '# Artifact Governance Taxonomy Configuration',
28
+ '# Schema version: 1',
29
+ '# Managed by: convoke-update taxonomy merger',
30
+ '#',
31
+ '# This file is the single source of truth for initiative IDs, artifact types,',
32
+ '# and historical name aliases used by the governance system.',
33
+ ''
34
+ ].join('\n');
35
+
36
+ /**
37
+ * Create or merge taxonomy.yaml with platform defaults.
38
+ * Idempotent: safe to run multiple times.
39
+ *
40
+ * - If absent: creates with platform defaults
41
+ * - If present: merges platform entries (adds missing, preserves user additions)
42
+ * - Promotes user initiative IDs to platform when they match (FR42)
43
+ *
44
+ * @param {string} projectRoot - Absolute path to project root
45
+ * @returns {Promise<{created: boolean, merged: boolean, promoted: string[]}>}
46
+ */
47
+ async function mergeTaxonomy(projectRoot) {
48
+ const configDir = path.join(projectRoot, '_bmad', '_config');
49
+ const configPath = path.join(configDir, 'taxonomy.yaml');
50
+
51
+ await fs.ensureDir(configDir);
52
+
53
+ // If no taxonomy exists, create from scratch
54
+ if (!await fs.pathExists(configPath)) {
55
+ const defaults = {
56
+ initiatives: { platform: [...PLATFORM_INITIATIVES], user: [] },
57
+ artifact_types: [...DEFAULT_ARTIFACT_TYPES],
58
+ aliases: { ...DEFAULT_ALIASES }
59
+ };
60
+ await fs.writeFile(configPath, TAXONOMY_HEADER + yaml.dump(defaults, { lineWidth: -1 }), 'utf8');
61
+ return { created: true, merged: false, promoted: [] };
62
+ }
63
+
64
+ // Read existing taxonomy (handle corrupt YAML gracefully, matching config-merger pattern)
65
+ const content = await fs.readFile(configPath, 'utf8');
66
+ let existing;
67
+ try {
68
+ existing = yaml.load(content) || {};
69
+ } catch {
70
+ console.warn('Warning: taxonomy.yaml contains invalid YAML. Treating as empty and merging defaults.');
71
+ existing = {};
72
+ }
73
+
74
+ // Ensure structure
75
+ if (!existing.initiatives) existing.initiatives = {};
76
+ if (!Array.isArray(existing.initiatives.platform)) existing.initiatives.platform = [];
77
+ if (!Array.isArray(existing.initiatives.user)) existing.initiatives.user = [];
78
+ if (!Array.isArray(existing.artifact_types)) existing.artifact_types = [];
79
+ if (!existing.aliases || typeof existing.aliases !== 'object') existing.aliases = {};
80
+
81
+ let merged = false;
82
+ const promoted = [];
83
+
84
+ // Merge platform initiatives (add missing)
85
+ const platformSet = new Set(existing.initiatives.platform);
86
+ for (const id of PLATFORM_INITIATIVES) {
87
+ if (!platformSet.has(id)) {
88
+ existing.initiatives.platform.push(id);
89
+ merged = true;
90
+ }
91
+ }
92
+
93
+ // Promote user IDs that match platform (FR42)
94
+ const date = new Date().toISOString().split('T')[0];
95
+ const newPlatformSet = new Set(existing.initiatives.platform);
96
+ existing.initiatives.user = existing.initiatives.user.filter(userId => {
97
+ if (newPlatformSet.has(userId)) {
98
+ promoted.push(userId);
99
+ return false; // Remove from user (already in platform)
100
+ }
101
+ return true;
102
+ });
103
+
104
+ // Merge artifact types (add missing)
105
+ const typeSet = new Set(existing.artifact_types);
106
+ for (const type of DEFAULT_ARTIFACT_TYPES) {
107
+ if (!typeSet.has(type)) {
108
+ existing.artifact_types.push(type);
109
+ merged = true;
110
+ }
111
+ }
112
+
113
+ // Merge aliases (add missing, don't overwrite existing)
114
+ for (const [key, value] of Object.entries(DEFAULT_ALIASES)) {
115
+ if (!(key in existing.aliases)) {
116
+ existing.aliases[key] = value;
117
+ merged = true;
118
+ }
119
+ }
120
+
121
+ // Write back if changes were made
122
+ if (merged || promoted.length > 0) {
123
+ let output = TAXONOMY_HEADER + yaml.dump(existing, { lineWidth: -1 });
124
+
125
+ // Add promotion comments
126
+ if (promoted.length > 0) {
127
+ for (const id of promoted) {
128
+ output += `# ${id}: promoted from user section on ${date}\n`;
129
+ }
130
+ }
131
+
132
+ await fs.writeFile(configPath, output, 'utf8');
133
+ }
134
+
135
+ return { created: false, merged: merged || promoted.length > 0, promoted };
136
+ }
137
+
138
+ module.exports = { mergeTaxonomy, PLATFORM_INITIATIVES, DEFAULT_ARTIFACT_TYPES, DEFAULT_ALIASES };
@@ -0,0 +1,50 @@
1
+ const { mergeTaxonomy } = require('../lib/taxonomy-merger');
2
+
3
+ /**
4
+ * Migration: 2.0.x → 3.1.0
5
+ * Introduces artifact governance taxonomy configuration.
6
+ * Creates or merges _bmad/_config/taxonomy.yaml with platform defaults.
7
+ * Idempotent — safe to re-run.
8
+ */
9
+
10
+ module.exports = {
11
+ name: '2.0.x-to-3.1.0',
12
+ fromVersion: '2.0.x',
13
+ breaking: false,
14
+
15
+ async preview() {
16
+ return {
17
+ actions: [
18
+ 'Create or merge _bmad/_config/taxonomy.yaml with platform defaults',
19
+ 'Add 8 platform initiative IDs (vortex, gyre, bmm, forge, helm, enhance, loom, convoke)',
20
+ 'Add 21 artifact type identifiers',
21
+ 'Add 6 historical name aliases for migration',
22
+ 'Promote any user initiative IDs that match new platform IDs'
23
+ ]
24
+ };
25
+ },
26
+
27
+ /**
28
+ * Apply migration: create or merge taxonomy config.
29
+ * @param {string} projectRoot - Absolute path to project root
30
+ * @returns {Promise<Array<string>>} List of changes made
31
+ */
32
+ async apply(projectRoot) {
33
+ const changes = [];
34
+ const result = await mergeTaxonomy(projectRoot);
35
+
36
+ if (result.created) {
37
+ changes.push('Created _bmad/_config/taxonomy.yaml with platform defaults');
38
+ } else if (result.merged) {
39
+ changes.push('Merged platform entries into existing taxonomy.yaml');
40
+ } else {
41
+ changes.push('Taxonomy already up to date — no changes needed');
42
+ }
43
+
44
+ if (result.promoted.length > 0) {
45
+ changes.push(`Promoted ${result.promoted.length} user initiative(s) to platform: ${result.promoted.join(', ')}`);
46
+ }
47
+
48
+ return changes;
49
+ }
50
+ };
@@ -0,0 +1,41 @@
1
+ const { mergeTaxonomy } = require('../lib/taxonomy-merger');
2
+
3
+ /**
4
+ * Migration: 3.0.x → 3.1.0
5
+ * Parallel entry for 3.0.x users (same logic as 2.0.x-to-3.1.0).
6
+ * Introduces artifact governance taxonomy configuration.
7
+ */
8
+
9
+ module.exports = {
10
+ name: '3.0.x-to-3.1.0',
11
+ fromVersion: '3.0.x',
12
+ breaking: false,
13
+
14
+ async preview() {
15
+ return {
16
+ actions: [
17
+ 'Create or merge _bmad/_config/taxonomy.yaml with platform defaults',
18
+ 'Add platform initiative IDs, artifact types, and aliases if missing'
19
+ ]
20
+ };
21
+ },
22
+
23
+ async apply(projectRoot) {
24
+ const changes = [];
25
+ const result = await mergeTaxonomy(projectRoot);
26
+
27
+ if (result.created) {
28
+ changes.push('Created _bmad/_config/taxonomy.yaml with platform defaults');
29
+ } else if (result.merged) {
30
+ changes.push('Merged platform entries into existing taxonomy.yaml');
31
+ } else {
32
+ changes.push('Taxonomy already up to date — no changes needed');
33
+ }
34
+
35
+ if (result.promoted.length > 0) {
36
+ changes.push(`Promoted ${result.promoted.length} user initiative(s) to platform: ${result.promoted.join(', ')}`);
37
+ }
38
+
39
+ return changes;
40
+ }
41
+ };
@@ -67,6 +67,20 @@ const MIGRATIONS = [
67
67
  breaking: true,
68
68
  description: 'Product rename: BMAD-Enhanced -> Convoke. CLI commands renamed from bmad-* to convoke-*. _bmad/ directory preserved.',
69
69
  module: null
70
+ },
71
+ {
72
+ name: '2.0.x-to-3.1.0',
73
+ fromVersion: '2.0.x',
74
+ breaking: false,
75
+ description: 'Artifact governance: create or merge _bmad/_config/taxonomy.yaml with platform defaults, aliases, and artifact types',
76
+ module: null
77
+ },
78
+ {
79
+ name: '3.0.x-to-3.1.0',
80
+ fromVersion: '3.0.x',
81
+ breaking: false,
82
+ description: 'Artifact governance: create or merge _bmad/_config/taxonomy.yaml (parallel entry for 3.0.x users)',
83
+ module: null
70
84
  }
71
85
  // Future migrations: append here. Only add delta logic for version-specific changes.
72
86
  ];