specweave 0.28.13 → 0.28.14

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 (65) hide show
  1. package/dist/src/cli/commands/archive.d.ts +0 -1
  2. package/dist/src/cli/commands/archive.d.ts.map +1 -1
  3. package/dist/src/cli/commands/archive.js +1 -4
  4. package/dist/src/cli/commands/archive.js.map +1 -1
  5. package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
  6. package/dist/src/cli/helpers/init/external-import.js +83 -10
  7. package/dist/src/cli/helpers/init/external-import.js.map +1 -1
  8. package/dist/src/core/feature-deleter/validator.d.ts +1 -0
  9. package/dist/src/core/feature-deleter/validator.d.ts.map +1 -1
  10. package/dist/src/core/feature-deleter/validator.js +8 -10
  11. package/dist/src/core/feature-deleter/validator.js.map +1 -1
  12. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  13. package/dist/src/core/increment/increment-archiver.js +12 -5
  14. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  15. package/dist/src/core/living-docs/feature-archiver.d.ts +25 -3
  16. package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
  17. package/dist/src/core/living-docs/feature-archiver.js +131 -129
  18. package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
  19. package/dist/src/core/living-docs/feature-consistency-validator.d.ts +23 -22
  20. package/dist/src/core/living-docs/feature-consistency-validator.d.ts.map +1 -1
  21. package/dist/src/core/living-docs/feature-consistency-validator.js +68 -150
  22. package/dist/src/core/living-docs/feature-consistency-validator.js.map +1 -1
  23. package/dist/src/core/living-docs/feature-id-manager.d.ts +5 -1
  24. package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
  25. package/dist/src/core/living-docs/feature-id-manager.js +43 -23
  26. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  27. package/dist/src/core/living-docs/hierarchy-mapper.d.ts +21 -12
  28. package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -1
  29. package/dist/src/core/living-docs/hierarchy-mapper.js +89 -70
  30. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
  31. package/dist/src/core/living-docs/living-docs-sync.d.ts +10 -11
  32. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  33. package/dist/src/core/living-docs/living-docs-sync.js +24 -56
  34. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  35. package/dist/src/core/repo-structure/repo-bulk-discovery.d.ts +1 -1
  36. package/dist/src/core/repo-structure/repo-bulk-discovery.d.ts.map +1 -1
  37. package/dist/src/core/repo-structure/repo-bulk-discovery.js +168 -126
  38. package/dist/src/core/repo-structure/repo-bulk-discovery.js.map +1 -1
  39. package/dist/src/core/spec-detector.js +2 -2
  40. package/dist/src/core/spec-detector.js.map +1 -1
  41. package/dist/src/importers/duplicate-detector.d.ts +6 -0
  42. package/dist/src/importers/duplicate-detector.d.ts.map +1 -1
  43. package/dist/src/importers/duplicate-detector.js +8 -2
  44. package/dist/src/importers/duplicate-detector.js.map +1 -1
  45. package/dist/src/importers/external-importer.d.ts +6 -0
  46. package/dist/src/importers/external-importer.d.ts.map +1 -1
  47. package/dist/src/importers/import-coordinator.d.ts +38 -2
  48. package/dist/src/importers/import-coordinator.d.ts.map +1 -1
  49. package/dist/src/importers/import-coordinator.js +142 -5
  50. package/dist/src/importers/import-coordinator.js.map +1 -1
  51. package/dist/src/importers/item-converter.d.ts +39 -1
  52. package/dist/src/importers/item-converter.d.ts.map +1 -1
  53. package/dist/src/importers/item-converter.js +193 -24
  54. package/dist/src/importers/item-converter.js.map +1 -1
  55. package/dist/src/living-docs/fs-id-allocator.d.ts +8 -2
  56. package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -1
  57. package/dist/src/living-docs/fs-id-allocator.js +18 -10
  58. package/dist/src/living-docs/fs-id-allocator.js.map +1 -1
  59. package/dist/src/utils/project-detection.d.ts +13 -10
  60. package/dist/src/utils/project-detection.d.ts.map +1 -1
  61. package/dist/src/utils/project-detection.js +26 -11
  62. package/dist/src/utils/project-detection.js.map +1 -1
  63. package/package.json +1 -1
  64. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +6 -0
  65. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +9 -0
