specweave 0.34.4 → 0.34.6

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 (76) hide show
  1. package/bin/fix-marketplace-errors.sh +55 -7
  2. package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -1
  3. package/dist/plugins/specweave-github/lib/github-feature-sync.js +3 -1
  4. package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -1
  5. package/dist/src/cli/commands/init.d.ts.map +1 -1
  6. package/dist/src/cli/commands/init.js +11 -2
  7. package/dist/src/cli/commands/init.js.map +1 -1
  8. package/dist/src/cli/commands/living-docs.js +4 -4
  9. package/dist/src/cli/commands/living-docs.js.map +1 -1
  10. package/dist/src/cli/helpers/init/brownfield-analysis.js +15 -15
  11. package/dist/src/cli/helpers/init/brownfield-analysis.js.map +1 -1
  12. package/dist/src/cli/helpers/init/living-docs-preflight.js +7 -7
  13. package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
  14. package/dist/src/cli/helpers/init/plugin-installer.d.ts.map +1 -1
  15. package/dist/src/cli/helpers/init/plugin-installer.js +61 -9
  16. package/dist/src/cli/helpers/init/plugin-installer.js.map +1 -1
  17. package/dist/src/core/background/types.d.ts +3 -0
  18. package/dist/src/core/background/types.d.ts.map +1 -1
  19. package/dist/src/core/living-docs/delivery/delivery-generator.d.ts +58 -0
  20. package/dist/src/core/living-docs/delivery/delivery-generator.d.ts.map +1 -0
  21. package/dist/src/core/living-docs/delivery/delivery-generator.js +501 -0
  22. package/dist/src/core/living-docs/delivery/delivery-generator.js.map +1 -0
  23. package/dist/src/core/living-docs/delivery/index.d.ts +8 -0
  24. package/dist/src/core/living-docs/delivery/index.d.ts.map +1 -0
  25. package/dist/src/core/living-docs/delivery/index.js +7 -0
  26. package/dist/src/core/living-docs/delivery/index.js.map +1 -0
  27. package/dist/src/core/living-docs/diagrams/index.d.ts +8 -0
  28. package/dist/src/core/living-docs/diagrams/index.d.ts.map +1 -0
  29. package/dist/src/core/living-docs/diagrams/index.js +7 -0
  30. package/dist/src/core/living-docs/diagrams/index.js.map +1 -0
  31. package/dist/src/core/living-docs/diagrams/mermaid-generator.d.ts +103 -0
  32. package/dist/src/core/living-docs/diagrams/mermaid-generator.d.ts.map +1 -0
  33. package/dist/src/core/living-docs/diagrams/mermaid-generator.js +515 -0
  34. package/dist/src/core/living-docs/diagrams/mermaid-generator.js.map +1 -0
  35. package/dist/src/core/living-docs/enterprise/enterprise-generator.d.ts +85 -0
  36. package/dist/src/core/living-docs/enterprise/enterprise-generator.d.ts.map +1 -0
  37. package/dist/src/core/living-docs/enterprise/enterprise-generator.js +556 -0
  38. package/dist/src/core/living-docs/enterprise/enterprise-generator.js.map +1 -0
  39. package/dist/src/core/living-docs/enterprise/history-analyzer.d.ts +91 -0
  40. package/dist/src/core/living-docs/enterprise/history-analyzer.d.ts.map +1 -0
  41. package/dist/src/core/living-docs/enterprise/history-analyzer.js +321 -0
  42. package/dist/src/core/living-docs/enterprise/history-analyzer.js.map +1 -0
  43. package/dist/src/core/living-docs/enterprise/index.d.ts +18 -0
  44. package/dist/src/core/living-docs/enterprise/index.d.ts.map +1 -0
  45. package/dist/src/core/living-docs/enterprise/index.js +14 -0
  46. package/dist/src/core/living-docs/enterprise/index.js.map +1 -0
  47. package/dist/src/core/living-docs/enterprise/relationship-mapper.d.ts +58 -0
  48. package/dist/src/core/living-docs/enterprise/relationship-mapper.d.ts.map +1 -0
  49. package/dist/src/core/living-docs/enterprise/relationship-mapper.js +227 -0
  50. package/dist/src/core/living-docs/enterprise/relationship-mapper.js.map +1 -0
  51. package/dist/src/core/living-docs/enterprise/spec-loader.d.ts +161 -0
  52. package/dist/src/core/living-docs/enterprise/spec-loader.d.ts.map +1 -0
  53. package/dist/src/core/living-docs/enterprise/spec-loader.js +470 -0
  54. package/dist/src/core/living-docs/enterprise/spec-loader.js.map +1 -0
  55. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts +31 -1
  56. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts.map +1 -1
  57. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js +626 -14
  58. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js.map +1 -1
  59. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +8 -0
  60. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -1
  61. package/dist/src/core/living-docs/intelligent-analyzer/index.js +87 -4
  62. package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -1
  63. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +3 -1
  64. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -1
  65. package/dist/src/core/living-docs/operations/index.d.ts +8 -0
  66. package/dist/src/core/living-docs/operations/index.d.ts.map +1 -0
  67. package/dist/src/core/living-docs/operations/index.js +7 -0
  68. package/dist/src/core/living-docs/operations/index.js.map +1 -0
  69. package/dist/src/core/living-docs/operations/ops-generator.d.ts +53 -0
  70. package/dist/src/core/living-docs/operations/ops-generator.d.ts.map +1 -0
  71. package/dist/src/core/living-docs/operations/ops-generator.js +462 -0
  72. package/dist/src/core/living-docs/operations/ops-generator.js.map +1 -0
  73. package/package.json +1 -1
  74. package/plugins/specweave/commands/living-docs.md +168 -39
  75. package/plugins/specweave-github/lib/github-feature-sync.js +1 -1
  76. package/plugins/specweave-github/lib/github-feature-sync.ts +3 -1
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Enterprise Knowledge Base Generator
3
+ *
4
+ * Main orchestrator that generates comprehensive enterprise documentation:
5
+ * - Company history and timeline
6
+ * - Feature catalog with ownership
7
+ * - Team directory with expertise
8
+ * - Cross-references and relationships
9
+ * - Mermaid diagrams for visualization
10
+ */
11
+ import { Logger } from '../../../utils/logger.js';
12
+ import type { RepoAnalysis, LLMProvider, ProgressCallback } from '../intelligent-analyzer/types.js';
13
+ import type { OrganizationSynthesisResult } from '../intelligent-analyzer/organization-synthesizer.js';
14
+ export interface EnterpriseGeneratorOptions {
15
+ projectPath: string;
16
+ projectName?: string;
17
+ logger?: Logger;
18
+ llmProvider?: LLMProvider;
19
+ repoAnalyses?: Map<string, RepoAnalysis>;
20
+ orgResult?: OrganizationSynthesisResult;
21
+ teams?: Array<{
22
+ name: string;
23
+ repos: string[];
24
+ members?: string[];
25
+ }>;
26
+ }
27
+ export interface EnterpriseGenerationResult {
28
+ filesCreated: string[];
29
+ savedFiles: string[];
30
+ metrics: EnterpriseMetrics;
31
+ }
32
+ export interface EnterpriseMetrics {
33
+ totalFeatures: number;
34
+ activeFeatures: number;
35
+ completedFeatures: number;
36
+ totalUserStories: number;
37
+ totalTeams: number;
38
+ totalModules: number;
39
+ overallCompletion: number;
40
+ timelineEvents: number;
41
+ relationships: number;
42
+ }
43
+ /**
44
+ * Enterprise documentation generator
45
+ */
46
+ export declare class EnterpriseGenerator {
47
+ private projectPath;
48
+ private logger;
49
+ private llmProvider?;
50
+ private repoAnalyses?;
51
+ private orgResult?;
52
+ private enterprisePath;
53
+ constructor(options: EnterpriseGeneratorOptions);
54
+ /**
55
+ * Generate all enterprise documentation
56
+ */
57
+ generate(onProgress?: ProgressCallback): Promise<EnterpriseGenerationResult>;
58
+ /**
59
+ * Generate COMPANY-HISTORY.md with timeline
60
+ */
61
+ private generateHistory;
62
+ /**
63
+ * Generate FEATURE-CATALOG.md
64
+ */
65
+ private generateFeatureCatalog;
66
+ /**
67
+ * Generate TEAM-DIRECTORY.md
68
+ */
69
+ private generateTeamDirectory;
70
+ /**
71
+ * Generate ARCHITECTURE-MAP.md with C4 diagrams
72
+ */
73
+ private generateArchitectureMap;
74
+ /**
75
+ * Generate relationship documentation files
76
+ */
77
+ private generateRelationshipDocs;
78
+ /**
79
+ * Get project name from config or folder
80
+ */
81
+ private getProjectName;
82
+ private getStatusEmoji;
83
+ private getEventEmoji;
84
+ }
85
+ //# sourceMappingURL=enterprise-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enterprise-generator.d.ts","sourceRoot":"","sources":["../../../../../src/core/living-docs/enterprise/enterprise-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,MAAM,EAAiB,MAAM,0BAA0B,CAAC;AAIjE,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAgB,MAAM,kCAAkC,CAAC;AAClH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qDAAqD,CAAC;AAEvG,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACzC,SAAS,CAAC,EAAE,2BAA2B,CAAC;IACxC,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,0BAA0B;IACzC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,YAAY,CAAC,CAA4B;IACjD,OAAO,CAAC,SAAS,CAAC,CAA8B;IAChD,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,EAAE,0BAA0B;IAS/C;;OAEG;IACG,QAAQ,CACZ,UAAU,CAAC,EAAE,gBAAgB,GAC5B,OAAO,CAAC,0BAA0B,CAAC;IAuGtC;;OAEG;YACW,eAAe;IA+D7B;;OAEG;YACW,sBAAsB;IA0FpC;;OAEG;YACW,qBAAqB;IAyGnC;;OAEG;YACW,uBAAuB;IA4FrC;;OAEG;YACW,wBAAwB;IAyHtC;;OAEG;IACH,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,aAAa;CAYtB"}
@@ -0,0 +1,556 @@
1
+ /**
2
+ * Enterprise Knowledge Base Generator
3
+ *
4
+ * Main orchestrator that generates comprehensive enterprise documentation:
5
+ * - Company history and timeline
6
+ * - Feature catalog with ownership
7
+ * - Team directory with expertise
8
+ * - Cross-references and relationships
9
+ * - Mermaid diagrams for visualization
10
+ */
11
+ import * as fs from 'fs';
12
+ import * as path from 'path';
13
+ import { consoleLogger } from '../../../utils/logger.js';
14
+ import { EnhancedSpecLoader } from './spec-loader.js';
15
+ import { HistoryAnalyzer } from './history-analyzer.js';
16
+ import { RelationshipMapper } from './relationship-mapper.js';
17
+ /**
18
+ * Enterprise documentation generator
19
+ */
20
+ export class EnterpriseGenerator {
21
+ constructor(options) {
22
+ this.projectPath = options.projectPath;
23
+ this.logger = options.logger ?? consoleLogger;
24
+ this.llmProvider = options.llmProvider;
25
+ this.repoAnalyses = options.repoAnalyses;
26
+ this.orgResult = options.orgResult;
27
+ this.enterprisePath = path.join(this.projectPath, '.specweave/docs/internal/enterprise');
28
+ }
29
+ /**
30
+ * Generate all enterprise documentation
31
+ */
32
+ async generate(onProgress) {
33
+ const progress = onProgress ?? (() => { });
34
+ const filesCreated = [];
35
+ this.logger.info('ENTERPRISE KNOWLEDGE BASE GENERATION');
36
+ this.logger.info('═══════════════════════════════════════════════════════════');
37
+ // Ensure enterprise directory exists
38
+ fs.mkdirSync(this.enterprisePath, { recursive: true });
39
+ // Phase 1: Load all specs
40
+ progress('enterprise', 0, 100, 'Loading specifications');
41
+ this.logger.info('');
42
+ this.logger.info('📚 Loading all specifications...');
43
+ const specLoader = new EnhancedSpecLoader({
44
+ projectPath: this.projectPath,
45
+ logger: this.logger,
46
+ includeArchived: true,
47
+ });
48
+ const specsCatalog = await specLoader.loadAllSpecs();
49
+ this.logger.info(` Loaded ${specsCatalog.totalFeatures} features, ${specsCatalog.totalUserStories} user stories`);
50
+ // Phase 2: Analyze history
51
+ progress('enterprise', 20, 100, 'Analyzing project history');
52
+ this.logger.info('');
53
+ this.logger.info('📅 Analyzing project history...');
54
+ const historyAnalyzer = new HistoryAnalyzer({
55
+ projectPath: this.projectPath,
56
+ logger: this.logger,
57
+ });
58
+ const timeline = await historyAnalyzer.analyze(specsCatalog);
59
+ this.logger.info(` Found ${timeline.events.length} timeline events`);
60
+ // Phase 3: Map relationships
61
+ progress('enterprise', 40, 100, 'Mapping relationships');
62
+ this.logger.info('');
63
+ this.logger.info('🔗 Mapping relationships...');
64
+ const relationshipMapper = new RelationshipMapper({
65
+ projectPath: this.projectPath,
66
+ logger: this.logger,
67
+ repoAnalyses: this.repoAnalyses,
68
+ });
69
+ const relationships = await relationshipMapper.map(specsCatalog, this.orgResult);
70
+ this.logger.info(` Mapped ${relationships.totalRelationships} relationships`);
71
+ // Phase 4: Generate documentation files
72
+ progress('enterprise', 60, 100, 'Generating documentation');
73
+ this.logger.info('');
74
+ this.logger.info('📝 Generating enterprise documentation...');
75
+ // Generate COMPANY-HISTORY.md
76
+ const historyFile = await this.generateHistory(timeline, specsCatalog);
77
+ filesCreated.push(historyFile);
78
+ this.logger.info(' ✓ COMPANY-HISTORY.md');
79
+ // Generate FEATURE-CATALOG.md
80
+ const catalogFile = await this.generateFeatureCatalog(specsCatalog, relationships);
81
+ filesCreated.push(catalogFile);
82
+ this.logger.info(' ✓ FEATURE-CATALOG.md');
83
+ // Generate TEAM-DIRECTORY.md
84
+ const teamFile = await this.generateTeamDirectory(specsCatalog, relationships);
85
+ filesCreated.push(teamFile);
86
+ this.logger.info(' ✓ TEAM-DIRECTORY.md');
87
+ // Generate ARCHITECTURE-MAP.md with Mermaid
88
+ const archFile = await this.generateArchitectureMap(specsCatalog, relationships);
89
+ filesCreated.push(archFile);
90
+ this.logger.info(' ✓ ARCHITECTURE-MAP.md');
91
+ // Generate relationships folder
92
+ progress('enterprise', 80, 100, 'Generating relationship docs');
93
+ this.logger.info('');
94
+ this.logger.info('🔗 Generating relationship documentation...');
95
+ const relFiles = await this.generateRelationshipDocs(relationships, specsCatalog);
96
+ filesCreated.push(...relFiles);
97
+ this.logger.info(` ✓ ${relFiles.length} relationship files`);
98
+ progress('enterprise', 100, 100, 'Complete');
99
+ const metrics = {
100
+ totalFeatures: specsCatalog.totalFeatures,
101
+ activeFeatures: specsCatalog.activeFeatures,
102
+ completedFeatures: specsCatalog.completedFeatures,
103
+ totalUserStories: specsCatalog.totalUserStories,
104
+ totalTeams: this.orgResult?.enhancedTeams.length ?? 0,
105
+ totalModules: this.repoAnalyses?.size ?? 0,
106
+ overallCompletion: specsCatalog.overallCompletion,
107
+ timelineEvents: timeline.events.length,
108
+ relationships: relationships.totalRelationships,
109
+ };
110
+ this.logger.info('');
111
+ this.logger.info('═══════════════════════════════════════════════════════════');
112
+ this.logger.info(`✅ Enterprise documentation complete: ${filesCreated.length} files`);
113
+ return { filesCreated, savedFiles: filesCreated, metrics };
114
+ }
115
+ /**
116
+ * Generate COMPANY-HISTORY.md with timeline
117
+ */
118
+ async generateHistory(timeline, catalog) {
119
+ const lines = [
120
+ '# Project History & Timeline',
121
+ '',
122
+ `*Generated: ${new Date().toLocaleDateString()} | Project: ${timeline.projectName}*`,
123
+ '',
124
+ '## Overview',
125
+ '',
126
+ `- **Started**: ${timeline.startDate}`,
127
+ `- **Current Version**: ${timeline.currentVersion}`,
128
+ `- **Total Features**: ${catalog.totalFeatures}`,
129
+ `- **Completion Rate**: ${catalog.overallCompletion}%`,
130
+ '',
131
+ '## Timeline',
132
+ '',
133
+ '```mermaid',
134
+ 'timeline',
135
+ ` title ${timeline.projectName} Evolution`,
136
+ ];
137
+ // Group events by month
138
+ const eventsByMonth = new Map();
139
+ for (const event of timeline.events.slice(-50)) { // Last 50 events
140
+ const month = event.date.substring(0, 7); // YYYY-MM
141
+ if (!eventsByMonth.has(month)) {
142
+ eventsByMonth.set(month, []);
143
+ }
144
+ eventsByMonth.get(month).push(event);
145
+ }
146
+ for (const [month, events] of eventsByMonth) {
147
+ const [year, monthNum] = month.split('-');
148
+ const monthName = new Date(parseInt(year), parseInt(monthNum) - 1).toLocaleString('default', { month: 'short' });
149
+ lines.push(` section ${monthName} ${year}`);
150
+ for (const event of events.slice(0, 3)) { // Max 3 per month
151
+ const escapedTitle = event.title.replace(/:/g, ' ').substring(0, 40);
152
+ lines.push(` ${escapedTitle}`);
153
+ }
154
+ }
155
+ lines.push('```', '');
156
+ // Detailed event list
157
+ lines.push('## Detailed Events', '');
158
+ lines.push('| Date | Type | Event | Related |');
159
+ lines.push('|------|------|-------|---------|');
160
+ for (const event of timeline.events.slice(-100)) { // Last 100
161
+ const typeEmoji = this.getEventEmoji(event.type);
162
+ const related = event.relatedEntities.slice(0, 2).join(', ');
163
+ lines.push(`| ${event.date} | ${typeEmoji} ${event.type} | ${event.title} | ${related} |`);
164
+ }
165
+ lines.push('', '---', `*Last updated: ${new Date().toISOString()}*`);
166
+ const filePath = path.join(this.enterprisePath, 'COMPANY-HISTORY.md');
167
+ fs.writeFileSync(filePath, lines.join('\n'));
168
+ return filePath;
169
+ }
170
+ /**
171
+ * Generate FEATURE-CATALOG.md
172
+ */
173
+ async generateFeatureCatalog(catalog, relationships) {
174
+ const lines = [
175
+ '# Feature Catalog',
176
+ '',
177
+ `*Generated: ${new Date().toLocaleDateString()} | Total: ${catalog.totalFeatures} features*`,
178
+ '',
179
+ '## Summary',
180
+ '',
181
+ '| Status | Count | Completion |',
182
+ '|--------|-------|------------|',
183
+ `| 🟢 Active | ${catalog.activeFeatures} | - |`,
184
+ `| ✅ Completed | ${catalog.completedFeatures} | 100% |`,
185
+ `| 📦 Archived | ${catalog.archivedFeatures} | - |`,
186
+ '',
187
+ `**Overall Completion**: ${catalog.overallCompletion}% (${catalog.completedACs}/${catalog.totalACs} ACs)`,
188
+ '',
189
+ '## Feature Status Diagram',
190
+ '',
191
+ '```mermaid',
192
+ 'pie showData',
193
+ ' title Feature Status Distribution',
194
+ ` "Active" : ${catalog.activeFeatures}`,
195
+ ` "Completed" : ${catalog.completedFeatures}`,
196
+ ` "Archived" : ${catalog.archivedFeatures}`,
197
+ '```',
198
+ '',
199
+ ];
200
+ // Features by project
201
+ if (catalog.byProject.size > 1) {
202
+ lines.push('## By Project', '');
203
+ for (const [project, features] of catalog.byProject) {
204
+ lines.push(`### ${project}`, '');
205
+ lines.push('| Feature | Status | User Stories | Completion | Owner |');
206
+ lines.push('|---------|--------|--------------|------------|-------|');
207
+ for (const f of features.slice(0, 20)) {
208
+ const owner = relationships.featureToTeam.get(f.featureId) || '-';
209
+ const status = this.getStatusEmoji(f.status);
210
+ lines.push(`| [${f.featureId}](#${f.featureId.toLowerCase()}) | ${status} | ${f.userStories.length} | ${f.completionPercentage}% | ${owner} |`);
211
+ }
212
+ if (features.length > 20) {
213
+ lines.push(`| ... | | | | *${features.length - 20} more* |`);
214
+ }
215
+ lines.push('');
216
+ }
217
+ }
218
+ // All features detail
219
+ lines.push('## Feature Details', '');
220
+ for (const feature of catalog.features.slice(0, 50)) { // Limit for file size
221
+ lines.push(`### ${feature.featureId}: ${feature.featureName}`, '');
222
+ lines.push(`**Status**: ${this.getStatusEmoji(feature.status)} ${feature.status}`);
223
+ lines.push(`**Completion**: ${feature.completionPercentage}%`);
224
+ if (feature.project) {
225
+ lines.push(`**Project**: ${feature.project}`);
226
+ }
227
+ if (feature.relatedIncrements.length > 0) {
228
+ lines.push(`**Related Increments**: ${feature.relatedIncrements.slice(0, 5).join(', ')}`);
229
+ }
230
+ lines.push('', '**User Stories**:', '');
231
+ for (const us of feature.userStories.slice(0, 10)) {
232
+ const usStatus = this.getStatusEmoji(us.status);
233
+ const acComplete = us.acceptanceCriteria.filter(ac => ac.completed).length;
234
+ lines.push(`- ${usStatus} **${us.id}**: ${us.title} (${acComplete}/${us.acceptanceCriteria.length} ACs)`);
235
+ }
236
+ if (feature.userStories.length > 10) {
237
+ lines.push(`- *... ${feature.userStories.length - 10} more user stories*`);
238
+ }
239
+ lines.push('');
240
+ }
241
+ if (catalog.features.length > 50) {
242
+ lines.push(`*Showing 50 of ${catalog.features.length} features. See individual project folders for complete list.*`);
243
+ }
244
+ lines.push('', '---', `*Last updated: ${new Date().toISOString()}*`);
245
+ const filePath = path.join(this.enterprisePath, 'FEATURE-CATALOG.md');
246
+ fs.writeFileSync(filePath, lines.join('\n'));
247
+ return filePath;
248
+ }
249
+ /**
250
+ * Generate TEAM-DIRECTORY.md
251
+ */
252
+ async generateTeamDirectory(catalog, relationships) {
253
+ const teams = this.orgResult?.enhancedTeams ?? [];
254
+ const lines = [
255
+ '# Team Directory',
256
+ '',
257
+ `*Generated: ${new Date().toLocaleDateString()} | Total: ${teams.length} teams*`,
258
+ '',
259
+ '## Organization Chart',
260
+ '',
261
+ '```mermaid',
262
+ 'graph TD',
263
+ ];
264
+ // Build org chart
265
+ if (teams.length > 0) {
266
+ lines.push(' org[Organization]');
267
+ for (const team of teams) {
268
+ const teamId = team.name.replace(/\s+/g, '_').replace(/[^a-zA-Z0-9_]/g, '');
269
+ lines.push(` org --> ${teamId}["${team.name}"]`);
270
+ }
271
+ }
272
+ else {
273
+ lines.push(' org[No teams detected]');
274
+ }
275
+ lines.push('```', '');
276
+ // Team summary table
277
+ lines.push('## Teams Overview', '');
278
+ lines.push('| Team | Modules | Features | Tech Stack |');
279
+ lines.push('|------|---------|----------|------------|');
280
+ for (const team of teams) {
281
+ const moduleCount = team.repos.length;
282
+ const featureCount = relationships.teamToFeatures.get(team.name)?.length ?? 0;
283
+ const techStack = team.techStack.slice(0, 3).join(', ');
284
+ lines.push(`| [${team.name}](#${team.name.toLowerCase().replace(/\s+/g, '-')}) | ${moduleCount} | ${featureCount} | ${techStack} |`);
285
+ }
286
+ lines.push('');
287
+ // Team details
288
+ lines.push('## Team Details', '');
289
+ for (const team of teams) {
290
+ lines.push(`### ${team.name}`, '');
291
+ lines.push(team.description, '');
292
+ if (team.responsibilities.length > 0) {
293
+ lines.push('**Responsibilities**:', '');
294
+ for (const r of team.responsibilities) {
295
+ lines.push(`- ${r}`);
296
+ }
297
+ lines.push('');
298
+ }
299
+ if (team.domainExpertise.length > 0) {
300
+ lines.push('**Domain Expertise**:', '');
301
+ for (const e of team.domainExpertise) {
302
+ lines.push(`- ${e}`);
303
+ }
304
+ lines.push('');
305
+ }
306
+ if (team.techStack.length > 0) {
307
+ lines.push(`**Tech Stack**: ${team.techStack.join(', ')}`, '');
308
+ }
309
+ if (team.repos.length > 0) {
310
+ lines.push('**Owned Modules**:', '');
311
+ for (const repo of team.repos) {
312
+ lines.push(`- [${repo}](../modules/${repo}.md)`);
313
+ }
314
+ lines.push('');
315
+ }
316
+ const features = relationships.teamToFeatures.get(team.name) ?? [];
317
+ if (features.length > 0) {
318
+ lines.push('**Owned Features**:', '');
319
+ for (const f of features.slice(0, 10)) {
320
+ lines.push(`- ${f}`);
321
+ }
322
+ if (features.length > 10) {
323
+ lines.push(`- *... ${features.length - 10} more*`);
324
+ }
325
+ lines.push('');
326
+ }
327
+ if (team.externalUrl) {
328
+ lines.push(`**External Link**: [View in ${team.externalProvider}](${team.externalUrl})`, '');
329
+ }
330
+ lines.push('---', '');
331
+ }
332
+ lines.push(`*Last updated: ${new Date().toISOString()}*`);
333
+ const filePath = path.join(this.enterprisePath, 'TEAM-DIRECTORY.md');
334
+ fs.writeFileSync(filePath, lines.join('\n'));
335
+ return filePath;
336
+ }
337
+ /**
338
+ * Generate ARCHITECTURE-MAP.md with C4 diagrams
339
+ */
340
+ async generateArchitectureMap(catalog, relationships) {
341
+ const lines = [
342
+ '# Architecture Map',
343
+ '',
344
+ `*Generated: ${new Date().toLocaleDateString()}*`,
345
+ '',
346
+ '## System Context',
347
+ '',
348
+ '```mermaid',
349
+ 'C4Context',
350
+ ' title System Context Diagram',
351
+ '',
352
+ ];
353
+ // Add main system
354
+ const projectName = this.getProjectName();
355
+ lines.push(` System(main, "${projectName}", "Main application")`);
356
+ // Add external systems from external refs
357
+ const externalSystems = new Set();
358
+ for (const feature of catalog.features) {
359
+ for (const ref of feature.externalRefs) {
360
+ externalSystems.add(ref.provider);
361
+ }
362
+ }
363
+ for (const ext of externalSystems) {
364
+ const label = ext === 'github' ? 'GitHub' : ext === 'jira' ? 'JIRA' : 'Azure DevOps';
365
+ lines.push(` System_Ext(${ext}, "${label}", "External tracking")`);
366
+ }
367
+ // Add relationships
368
+ for (const ext of externalSystems) {
369
+ lines.push(` Rel(main, ${ext}, "Syncs with")`);
370
+ }
371
+ lines.push('```', '');
372
+ // Module dependency diagram
373
+ lines.push('## Module Dependencies', '');
374
+ lines.push('```mermaid', 'graph LR');
375
+ if (this.repoAnalyses && this.repoAnalyses.size > 0) {
376
+ const modules = Array.from(this.repoAnalyses.keys()).slice(0, 20);
377
+ for (const mod of modules) {
378
+ const deps = relationships.moduleDependencies.get(mod) ?? [];
379
+ if (deps.length > 0) {
380
+ for (const dep of deps.slice(0, 5)) {
381
+ if (modules.includes(dep)) {
382
+ lines.push(` ${mod.replace(/[^a-zA-Z0-9]/g, '_')} --> ${dep.replace(/[^a-zA-Z0-9]/g, '_')}`);
383
+ }
384
+ }
385
+ }
386
+ }
387
+ }
388
+ else {
389
+ lines.push(' no_modules[No modules analyzed]');
390
+ }
391
+ lines.push('```', '');
392
+ // Feature hierarchy
393
+ lines.push('## Feature Hierarchy', '');
394
+ lines.push('```mermaid', 'graph TD');
395
+ const activeFeatures = catalog.byStatus.get('active') ?? [];
396
+ for (const feature of activeFeatures.slice(0, 15)) {
397
+ const fId = feature.featureId.replace(/[^a-zA-Z0-9]/g, '_');
398
+ lines.push(` ${fId}["${feature.featureId}<br/>${feature.completionPercentage}%"]`);
399
+ for (const us of feature.userStories.slice(0, 3)) {
400
+ const usId = us.id.replace(/[^a-zA-Z0-9]/g, '_');
401
+ const acComplete = us.acceptanceCriteria.filter(ac => ac.completed).length;
402
+ const acTotal = us.acceptanceCriteria.length;
403
+ lines.push(` ${fId} --> ${usId}["${us.id}<br/>${acComplete}/${acTotal}"]`);
404
+ }
405
+ if (feature.userStories.length > 3) {
406
+ lines.push(` ${fId} --> ${fId}_more["...${feature.userStories.length - 3} more"]`);
407
+ }
408
+ }
409
+ lines.push('```', '');
410
+ lines.push('---', `*Last updated: ${new Date().toISOString()}*`);
411
+ const filePath = path.join(this.enterprisePath, 'ARCHITECTURE-MAP.md');
412
+ fs.writeFileSync(filePath, lines.join('\n'));
413
+ return filePath;
414
+ }
415
+ /**
416
+ * Generate relationship documentation files
417
+ */
418
+ async generateRelationshipDocs(relationships, catalog) {
419
+ const filesCreated = [];
420
+ const relPath = path.join(this.projectPath, '.specweave/docs/internal/relationships');
421
+ fs.mkdirSync(relPath, { recursive: true });
422
+ // FEATURE-TO-CODE.md
423
+ const ftcLines = [
424
+ '# Feature to Code Mapping',
425
+ '',
426
+ `*Generated: ${new Date().toLocaleDateString()}*`,
427
+ '',
428
+ '## Mappings',
429
+ '',
430
+ '| Feature | Files | Coverage |',
431
+ '|---------|-------|----------|',
432
+ ];
433
+ for (const [featureId, files] of relationships.featureToCode) {
434
+ const coverage = files.length > 0 ? '✅' : '❌';
435
+ ftcLines.push(`| ${featureId} | ${files.length} | ${coverage} |`);
436
+ }
437
+ const ftcPath = path.join(relPath, 'FEATURE-TO-CODE.md');
438
+ fs.writeFileSync(ftcPath, ftcLines.join('\n'));
439
+ filesCreated.push(ftcPath);
440
+ // TEAM-TO-FEATURES.md
441
+ const ttfLines = [
442
+ '# Team to Features Mapping',
443
+ '',
444
+ `*Generated: ${new Date().toLocaleDateString()}*`,
445
+ '',
446
+ ];
447
+ for (const [team, features] of relationships.teamToFeatures) {
448
+ ttfLines.push(`## ${team}`, '');
449
+ for (const f of features) {
450
+ ttfLines.push(`- ${f}`);
451
+ }
452
+ ttfLines.push('');
453
+ }
454
+ const ttfPath = path.join(relPath, 'TEAM-TO-FEATURES.md');
455
+ fs.writeFileSync(ttfPath, ttfLines.join('\n'));
456
+ filesCreated.push(ttfPath);
457
+ // MODULE-DEPENDENCIES.md
458
+ const mdLines = [
459
+ '# Module Dependencies',
460
+ '',
461
+ `*Generated: ${new Date().toLocaleDateString()}*`,
462
+ '',
463
+ '## Dependency Matrix',
464
+ '',
465
+ ];
466
+ for (const [mod, deps] of relationships.moduleDependencies) {
467
+ if (deps.length > 0) {
468
+ mdLines.push(`### ${mod}`, '');
469
+ mdLines.push('**Depends on**:', '');
470
+ for (const dep of deps) {
471
+ mdLines.push(`- ${dep}`);
472
+ }
473
+ mdLines.push('');
474
+ }
475
+ }
476
+ const mdPath = path.join(relPath, 'MODULE-DEPENDENCIES.md');
477
+ fs.writeFileSync(mdPath, mdLines.join('\n'));
478
+ filesCreated.push(mdPath);
479
+ // EXTERNAL-REFS.md
480
+ const erLines = [
481
+ '# External References',
482
+ '',
483
+ `*Generated: ${new Date().toLocaleDateString()}*`,
484
+ '',
485
+ '## GitHub Issues',
486
+ '',
487
+ '| Feature | Issue | Status |',
488
+ '|---------|-------|--------|',
489
+ ];
490
+ for (const feature of catalog.features) {
491
+ for (const ref of feature.externalRefs) {
492
+ if (ref.provider === 'github') {
493
+ erLines.push(`| ${feature.featureId} | #${ref.id} | ${ref.status || '-'} |`);
494
+ }
495
+ }
496
+ }
497
+ erLines.push('', '## JIRA Issues', '', '| Feature | Key | Status |', '|---------|-----|--------|');
498
+ for (const feature of catalog.features) {
499
+ for (const ref of feature.externalRefs) {
500
+ if (ref.provider === 'jira') {
501
+ erLines.push(`| ${feature.featureId} | ${ref.id} | ${ref.status || '-'} |`);
502
+ }
503
+ }
504
+ }
505
+ erLines.push('', '## Azure DevOps', '', '| Feature | Work Item | Status |', '|---------|-----------|--------|');
506
+ for (const feature of catalog.features) {
507
+ for (const ref of feature.externalRefs) {
508
+ if (ref.provider === 'ado') {
509
+ erLines.push(`| ${feature.featureId} | ${ref.id} | ${ref.status || '-'} |`);
510
+ }
511
+ }
512
+ }
513
+ const erPath = path.join(relPath, 'EXTERNAL-REFS.md');
514
+ fs.writeFileSync(erPath, erLines.join('\n'));
515
+ filesCreated.push(erPath);
516
+ return filesCreated;
517
+ }
518
+ /**
519
+ * Get project name from config or folder
520
+ */
521
+ getProjectName() {
522
+ const configPath = path.join(this.projectPath, '.specweave/config.json');
523
+ if (fs.existsSync(configPath)) {
524
+ try {
525
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
526
+ return config.project?.name || config.name || path.basename(this.projectPath);
527
+ }
528
+ catch { /* ignore */ }
529
+ }
530
+ return path.basename(this.projectPath);
531
+ }
532
+ getStatusEmoji(status) {
533
+ switch (status) {
534
+ case 'active': return '🟢';
535
+ case 'completed': return '✅';
536
+ case 'archived': return '📦';
537
+ case 'in_progress': return '🔄';
538
+ case 'draft': return '📝';
539
+ case 'ready': return '🎯';
540
+ default: return '⚪';
541
+ }
542
+ }
543
+ getEventEmoji(type) {
544
+ switch (type) {
545
+ case 'feature_started': return '🚀';
546
+ case 'feature_completed': return '✅';
547
+ case 'release': return '📦';
548
+ case 'team_change': return '👥';
549
+ case 'incident': return '🚨';
550
+ case 'increment_started': return '📋';
551
+ case 'increment_completed': return '🎉';
552
+ default: return '📌';
553
+ }
554
+ }
555
+ }
556
+ //# sourceMappingURL=enterprise-generator.js.map