specweave 0.30.6 → 0.30.8
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/dist/plugins/specweave-ado/lib/ado-profile-resolver.d.ts +9 -3
- package/dist/plugins/specweave-ado/lib/ado-profile-resolver.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-profile-resolver.js +13 -6
- package/dist/plugins/specweave-ado/lib/ado-profile-resolver.js.map +1 -1
- package/dist/src/cli/helpers/init/external-import-grouping.js +1 -1
- package/dist/src/cli/helpers/init/external-import-grouping.js.map +1 -1
- package/dist/src/cli/helpers/init/sync-profile-helpers.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/sync-profile-helpers.js +3 -2
- package/dist/src/cli/helpers/init/sync-profile-helpers.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado.js +2 -2
- package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +6 -5
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js +15 -10
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js.map +1 -1
- package/dist/src/cli/workers/clone-worker.js +55 -0
- package/dist/src/cli/workers/clone-worker.js.map +1 -1
- package/dist/src/cli/workers/living-docs-worker.js +7 -0
- package/dist/src/cli/workers/living-docs-worker.js.map +1 -1
- package/dist/src/config/types.d.ts +2 -2
- package/dist/src/core/config/types.d.ts +15 -1
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/living-docs/discovery.d.ts +9 -0
- package/dist/src/core/living-docs/discovery.d.ts.map +1 -1
- package/dist/src/core/living-docs/discovery.js +204 -3
- package/dist/src/core/living-docs/discovery.js.map +1 -1
- package/dist/src/core/living-docs/foundation-builder.d.ts.map +1 -1
- package/dist/src/core/living-docs/foundation-builder.js +149 -34
- package/dist/src/core/living-docs/foundation-builder.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +3 -3
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +35 -20
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/suggestions-generator.d.ts +42 -0
- package/dist/src/core/living-docs/suggestions-generator.d.ts.map +1 -1
- package/dist/src/core/living-docs/suggestions-generator.js +219 -1
- package/dist/src/core/living-docs/suggestions-generator.js.map +1 -1
- package/dist/src/core/living-docs/umbrella-detector.d.ts +94 -0
- package/dist/src/core/living-docs/umbrella-detector.d.ts.map +1 -0
- package/dist/src/core/living-docs/umbrella-detector.js +484 -0
- package/dist/src/core/living-docs/umbrella-detector.js.map +1 -0
- package/dist/src/core/living-docs/workitem-matcher.d.ts +4 -0
- package/dist/src/core/living-docs/workitem-matcher.d.ts.map +1 -1
- package/dist/src/core/living-docs/workitem-matcher.js +513 -2
- package/dist/src/core/living-docs/workitem-matcher.js.map +1 -1
- package/dist/src/core/types/config.d.ts +41 -0
- package/dist/src/core/types/config.d.ts.map +1 -1
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/core/types/sync-profile.d.ts +279 -2
- package/dist/src/core/types/sync-profile.d.ts.map +1 -1
- package/dist/src/core/types/sync-profile.js +163 -0
- package/dist/src/core/types/sync-profile.js.map +1 -1
- package/dist/src/importers/item-converter.d.ts +56 -1
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +217 -64
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/init/compliance/types.d.ts +1 -1
- package/dist/src/living-docs/epic-id-allocator.d.ts +1 -1
- package/dist/src/living-docs/epic-id-allocator.js +1 -1
- package/package.json +1 -1
- package/plugins/specweave-ado/commands/specweave-ado-close-workitem.md +5 -5
- package/plugins/specweave-ado/commands/specweave-ado-create-workitem.md +4 -4
- package/plugins/specweave-ado/commands/specweave-ado-sync.md +5 -5
- package/plugins/specweave-ado/lib/ado-profile-resolver.js +5 -3
- package/plugins/specweave-ado/lib/ado-profile-resolver.ts +16 -6
- package/plugins/specweave-ado/lib/ado-project-detector.ts +2 -2
- package/src/templates/config.json.template +1 -1
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Umbrella Repository Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects umbrella/multi-repo project structures where:
|
|
5
|
+
* - Multiple independent git repositories are cloned into subdirectories
|
|
6
|
+
* - Each child repo should be treated as a module
|
|
7
|
+
* - Clone job has produced a list of repositories
|
|
8
|
+
*
|
|
9
|
+
* Detection strategies (in priority order):
|
|
10
|
+
* 1. Clone job config - reads repos from .specweave/state/jobs/<id>/config.json
|
|
11
|
+
* 2. Umbrella config - reads from config.json umbrella.childRepos
|
|
12
|
+
* 3. Git directory scan - finds all .git directories as module boundaries
|
|
13
|
+
*
|
|
14
|
+
* @module living-docs/umbrella-detector
|
|
15
|
+
*/
|
|
16
|
+
import * as fs from '../../utils/fs-native.js';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
/**
|
|
19
|
+
* Skip directories when scanning for .git
|
|
20
|
+
*/
|
|
21
|
+
const SKIP_DIRS = new Set([
|
|
22
|
+
'node_modules',
|
|
23
|
+
'.specweave',
|
|
24
|
+
'dist',
|
|
25
|
+
'build',
|
|
26
|
+
'out',
|
|
27
|
+
'coverage',
|
|
28
|
+
'.next',
|
|
29
|
+
'.nuxt',
|
|
30
|
+
'__pycache__',
|
|
31
|
+
'.pytest_cache',
|
|
32
|
+
'.venv',
|
|
33
|
+
'venv',
|
|
34
|
+
'vendor',
|
|
35
|
+
'target',
|
|
36
|
+
]);
|
|
37
|
+
/**
|
|
38
|
+
* Main entry point: Detect umbrella structure
|
|
39
|
+
*
|
|
40
|
+
* Tries detection strategies in order:
|
|
41
|
+
* 1. Clone job config (most accurate)
|
|
42
|
+
* 2. Config.json umbrella section
|
|
43
|
+
* 3. Git directory scanning (fallback)
|
|
44
|
+
*/
|
|
45
|
+
export async function detectUmbrellaStructure(projectPath, cloneJobId) {
|
|
46
|
+
const startTime = Date.now();
|
|
47
|
+
// Strategy 1: Load from clone job
|
|
48
|
+
if (cloneJobId) {
|
|
49
|
+
const fromJob = await loadFromCloneJob(projectPath, cloneJobId);
|
|
50
|
+
if (fromJob.isUmbrella) {
|
|
51
|
+
fromJob.stats.detectionTimeMs = Date.now() - startTime;
|
|
52
|
+
return fromJob;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Strategy 1b: Find most recent clone job
|
|
56
|
+
const recentJobResult = await loadFromMostRecentCloneJob(projectPath);
|
|
57
|
+
if (recentJobResult.isUmbrella) {
|
|
58
|
+
recentJobResult.stats.detectionTimeMs = Date.now() - startTime;
|
|
59
|
+
return recentJobResult;
|
|
60
|
+
}
|
|
61
|
+
// Strategy 2: Load from config.json
|
|
62
|
+
const fromConfig = await loadFromUmbrellaConfig(projectPath);
|
|
63
|
+
if (fromConfig.isUmbrella) {
|
|
64
|
+
fromConfig.stats.detectionTimeMs = Date.now() - startTime;
|
|
65
|
+
return fromConfig;
|
|
66
|
+
}
|
|
67
|
+
// Strategy 3: Scan for .git directories
|
|
68
|
+
const fromScan = await scanForChildRepos(projectPath);
|
|
69
|
+
fromScan.stats.detectionTimeMs = Date.now() - startTime;
|
|
70
|
+
return fromScan;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Load umbrella structure from clone job config
|
|
74
|
+
*/
|
|
75
|
+
export async function loadFromCloneJob(projectPath, jobId) {
|
|
76
|
+
const configPath = path.join(projectPath, '.specweave', 'state', 'jobs', jobId, 'config.json');
|
|
77
|
+
const emptyResult = {
|
|
78
|
+
isUmbrella: false,
|
|
79
|
+
config: null,
|
|
80
|
+
modules: [],
|
|
81
|
+
source: 'none',
|
|
82
|
+
stats: { totalRepos: 0, clonedRepos: 0, failedRepos: 0, detectionTimeMs: 0 },
|
|
83
|
+
};
|
|
84
|
+
if (!fs.existsSync(configPath)) {
|
|
85
|
+
return emptyResult;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const jobConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
89
|
+
if (!jobConfig.repositories || jobConfig.repositories.length === 0) {
|
|
90
|
+
return emptyResult;
|
|
91
|
+
}
|
|
92
|
+
// Load result.json for status
|
|
93
|
+
const resultPath = path.join(projectPath, '.specweave', 'state', 'jobs', jobId, 'result.json');
|
|
94
|
+
let resultData = {};
|
|
95
|
+
if (fs.existsSync(resultPath)) {
|
|
96
|
+
resultData = JSON.parse(fs.readFileSync(resultPath, 'utf-8'));
|
|
97
|
+
}
|
|
98
|
+
// Convert to child repo configs
|
|
99
|
+
const childRepos = jobConfig.repositories.map((repo) => ({
|
|
100
|
+
id: repo.name,
|
|
101
|
+
path: repo.path,
|
|
102
|
+
name: repo.name,
|
|
103
|
+
team: repo.team || extractTeamFromPath(repo.path),
|
|
104
|
+
areaPath: repo.areaPath,
|
|
105
|
+
clonedAt: jobConfig.startedAt,
|
|
106
|
+
status: 'cloned',
|
|
107
|
+
}));
|
|
108
|
+
// Convert to modules
|
|
109
|
+
const modules = await convertReposToModules(projectPath, childRepos);
|
|
110
|
+
return {
|
|
111
|
+
isUmbrella: true,
|
|
112
|
+
config: {
|
|
113
|
+
enabled: true,
|
|
114
|
+
childRepos,
|
|
115
|
+
detectedFrom: 'clone-job',
|
|
116
|
+
detectedAt: new Date().toISOString(),
|
|
117
|
+
},
|
|
118
|
+
modules,
|
|
119
|
+
source: 'clone-job',
|
|
120
|
+
stats: {
|
|
121
|
+
totalRepos: jobConfig.repositories.length,
|
|
122
|
+
clonedRepos: resultData.succeeded || modules.length,
|
|
123
|
+
failedRepos: resultData.failed || 0,
|
|
124
|
+
detectionTimeMs: 0,
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
return emptyResult;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Load from most recent clone job (auto-detect)
|
|
134
|
+
*/
|
|
135
|
+
async function loadFromMostRecentCloneJob(projectPath) {
|
|
136
|
+
const jobsDir = path.join(projectPath, '.specweave', 'state', 'jobs');
|
|
137
|
+
const emptyResult = {
|
|
138
|
+
isUmbrella: false,
|
|
139
|
+
config: null,
|
|
140
|
+
modules: [],
|
|
141
|
+
source: 'none',
|
|
142
|
+
stats: { totalRepos: 0, clonedRepos: 0, failedRepos: 0, detectionTimeMs: 0 },
|
|
143
|
+
};
|
|
144
|
+
if (!fs.existsSync(jobsDir)) {
|
|
145
|
+
return emptyResult;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const jobDirs = fs
|
|
149
|
+
.readdirSync(jobsDir, { withFileTypes: true })
|
|
150
|
+
.filter((d) => d.isDirectory())
|
|
151
|
+
.map((d) => d.name);
|
|
152
|
+
// Find clone jobs by checking for config.json with repositories
|
|
153
|
+
for (const jobId of jobDirs.reverse()) {
|
|
154
|
+
// Most recent first
|
|
155
|
+
const configPath = path.join(jobsDir, jobId, 'config.json');
|
|
156
|
+
if (fs.existsSync(configPath)) {
|
|
157
|
+
try {
|
|
158
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
159
|
+
if (config.repositories && config.repositories.length > 0) {
|
|
160
|
+
return loadFromCloneJob(projectPath, jobId);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return emptyResult;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return emptyResult;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Load umbrella structure from config.json
|
|
176
|
+
*/
|
|
177
|
+
export async function loadFromUmbrellaConfig(projectPath) {
|
|
178
|
+
const configPath = path.join(projectPath, '.specweave', 'config.json');
|
|
179
|
+
const emptyResult = {
|
|
180
|
+
isUmbrella: false,
|
|
181
|
+
config: null,
|
|
182
|
+
modules: [],
|
|
183
|
+
source: 'none',
|
|
184
|
+
stats: { totalRepos: 0, clonedRepos: 0, failedRepos: 0, detectionTimeMs: 0 },
|
|
185
|
+
};
|
|
186
|
+
if (!fs.existsSync(configPath)) {
|
|
187
|
+
return emptyResult;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
191
|
+
if (!config.umbrella?.enabled || !config.umbrella?.childRepos?.length) {
|
|
192
|
+
return emptyResult;
|
|
193
|
+
}
|
|
194
|
+
const childRepos = config.umbrella.childRepos;
|
|
195
|
+
const modules = await convertReposToModules(projectPath, childRepos);
|
|
196
|
+
return {
|
|
197
|
+
isUmbrella: true,
|
|
198
|
+
config: {
|
|
199
|
+
enabled: true,
|
|
200
|
+
childRepos,
|
|
201
|
+
detectedFrom: 'config',
|
|
202
|
+
detectedAt: new Date().toISOString(),
|
|
203
|
+
},
|
|
204
|
+
modules,
|
|
205
|
+
source: 'config',
|
|
206
|
+
stats: {
|
|
207
|
+
totalRepos: childRepos.length,
|
|
208
|
+
clonedRepos: modules.length,
|
|
209
|
+
failedRepos: childRepos.length - modules.length,
|
|
210
|
+
detectionTimeMs: 0,
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return emptyResult;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Scan for child repositories by finding .git directories
|
|
220
|
+
*/
|
|
221
|
+
export async function scanForChildRepos(projectPath, maxDepth = 3) {
|
|
222
|
+
const childRepos = [];
|
|
223
|
+
const emptyResult = {
|
|
224
|
+
isUmbrella: false,
|
|
225
|
+
config: null,
|
|
226
|
+
modules: [],
|
|
227
|
+
source: 'none',
|
|
228
|
+
stats: { totalRepos: 0, clonedRepos: 0, failedRepos: 0, detectionTimeMs: 0 },
|
|
229
|
+
};
|
|
230
|
+
// Don't scan root .git
|
|
231
|
+
const rootGit = path.join(projectPath, '.git');
|
|
232
|
+
const hasRootGit = fs.existsSync(rootGit);
|
|
233
|
+
/**
|
|
234
|
+
* Recursively scan for .git directories
|
|
235
|
+
*/
|
|
236
|
+
function scanDir(dir, depth) {
|
|
237
|
+
if (depth > maxDepth)
|
|
238
|
+
return;
|
|
239
|
+
try {
|
|
240
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
241
|
+
for (const entry of entries) {
|
|
242
|
+
if (!entry.isDirectory())
|
|
243
|
+
continue;
|
|
244
|
+
if (SKIP_DIRS.has(entry.name))
|
|
245
|
+
continue;
|
|
246
|
+
if (entry.name.startsWith('.') && entry.name !== '.git')
|
|
247
|
+
continue;
|
|
248
|
+
const fullPath = path.join(dir, entry.name);
|
|
249
|
+
const relativePath = path.relative(projectPath, fullPath);
|
|
250
|
+
// Check if this directory has a .git folder
|
|
251
|
+
const gitPath = path.join(fullPath, '.git');
|
|
252
|
+
if (fs.existsSync(gitPath) && relativePath !== '') {
|
|
253
|
+
// Found a child repo
|
|
254
|
+
childRepos.push({
|
|
255
|
+
id: entry.name,
|
|
256
|
+
path: relativePath,
|
|
257
|
+
name: entry.name,
|
|
258
|
+
team: extractTeamFromPath(relativePath),
|
|
259
|
+
status: 'cloned',
|
|
260
|
+
});
|
|
261
|
+
// Don't recurse into child repos
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
// Recurse into subdirectories
|
|
265
|
+
scanDir(fullPath, depth + 1);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
// Ignore permission errors
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
scanDir(projectPath, 0);
|
|
273
|
+
// Umbrella detection threshold: at least 2 child repos
|
|
274
|
+
if (childRepos.length < 2) {
|
|
275
|
+
return emptyResult;
|
|
276
|
+
}
|
|
277
|
+
const modules = await convertReposToModules(projectPath, childRepos);
|
|
278
|
+
return {
|
|
279
|
+
isUmbrella: true,
|
|
280
|
+
config: {
|
|
281
|
+
enabled: true,
|
|
282
|
+
childRepos,
|
|
283
|
+
detectedFrom: 'git-scan',
|
|
284
|
+
detectedAt: new Date().toISOString(),
|
|
285
|
+
},
|
|
286
|
+
modules,
|
|
287
|
+
source: 'git-scan',
|
|
288
|
+
stats: {
|
|
289
|
+
totalRepos: childRepos.length,
|
|
290
|
+
clonedRepos: modules.length,
|
|
291
|
+
failedRepos: 0,
|
|
292
|
+
detectionTimeMs: 0,
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Convert child repo configs to ModuleInfo format
|
|
298
|
+
*/
|
|
299
|
+
async function convertReposToModules(projectPath, repos) {
|
|
300
|
+
const modules = [];
|
|
301
|
+
for (const repo of repos) {
|
|
302
|
+
const fullPath = path.join(projectPath, repo.path);
|
|
303
|
+
if (!fs.existsSync(fullPath)) {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
const moduleInfo = await analyzeChildRepo(fullPath, repo);
|
|
307
|
+
modules.push(moduleInfo);
|
|
308
|
+
}
|
|
309
|
+
// Sort by file count (largest first)
|
|
310
|
+
modules.sort((a, b) => b.fileCount - a.fileCount);
|
|
311
|
+
return modules;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Analyze a child repository to create ModuleInfo
|
|
315
|
+
*/
|
|
316
|
+
async function analyzeChildRepo(repoPath, config) {
|
|
317
|
+
const info = {
|
|
318
|
+
name: config.name,
|
|
319
|
+
path: config.path,
|
|
320
|
+
fileCount: 0,
|
|
321
|
+
estimatedLOC: 0,
|
|
322
|
+
hasTests: false,
|
|
323
|
+
hasReadme: false,
|
|
324
|
+
entryPoints: [],
|
|
325
|
+
extensions: {},
|
|
326
|
+
};
|
|
327
|
+
// Quick scan for stats (don't recurse too deep)
|
|
328
|
+
try {
|
|
329
|
+
await scanRepoStats(repoPath, info, 0, 5);
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
// Ignore errors
|
|
333
|
+
}
|
|
334
|
+
// Check for common entry points
|
|
335
|
+
const entryPointPatterns = [
|
|
336
|
+
'index.ts',
|
|
337
|
+
'index.js',
|
|
338
|
+
'main.ts',
|
|
339
|
+
'main.js',
|
|
340
|
+
'app.ts',
|
|
341
|
+
'app.js',
|
|
342
|
+
'src/index.ts',
|
|
343
|
+
'src/index.js',
|
|
344
|
+
'src/main.ts',
|
|
345
|
+
'src/main.js',
|
|
346
|
+
];
|
|
347
|
+
for (const pattern of entryPointPatterns) {
|
|
348
|
+
if (fs.existsSync(path.join(repoPath, pattern))) {
|
|
349
|
+
info.entryPoints.push(pattern);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// Check for README
|
|
353
|
+
const readmePatterns = ['README.md', 'readme.md', 'README'];
|
|
354
|
+
for (const pattern of readmePatterns) {
|
|
355
|
+
if (fs.existsSync(path.join(repoPath, pattern))) {
|
|
356
|
+
info.hasReadme = true;
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// Check for tests
|
|
361
|
+
const testPatterns = ['tests', 'test', '__tests__', 'spec'];
|
|
362
|
+
for (const pattern of testPatterns) {
|
|
363
|
+
if (fs.existsSync(path.join(repoPath, pattern))) {
|
|
364
|
+
info.hasTests = true;
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return info;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Scan repository stats (file count, extensions, LOC estimate)
|
|
372
|
+
*/
|
|
373
|
+
async function scanRepoStats(dir, info, depth, maxDepth) {
|
|
374
|
+
if (depth > maxDepth)
|
|
375
|
+
return;
|
|
376
|
+
try {
|
|
377
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
378
|
+
for (const entry of entries) {
|
|
379
|
+
const fullPath = path.join(dir, entry.name);
|
|
380
|
+
if (entry.isDirectory()) {
|
|
381
|
+
if (SKIP_DIRS.has(entry.name) || entry.name.startsWith('.')) {
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
await scanRepoStats(fullPath, info, depth + 1, maxDepth);
|
|
385
|
+
}
|
|
386
|
+
else if (entry.isFile()) {
|
|
387
|
+
info.fileCount++;
|
|
388
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
389
|
+
info.extensions[ext] = (info.extensions[ext] || 0) + 1;
|
|
390
|
+
// Estimate LOC for code files
|
|
391
|
+
if (isCodeFile(ext)) {
|
|
392
|
+
try {
|
|
393
|
+
const stat = fs.statSync(fullPath);
|
|
394
|
+
info.estimatedLOC += Math.round(stat.size / 40);
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
// Ignore
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// Check for test files
|
|
401
|
+
if (entry.name.includes('.test.') ||
|
|
402
|
+
entry.name.includes('.spec.') ||
|
|
403
|
+
entry.name.includes('_test.')) {
|
|
404
|
+
info.hasTests = true;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
catch {
|
|
410
|
+
// Ignore permission errors
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Check if extension is a code file
|
|
415
|
+
*/
|
|
416
|
+
function isCodeFile(ext) {
|
|
417
|
+
const codeExtensions = new Set([
|
|
418
|
+
'.ts',
|
|
419
|
+
'.tsx',
|
|
420
|
+
'.js',
|
|
421
|
+
'.jsx',
|
|
422
|
+
'.py',
|
|
423
|
+
'.go',
|
|
424
|
+
'.rs',
|
|
425
|
+
'.java',
|
|
426
|
+
'.kt',
|
|
427
|
+
'.cs',
|
|
428
|
+
'.cpp',
|
|
429
|
+
'.c',
|
|
430
|
+
'.rb',
|
|
431
|
+
'.php',
|
|
432
|
+
'.swift',
|
|
433
|
+
'.vue',
|
|
434
|
+
'.svelte',
|
|
435
|
+
]);
|
|
436
|
+
return codeExtensions.has(ext);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Extract team name from path
|
|
440
|
+
* e.g., "acme/inventory-fe" -> "inventory"
|
|
441
|
+
*/
|
|
442
|
+
function extractTeamFromPath(repoPath) {
|
|
443
|
+
const parts = repoPath.split('/');
|
|
444
|
+
if (parts.length >= 2) {
|
|
445
|
+
// Pattern: org/team-suffix -> team
|
|
446
|
+
const repoName = parts[parts.length - 1];
|
|
447
|
+
// Remove common suffixes
|
|
448
|
+
const team = repoName
|
|
449
|
+
.replace(/-fe$/, '')
|
|
450
|
+
.replace(/-be$/, '')
|
|
451
|
+
.replace(/-api$/, '')
|
|
452
|
+
.replace(/-web$/, '')
|
|
453
|
+
.replace(/-mobile$/, '')
|
|
454
|
+
.replace(/-backend$/, '')
|
|
455
|
+
.replace(/-frontend$/, '')
|
|
456
|
+
.replace(/-service$/, '')
|
|
457
|
+
.replace(/-srv$/, '');
|
|
458
|
+
return team;
|
|
459
|
+
}
|
|
460
|
+
return undefined;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Persist umbrella config to config.json
|
|
464
|
+
*/
|
|
465
|
+
export async function persistUmbrellaConfig(projectPath, umbrellaConfig) {
|
|
466
|
+
const configPath = path.join(projectPath, '.specweave', 'config.json');
|
|
467
|
+
let config = {};
|
|
468
|
+
if (fs.existsSync(configPath)) {
|
|
469
|
+
try {
|
|
470
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
471
|
+
}
|
|
472
|
+
catch {
|
|
473
|
+
// Start fresh if parse fails
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
config.umbrella = {
|
|
477
|
+
enabled: umbrellaConfig.enabled,
|
|
478
|
+
childRepos: umbrellaConfig.childRepos,
|
|
479
|
+
detectedFrom: umbrellaConfig.detectedFrom,
|
|
480
|
+
detectedAt: umbrellaConfig.detectedAt,
|
|
481
|
+
};
|
|
482
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
483
|
+
}
|
|
484
|
+
//# sourceMappingURL=umbrella-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"umbrella-detector.js","sourceRoot":"","sources":["../../../../src/core/living-docs/umbrella-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,6 +31,10 @@ export interface WorkItem {
|
|
|
31
31
|
externalId?: string;
|
|
32
32
|
/** Keywords extracted from title and description */
|
|
33
33
|
keywords: string[];
|
|
34
|
+
/** Team name (extracted from folder structure or ADO area path) */
|
|
35
|
+
team?: string;
|
|
36
|
+
/** ADO area path (e.g., "Acme\\Inventory") */
|
|
37
|
+
areaPath?: string;
|
|
34
38
|
}
|
|
35
39
|
/**
|
|
36
40
|
* Match between work item and module
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workitem-matcher.d.ts","sourceRoot":"","sources":["../../../../src/core/living-docs/workitem-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAc,MAAM,gBAAgB,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,cAAc,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAC3C,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"workitem-matcher.d.ts","sourceRoot":"","sources":["../../../../src/core/living-docs/workitem-matcher.ts"],"names":[],"mappings":"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"}
|