@@ -15,7 +15,10 @@ import { RateLimiter } from './rate-limiter.js';
15
15
  export class ImportCoordinator {
16
16
  constructor(config) {
17
17
  this.importers = new Map();
18
+ /** Multi-repo importers keyed by "github:owner/repo" */
19
+ this.githubRepoImporters = new Map();
18
20
  this.rateLimiter = null;
21
+ this.importStartTime = 0;
19
22
  this.config = {
20
23
  enableSyncMetadata: true,
21
24
  enableRateLimiting: true,
@@ -33,8 +36,27 @@ export class ImportCoordinator {
33
36
  * Initialize importers based on configuration
34
37
  */
35
38
  initializeImporters() {
36
- // GitHub importer
37
- if (this.config.github) {
39
+ // Multi-repo GitHub support (preferred over single repo)
40
+ if (this.config.githubRepositories && this.config.githubRepositories.length > 0) {
41
+ const token = this.config.githubToken || this.config.github?.token || process.env.GITHUB_TOKEN;
42
+ for (const repo of this.config.githubRepositories) {
43
+ try {
44
+ const importer = new GitHubImporter(repo.owner, repo.repo, token);
45
+ const key = `github:${repo.owner}/${repo.repo}`;
46
+ this.githubRepoImporters.set(key, importer);
47
+ }
48
+ catch (error) {
49
+ console.warn(`Failed to initialize GitHub importer for ${repo.owner}/${repo.repo}: ${error.message}`);
50
+ }
51
+ }
52
+ // If we have multi-repo, don't create single repo importer
53
+ if (this.githubRepoImporters.size > 0) {
54
+ // Mark that we have GitHub configured (for platform detection)
55
+ // We'll handle multi-repo in importAll()
56
+ }
57
+ }
58
+ else if (this.config.github) {
59
+ // Single repo GitHub importer (backwards compatible)
38
60
  try {
39
61
  const importer = new GitHubImporter(this.config.github.owner, this.config.github.repo, this.config.github.token);
40
62
  this.importers.set('github', importer);
@@ -63,7 +85,7 @@ export class ImportCoordinator {
63
85
  console.warn(`Failed to initialize ADO importer: ${error.message}`);
64
86
  }
65
87
  }
66
- if (this.importers.size === 0) {
88
+ if (this.importers.size === 0 && this.githubRepoImporters.size === 0) {
67
89
  throw new Error('No importers configured. Provide at least one platform configuration.');
68
90
  }
69
91
  }
@@ -71,6 +93,7 @@ export class ImportCoordinator {
71
93
  * Import from all configured platforms
72
94
  */
73
95
  async importAll() {
96
+ this.importStartTime = Date.now();
74
97
  const parallel = this.config.parallel !== false; // Default to true
75
98
  if (parallel) {
76
99
  return this.importParallel();
@@ -83,7 +106,16 @@ export class ImportCoordinator {
83
106
  * Import from platforms in parallel
84
107
  */
85
108
  async importParallel() {
86
- const promises = Array.from(this.importers.entries()).map(([platform, importer]) => this.importFromPlatform(platform, importer));
109
+ const promises = [];
110
+ // Add standard platform importers
111
+ for (const [platform, importer] of this.importers.entries()) {
112
+ promises.push(this.importFromPlatform(platform, importer));
113
+ }
114
+ // Add multi-repo GitHub importers
115
+ for (const [key, importer] of this.githubRepoImporters.entries()) {
116
+ const sourceRepo = key.replace('github:', '');
117
+ promises.push(this.importFromGitHubRepo(importer, sourceRepo));
118
+ }
87
119
  const results = await Promise.allSettled(promises);
88
120
  return this.aggregateResults(results);
89
121
  }
@@ -92,6 +124,7 @@ export class ImportCoordinator {
92
124
  */
93
125
  async importSequential() {
94
126
  const results = [];
127
+ // Standard platform importers
95
128
  for (const [platform, importer] of this.importers.entries()) {
96
129
  try {
97
130
  const result = await this.importFromPlatform(platform, importer);
@@ -104,8 +137,98 @@ export class ImportCoordinator {
104
137
  });
105
138
  }
106
139
  }
140
+ // Multi-repo GitHub importers (sequentially to avoid rate limits)
141
+ for (const [key, importer] of this.githubRepoImporters.entries()) {
142
+ const sourceRepo = key.replace('github:', '');
143
+ try {
144
+ const result = await this.importFromGitHubRepo(importer, sourceRepo);
145
+ results.push({ status: 'fulfilled', value: result });
146
+ }
147
+ catch (error) {
148
+ results.push({
149
+ status: 'rejected',
150
+ reason: error,
151
+ });
152
+ }
153
+ }
107
154
  return this.aggregateResults(results);
108
155
  }
156
+ /**
157
+ * Import from a single GitHub repo with source tagging
158
+ */
159
+ async importFromGitHubRepo(importer, sourceRepo) {
160
+ const errors = [];
161
+ const items = [];
162
+ let totalEstimate;
163
+ try {
164
+ // Use pagination for progress tracking
165
+ for await (const page of importer.paginate(this.config.importConfig)) {
166
+ // Tag each item with source repo
167
+ for (const item of page) {
168
+ item.sourceRepo = sourceRepo;
169
+ }
170
+ items.push(...page);
171
+ // Calculate progress info
172
+ const elapsed = (Date.now() - this.importStartTime) / 1000;
173
+ const rate = elapsed > 0 ? items.length / elapsed : 0;
174
+ const eta = totalEstimate && rate > 0 ? (totalEstimate - items.length) / rate : undefined;
175
+ // Report enhanced progress
176
+ if (this.config.onProgressEnhanced) {
177
+ this.config.onProgressEnhanced({
178
+ platform: 'github',
179
+ current: items.length,
180
+ total: totalEstimate,
181
+ percentage: totalEstimate ? Math.round((items.length / totalEstimate) * 100) : undefined,
182
+ rate: Math.round(rate * 10) / 10,
183
+ eta: eta ? Math.round(eta) : undefined,
184
+ sourceRepo,
185
+ });
186
+ }
187
+ // Legacy progress callback
188
+ if (this.config.onProgress) {
189
+ this.config.onProgress(`github (${sourceRepo})`, items.length, totalEstimate);
190
+ }
191
+ }
192
+ // Update sync metadata if enabled
193
+ if (this.config.enableSyncMetadata && items.length > 0) {
194
+ const metadata = {
195
+ lastImport: new Date().toISOString(),
196
+ lastImportCount: items.length,
197
+ lastSyncResult: errors.length > 0 ? 'partial' : 'success',
198
+ };
199
+ try {
200
+ updateSyncMetadata(this.projectRoot, 'github', metadata);
201
+ }
202
+ catch (error) {
203
+ errors.push(`Failed to update sync metadata: ${error.message}`);
204
+ }
205
+ }
206
+ }
207
+ catch (error) {
208
+ errors.push(error.message || String(error));
209
+ if (this.config.enableSyncMetadata) {
210
+ const metadata = {
211
+ lastImport: new Date().toISOString(),
212
+ lastImportCount: 0,
213
+ lastSyncResult: 'failed',
214
+ };
215
+ try {
216
+ updateSyncMetadata(this.projectRoot, 'github', metadata);
217
+ }
218
+ catch {
219
+ // Ignore
220
+ }
221
+ }
222
+ }
223
+ return {
224
+ count: items.length,
225
+ items,
226
+ errors,
227
+ platform: 'github',
228
+ totalEstimate,
229
+ sourceRepo,
230
+ };
231
+ }
109
232
  /**
110
233
  * Import from a single platform with progress tracking
111
234
  */
@@ -212,13 +335,27 @@ export class ImportCoordinator {
212
335
  * Get list of configured platforms
213
336
  */
214
337
  getConfiguredPlatforms() {
215
- return Array.from(this.importers.keys());
338
+ const platforms = Array.from(this.importers.keys());
339
+ // Add 'github' if multi-repo importers are configured
340
+ if (this.githubRepoImporters.size > 0 && !platforms.includes('github')) {
341
+ platforms.push('github');
342
+ }
343
+ return platforms;
216
344
  }
217
345
  /**
218
346
  * Check if a platform is configured
219
347
  */
220
348
  isPlatformConfigured(platform) {
349
+ if (platform === 'github') {
350
+ return this.importers.has(platform) || this.githubRepoImporters.size > 0;
351
+ }
221
352
  return this.importers.has(platform);
222
353
  }
354
+ /**
355
+ * Get list of configured GitHub repositories (for multi-repo support)
356
+ */
357
+ getConfiguredGitHubRepos() {
358
+ return Array.from(this.githubRepoImporters.keys()).map(key => key.replace('github:', ''));
359
+ }
223
360
  }
224
361
  //# sourceMappingURL=import-coordinator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"import-coordinator.js","sourceRoot":"","sources":["../../../src/importers/import-coordinator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"import-coordinator.js","sourceRoot":"","sources":["../../../src/importers/import-coordinator.ts"],"names":[],"mappings":"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"}
@@ -27,11 +27,14 @@ export interface ConvertedUserStory {
27
27
  createdAt: string;
28
28
  updatedAt: string;
29
29
  labels: string[];
30
+ sourceRepo?: string;
30
31
  };
31
32
  /** Living docs file path */
32
33
  filePath: string;
33
34
  /** Living docs markdown content */
34
35
  markdown: string;
36
+ /** Feature ID this user story belongs to (when feature allocation enabled) */
37
+ featureId?: string;
35
38
  }
36
39
  export interface ItemConverterOptions {
37
40
  /** Base directory for living docs (e.g., .specweave/docs/internal/specs) */
@@ -42,10 +45,18 @@ export interface ItemConverterOptions {
42
45
  projectRoot?: string;
43
46
  /** Enable feature-level organization with FS-ID allocation */
44
47
  enableFeatureAllocation?: boolean;
48
+ /** Project ID for multi-project mode (default: 'default') */
49
+ projectId?: string;
45
50
  /** Enable duplicate detection (default: true) */
46
51
  enableDuplicateDetection?: boolean;
52
+ /** Auto-archive items older than this many days (default: 30, 0 to disable) */
53
+ autoArchiveAfterDays?: number;
47
54
  /** Callback for skipped duplicates */
48
55
  onDuplicateSkipped?: (externalId: string, existingUsId: string) => void;
56
+ /** Callback for feature folder creation */
57
+ onFeatureCreated?: (featureId: string, featurePath: string) => void;
58
+ /** Callback for archived items */
59
+ onItemArchived?: (usId: string, reason: string) => void;
49
60
  }
50
61
  /**
51
62
  * Convert external items to living docs User Stories
@@ -56,11 +67,18 @@ export interface ItemConverterOptions {
56
67
  export declare class ItemConverter {
57
68
  private options;
58
69
  private duplicateDetector;
70
+ private fsIdAllocator;
71
+ /** Cache of created feature folders to avoid duplicates */
72
+ private createdFeatures;
59
73
  constructor(options: ItemConverterOptions);
60
74
  /**
61
75
  * Convert a single external item to a User Story with E suffix
76
+ *
77
+ * @param item - External item to convert
78
+ * @param usId - User Story ID number
79
+ * @param featureId - Optional feature ID for folder organization
62
80
  */
63
- convertItem(item: ExternalItem, usId: number): ConvertedUserStory;
81
+ convertItem(item: ExternalItem, usId: number, featureId?: string): ConvertedUserStory;
64
82
  /**
65
83
  * Convert multiple external items to User Stories
66
84
  *
@@ -68,10 +86,30 @@ export declare class ItemConverter {
68
86
  * It does NOT create increments.
69
87
  */
70
88
  convertItems(items: ExternalItem[]): Promise<ConvertedUserStory[]>;
89
+ /**
90
+ * Group items by feature (based on source repo or labels)
91
+ * Items without clear grouping go into a default group
92
+ */
93
+ private groupItemsByFeature;
94
+ /**
95
+ * Allocate a feature ID for a group of items
96
+ */
97
+ private allocateFeatureForGroup;
98
+ /**
99
+ * Create feature folder with FEATURE.md
100
+ */
101
+ private createFeatureFolder;
71
102
  /**
72
103
  * Map external status to SpecWeave status
73
104
  */
74
105
  private mapStatus;
106
+ /**
107
+ * Check if an item should be auto-archived based on creation date
108
+ *
109
+ * @param createdAt - Item creation date
110
+ * @returns True if item is older than autoArchiveAfterDays threshold
111
+ */
112
+ private shouldAutoArchive;
75
113
  /**
76
114
  * Generate origin badge for living docs
77
115
  */
@@ -1 +1 @@
1
- {"version":3,"file":"item-converter.d.ts","sourceRoot":"","sources":["../../../src/importers/item-converter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAQ3D,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAC;IAEX,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IAEd,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IAEpB,0BAA0B;IAC1B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAE7B,uBAAuB;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IAEf,wBAAwB;IACxB,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;QAC5C,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IAEF,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IAEjB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IAEjB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,8DAA8D;IAC9D,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC,iDAAiD;IACjD,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC,sCAAsC;IACtC,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CACzE;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,iBAAiB,CAAkC;gBAE/C,OAAO,EAAE,oBAAoB;IAczC;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB;IA0DjE;;;;;OAKG;IACG,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAwCxE;;OAEG;IACH,OAAO,CAAC,SAAS;IAWjB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAsB3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA6ExB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;OAIG;IACH,MAAM,CAAC,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;CAsB9D"}
1
+ {"version":3,"file":"item-converter.d.ts","sourceRoot":"","sources":["../../../src/importers/item-converter.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import * as fs from '../utils/fs-native.js';
8
8
  import path from 'path';
9
+ import { FSIdAllocator } from '../living-docs/fs-id-allocator.js';
9
10
  import { DuplicateDetector } from './duplicate-detector.js';
10
11
  /**
11
12
  * Convert external items to living docs User Stories
@@ -16,8 +17,13 @@ import { DuplicateDetector } from './duplicate-detector.js';
16
17
  export class ItemConverter {
17
18
  constructor(options) {
18
19
  this.duplicateDetector = null;
20
+ this.fsIdAllocator = null;
21
+ /** Cache of created feature folders to avoid duplicates */
22
+ this.createdFeatures = new Map();
19
23
  this.options = {
20
24
  enableDuplicateDetection: true,
25
+ projectId: 'default',
26
+ autoArchiveAfterDays: 30, // Default: archive items older than 1 month
21
27
  ...options,
22
28
  };
23
29
  // Initialize duplicate detector if enabled
@@ -26,11 +32,19 @@ export class ItemConverter {
26
32
  specsDir: this.options.specsDir,
27
33
  });
28
34
  }
35
+ // Initialize FS-ID allocator if feature allocation is enabled
36
+ if (this.options.enableFeatureAllocation && this.options.projectRoot) {
37
+ this.fsIdAllocator = new FSIdAllocator(this.options.projectRoot, this.options.projectId || 'default');
38
+ }
29
39
  }
30
40
  /**
31
41
  * Convert a single external item to a User Story with E suffix
42
+ *
43
+ * @param item - External item to convert
44
+ * @param usId - User Story ID number
45
+ * @param featureId - Optional feature ID for folder organization
32
46
  */
33
- convertItem(item, usId) {
47
+ convertItem(item, usId, featureId) {
34
48
  // Generate US-ID with E suffix
35
49
  const id = `US-${String(usId).padStart(3, '0')}E`;
36
50
  // Map external status to SpecWeave status
@@ -55,12 +69,36 @@ export class ItemConverter {
55
69
  importedAt: new Date().toISOString(),
56
70
  createdAt: item.createdAt.toISOString(),
57
71
  updatedAt: item.updatedAt.toISOString(),
58
- labels: item.labels
72
+ labels: item.labels,
73
+ sourceRepo: item.sourceRepo
59
74
  }
60
75
  });
61
- // Generate file path
76
+ // Generate file path (with feature folder if allocated)
62
77
  const fileName = this.generateFileName(id, item.title);
63
- const filePath = path.join(this.options.specsDir, fileName);
78
+ let filePath;
79
+ // Check if item should be auto-archived (older than threshold)
80
+ const shouldArchive = this.shouldAutoArchive(item.createdAt);
81
+ if (featureId && this.options.enableFeatureAllocation) {
82
+ // Feature folder structure: specs/{projectId}/{featureId}/us-xxxe-title.md
83
+ // Or archive: specs/{projectId}/_archive/{featureId}/us-xxxe-title.md
84
+ const projectDir = path.join(this.options.specsDir, this.options.projectId || 'default');
85
+ const targetDir = shouldArchive
86
+ ? path.join(projectDir, '_archive', featureId)
87
+ : path.join(projectDir, featureId);
88
+ filePath = path.join(targetDir, fileName);
89
+ }
90
+ else {
91
+ // Legacy: direct in specs or archive folder
92
+ const targetDir = shouldArchive
93
+ ? path.join(this.options.specsDir, '_archive')
94
+ : this.options.specsDir;
95
+ filePath = path.join(targetDir, fileName);
96
+ }
97
+ // Notify callback if item was archived
98
+ if (shouldArchive && this.options.onItemArchived) {
99
+ const age = Math.floor((Date.now() - item.createdAt.getTime()) / (1000 * 60 * 60 * 24));
100
+ this.options.onItemArchived(id, `Item is ${age} days old (threshold: ${this.options.autoArchiveAfterDays} days)`);
101
+ }
64
102
  return {
65
103
  id,
66
104
  title: item.title,
@@ -75,10 +113,12 @@ export class ItemConverter {
75
113
  importedAt: new Date().toISOString(),
76
114
  createdAt: item.createdAt.toISOString(),
77
115
  updatedAt: item.updatedAt.toISOString(),
78
- labels: item.labels
116
+ labels: item.labels,
117
+ sourceRepo: item.sourceRepo
79
118
  },
80
119
  filePath,
81
- markdown
120
+ markdown,
121
+ featureId
82
122
  };
83
123
  }
84
124
  /**
@@ -93,30 +133,140 @@ export class ItemConverter {
93
133
  let skippedCount = 0;
94
134
  // Ensure specs directory exists
95
135
  fs.mkdirSync(this.options.specsDir, { recursive: true });
96
- // Convert each item
97
- for (let i = 0; i < items.length; i++) {
98
- const item = items[i];
99
- // Check for duplicates if duplicate detection is enabled
100
- if (this.duplicateDetector) {
101
- const existingReference = await this.duplicateDetector.findExternalIdReference(item.id);
102
- if (existingReference) {
103
- skippedCount++;
104
- // Notify callback if provided
105
- if (this.options.onDuplicateSkipped) {
106
- this.options.onDuplicateSkipped(item.id, existingReference.usId);
136
+ // If feature allocation is enabled, scan existing IDs first
137
+ if (this.fsIdAllocator) {
138
+ await this.fsIdAllocator.scanExistingIds();
139
+ }
140
+ // Group items by source (for multi-repo) or treat as single group
141
+ const itemGroups = this.groupItemsByFeature(items);
142
+ // Process each group
143
+ for (const [groupKey, groupItems] of itemGroups.entries()) {
144
+ // Allocate feature ID for this group if feature allocation is enabled
145
+ let featureId;
146
+ if (this.fsIdAllocator && this.options.enableFeatureAllocation && groupItems.length > 0) {
147
+ const firstItem = groupItems[0];
148
+ featureId = await this.allocateFeatureForGroup(firstItem, groupKey);
149
+ }
150
+ // Convert each item in the group
151
+ for (let i = 0; i < groupItems.length; i++) {
152
+ const item = groupItems[i];
153
+ // Check for duplicates if duplicate detection is enabled
154
+ if (this.duplicateDetector) {
155
+ const existingReference = await this.duplicateDetector.findExternalIdReference(item.id);
156
+ if (existingReference) {
157
+ skippedCount++;
158
+ // Notify callback if provided
159
+ if (this.options.onDuplicateSkipped) {
160
+ this.options.onDuplicateSkipped(item.id, existingReference.usId);
161
+ }
162
+ // Skip this item (duplicate)
163
+ continue;
107
164
  }
108
- // Skip this item (duplicate)
109
- continue;
110
165
  }
166
+ const usId = startingId + (converted.length);
167
+ const userStory = this.convertItem(item, usId, featureId);
168
+ converted.push(userStory);
169
+ // Ensure directory exists for feature folders
170
+ const fileDir = path.dirname(userStory.filePath);
171
+ fs.mkdirSync(fileDir, { recursive: true });
172
+ // Write living docs file
173
+ fs.writeFileSync(userStory.filePath, userStory.markdown, 'utf-8');
111
174
  }
112
- const usId = startingId + (i - skippedCount);
113
- const userStory = this.convertItem(item, usId);
114
- converted.push(userStory);
115
- // Write living docs file
116
- fs.writeFileSync(userStory.filePath, userStory.markdown, 'utf-8');
117
175
  }
118
176
  return converted;
119
177
  }
178
+ /**
179
+ * Group items by feature (based on source repo or labels)
180
+ * Items without clear grouping go into a default group
181
+ */
182
+ groupItemsByFeature(items) {
183
+ const groups = new Map();
184
+ for (const item of items) {
185
+ // Group by source repo if available
186
+ const groupKey = item.sourceRepo || 'default';
187
+ if (!groups.has(groupKey)) {
188
+ groups.set(groupKey, []);
189
+ }
190
+ groups.get(groupKey).push(item);
191
+ }
192
+ return groups;
193
+ }
194
+ /**
195
+ * Allocate a feature ID for a group of items
196
+ */
197
+ async allocateFeatureForGroup(firstItem, groupKey) {
198
+ // Check if we already created a feature for this group
199
+ if (this.createdFeatures.has(groupKey)) {
200
+ return this.createdFeatures.get(groupKey);
201
+ }
202
+ if (!this.fsIdAllocator) {
203
+ throw new Error('FSIdAllocator not initialized');
204
+ }
205
+ // Create external work item for allocation
206
+ const workItem = {
207
+ externalId: firstItem.id,
208
+ title: firstItem.sourceRepo || firstItem.title,
209
+ createdAt: firstItem.createdAt.toISOString(),
210
+ externalUrl: firstItem.url
211
+ };
212
+ // Allocate feature ID
213
+ const allocation = await this.fsIdAllocator.allocateId(workItem);
214
+ const featureId = allocation.id;
215
+ // Create feature folder with FEATURE.md
216
+ const featurePath = await this.createFeatureFolder(featureId, firstItem, groupKey);
217
+ // Cache for reuse
218
+ this.createdFeatures.set(groupKey, featureId);
219
+ // Notify callback
220
+ if (this.options.onFeatureCreated) {
221
+ this.options.onFeatureCreated(featureId, featurePath);
222
+ }
223
+ return featureId;
224
+ }
225
+ /**
226
+ * Create feature folder with FEATURE.md
227
+ */
228
+ async createFeatureFolder(featureId, firstItem, groupKey) {
229
+ const projectDir = path.join(this.options.specsDir, this.options.projectId || 'default');
230
+ const featurePath = path.join(projectDir, featureId);
231
+ // Create directory
232
+ fs.mkdirSync(featurePath, { recursive: true });
233
+ // Generate FEATURE.md content
234
+ const featureTitle = firstItem.sourceRepo
235
+ ? `Feature: ${firstItem.sourceRepo} External Items`
236
+ : `Feature: Imported from ${firstItem.platform}`;
237
+ const featureContent = `---
238
+ id: ${featureId}
239
+ title: ${featureTitle}
240
+ origin: external
241
+ source: ${firstItem.platform}
242
+ source_repo: ${firstItem.sourceRepo || 'unknown'}
243
+ created: ${new Date().toISOString()}
244
+ ---
245
+
246
+ # ${featureTitle}
247
+
248
+ **Origin**: 🔗 Imported from ${firstItem.platform}
249
+
250
+ ## Description
251
+
252
+ This feature folder contains User Stories imported from external tools.
253
+
254
+ ${firstItem.sourceRepo ? `**Source Repository**: ${firstItem.sourceRepo}` : ''}
255
+
256
+ ## User Stories
257
+
258
+ User stories in this feature will be listed here.
259
+
260
+ ## Status
261
+
262
+ - **Created**: ${new Date().toISOString()}
263
+ - **Source**: ${firstItem.platform}
264
+ `;
265
+ // Write FEATURE.md
266
+ const featureFile = path.join(featurePath, 'FEATURE.md');
267
+ fs.writeFileSync(featureFile, featureContent, 'utf-8');
268
+ return featurePath;
269
+ }
120
270
  /**
121
271
  * Map external status to SpecWeave status
122
272
  */
@@ -129,6 +279,22 @@ export class ItemConverter {
129
279
  };
130
280
  return statusMap[externalStatus] || 'Open';
131
281
  }
282
+ /**
283
+ * Check if an item should be auto-archived based on creation date
284
+ *
285
+ * @param createdAt - Item creation date
286
+ * @returns True if item is older than autoArchiveAfterDays threshold
287
+ */
288
+ shouldAutoArchive(createdAt) {
289
+ const threshold = this.options.autoArchiveAfterDays;
290
+ // Disabled if threshold is 0 or undefined
291
+ if (!threshold || threshold <= 0) {
292
+ return false;
293
+ }
294
+ const ageMs = Date.now() - createdAt.getTime();
295
+ const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24));
296
+ return ageDays >= threshold;
297
+ }
132
298
  /**
133
299
  * Generate origin badge for living docs
134
300
  */
@@ -201,6 +367,9 @@ export class ItemConverter {
201
367
  if (data.metadata.labels.length > 0) {
202
368
  parts.push(`- **Labels**: ${data.metadata.labels.join(', ')}`);
203
369
  }
370
+ if (data.metadata.sourceRepo) {
371
+ parts.push(`- **Source Repository**: ${data.metadata.sourceRepo}`);
372
+ }
204
373
  return parts.join('\n');
205
374
  }
206
375
  /**