specweave 0.33.2 → 0.33.3
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/CLAUDE.md +56 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts +120 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.js +276 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +4 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +13 -3
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/per-us-sync.d.ts +97 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.js +274 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.d.ts +113 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.js +254 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.js.map +1 -0
- package/dist/src/core/config/config-manager.d.ts.map +1 -1
- package/dist/src/core/config/config-manager.js +58 -0
- package/dist/src/core/config/config-manager.js.map +1 -1
- package/dist/src/core/config/types.d.ts +80 -0
- 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/cross-project-sync.d.ts +87 -15
- package/dist/src/core/living-docs/cross-project-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/cross-project-sync.js +147 -28
- package/dist/src/core/living-docs/cross-project-sync.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +26 -22
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/types.d.ts +24 -3
- package/dist/src/core/living-docs/types.d.ts.map +1 -1
- package/dist/src/core/types/config.d.ts +79 -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/sync/sync-coordinator.d.ts +20 -0
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +258 -33
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/dist/src/utils/project-resolver.d.ts +156 -0
- package/dist/src/utils/project-resolver.d.ts.map +1 -0
- package/dist/src/utils/project-resolver.js +587 -0
- package/dist/src/utils/project-resolver.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/hooks/hooks.json +10 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh +105 -3
- package/plugins/specweave/hooks/v2/guards/per-us-project-validator.sh +281 -0
- package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +29 -0
- package/plugins/specweave-ado/lib/per-us-sync.js +247 -0
- package/plugins/specweave-ado/lib/per-us-sync.ts +410 -0
- package/plugins/specweave-github/lib/github-client-v2.js +10 -3
- package/plugins/specweave-github/lib/github-client-v2.ts +15 -3
- package/plugins/specweave-github/lib/per-us-sync.js +241 -0
- package/plugins/specweave-github/lib/per-us-sync.ts +375 -0
- package/plugins/specweave-jira/lib/per-us-sync.js +224 -0
- package/plugins/specweave-jira/lib/per-us-sync.ts +366 -0
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Resolver
|
|
3
|
+
*
|
|
4
|
+
* Smart utility that auto-resolves project/board for user stories
|
|
5
|
+
* based on context analysis:
|
|
6
|
+
* - Single project → auto-select
|
|
7
|
+
* - Keyword matching → suggest with confidence
|
|
8
|
+
* - Cross-cutting detection → split across projects
|
|
9
|
+
* - Learned patterns from existing specs
|
|
10
|
+
*
|
|
11
|
+
* Part of increment 0137: Per-US Project/Board Enforcement
|
|
12
|
+
*
|
|
13
|
+
* @module utils/project-resolver
|
|
14
|
+
* @since v0.34.0
|
|
15
|
+
*/
|
|
16
|
+
import * as fs from './fs-native.js';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
import { detectStructureLevel } from './structure-level-detector.js';
|
|
19
|
+
import { consoleLogger } from './logger.js';
|
|
20
|
+
import { CrossCuttingDetector } from './cross-cutting-detector.js';
|
|
21
|
+
/**
|
|
22
|
+
* Default keyword patterns for common project types
|
|
23
|
+
*/
|
|
24
|
+
const DEFAULT_KEYWORD_PATTERNS = {
|
|
25
|
+
// Frontend patterns
|
|
26
|
+
frontend: [
|
|
27
|
+
'ui', 'form', 'button', 'page', 'component', 'react', 'vue', 'angular', 'next.js',
|
|
28
|
+
'css', 'style', 'responsive', 'chart', 'dashboard', 'view', 'modal', 'widget',
|
|
29
|
+
'tailwind', 'material-ui', 'recharts', 'user interface', 'client', 'browser'
|
|
30
|
+
],
|
|
31
|
+
// Backend patterns
|
|
32
|
+
backend: [
|
|
33
|
+
'api', 'endpoint', 'rest', 'graphql', 'database', 'query', 'migration', 'service',
|
|
34
|
+
'controller', 'authentication', 'jwt', 'session', 'middleware', 'crud',
|
|
35
|
+
'redis', 'postgresql', 'mongodb', 'microservice', 'server', 'lambda'
|
|
36
|
+
],
|
|
37
|
+
// Mobile patterns
|
|
38
|
+
mobile: [
|
|
39
|
+
'mobile', 'ios', 'android', 'react native', 'flutter', 'expo', 'app', 'native',
|
|
40
|
+
'push notification', 'offline', 'asyncstorage', 'screen', 'touch', 'gesture'
|
|
41
|
+
],
|
|
42
|
+
// Infrastructure patterns
|
|
43
|
+
infrastructure: [
|
|
44
|
+
'deploy', 'ci/cd', 'docker', 'kubernetes', 'terraform', 'monitoring',
|
|
45
|
+
'logging', 'pipeline', 'aws', 'azure', 'gcp', 'nginx', 'helm', 'argocd'
|
|
46
|
+
],
|
|
47
|
+
// Shared/common patterns
|
|
48
|
+
shared: [
|
|
49
|
+
'types', 'interfaces', 'utilities', 'validators', 'shared', 'common', 'library',
|
|
50
|
+
'sdk', 'models', 'constants', 'helpers', 'utils'
|
|
51
|
+
]
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Board-level keyword patterns (for 2-level structures)
|
|
55
|
+
*/
|
|
56
|
+
const DEFAULT_BOARD_KEYWORDS = {
|
|
57
|
+
analytics: ['analytics', 'metrics', 'kpi', 'dashboard', 'report', 'chart', 'graph'],
|
|
58
|
+
'user-management': ['user', 'auth', 'login', 'registration', 'profile', 'permissions', 'roles'],
|
|
59
|
+
integrations: ['integration', 'webhook', 'api', 'third-party', 'sync', 'import', 'export'],
|
|
60
|
+
payments: ['payment', 'billing', 'subscription', 'invoice', 'stripe', 'checkout'],
|
|
61
|
+
notifications: ['notification', 'alert', 'email', 'sms', 'push', 'messaging'],
|
|
62
|
+
devops: ['deploy', 'infrastructure', 'monitoring', 'ci/cd', 'pipeline']
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Project Resolver
|
|
66
|
+
*
|
|
67
|
+
* Resolves project/board context for user stories based on:
|
|
68
|
+
* 1. Single project auto-selection
|
|
69
|
+
* 2. Learned patterns from existing specs
|
|
70
|
+
* 3. Keyword-based matching
|
|
71
|
+
* 4. Cross-cutting detection
|
|
72
|
+
*/
|
|
73
|
+
export class ProjectResolver {
|
|
74
|
+
constructor(projectRoot, options = {}) {
|
|
75
|
+
this.learnedPatterns = new Map();
|
|
76
|
+
this.projectRoot = projectRoot;
|
|
77
|
+
this.logger = options.logger ?? consoleLogger;
|
|
78
|
+
this.structureConfig = detectStructureLevel(projectRoot);
|
|
79
|
+
this.keywordPatterns = {
|
|
80
|
+
projectKeywords: { ...DEFAULT_KEYWORD_PATTERNS },
|
|
81
|
+
boardKeywords: { ...DEFAULT_BOARD_KEYWORDS }
|
|
82
|
+
};
|
|
83
|
+
// Initialize cross-cutting detector with custom mappings from actual projects
|
|
84
|
+
const customMappings = {};
|
|
85
|
+
for (const project of this.structureConfig.projects) {
|
|
86
|
+
// Map project ID and name to itself
|
|
87
|
+
customMappings[project.id] = [project.id.toLowerCase()];
|
|
88
|
+
if (project.name && project.name !== project.id) {
|
|
89
|
+
customMappings[project.id].push(project.name.toLowerCase());
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
this.crossCuttingDetector = new CrossCuttingDetector({
|
|
93
|
+
logger: this.logger,
|
|
94
|
+
customMappings
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get structure level (1 or 2)
|
|
99
|
+
*/
|
|
100
|
+
getStructureLevel() {
|
|
101
|
+
return this.structureConfig.level;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get available projects
|
|
105
|
+
*/
|
|
106
|
+
getProjects() {
|
|
107
|
+
return this.structureConfig.projects;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get boards for a project (2-level only)
|
|
111
|
+
*/
|
|
112
|
+
getBoards(projectId) {
|
|
113
|
+
return this.structureConfig.boardsByProject?.[projectId] ?? [];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Learn keyword patterns from existing spec.md files
|
|
117
|
+
*/
|
|
118
|
+
async learnFromExistingSpecs() {
|
|
119
|
+
const incrementsPath = path.join(this.projectRoot, '.specweave/increments');
|
|
120
|
+
if (!fs.existsSync(incrementsPath)) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
const entries = fs.readdirSync(incrementsPath, { withFileTypes: true });
|
|
125
|
+
for (const entry of entries) {
|
|
126
|
+
if (!entry.isDirectory())
|
|
127
|
+
continue;
|
|
128
|
+
if (entry.name.startsWith('_'))
|
|
129
|
+
continue;
|
|
130
|
+
const specPath = path.join(incrementsPath, entry.name, 'spec.md');
|
|
131
|
+
if (!fs.existsSync(specPath))
|
|
132
|
+
continue;
|
|
133
|
+
try {
|
|
134
|
+
const content = fs.readFileSync(specPath, 'utf-8');
|
|
135
|
+
this.extractPatternsFromSpec(content);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Skip unreadable specs
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
this.logger.debug?.(`Learned ${this.learnedPatterns.size} keyword patterns from existing specs`);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Ignore read errors
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Extract keyword → project patterns from a spec file
|
|
149
|
+
*/
|
|
150
|
+
extractPatternsFromSpec(content) {
|
|
151
|
+
// Find US sections with **Project**: field
|
|
152
|
+
const usPattern = /### US-\d+:([^\n]+)\n(?:[^\n]*\n){0,5}\*\*Project\*\*:\s*(\S+)/gi;
|
|
153
|
+
let match;
|
|
154
|
+
while ((match = usPattern.exec(content)) !== null) {
|
|
155
|
+
const usTitle = match[1].toLowerCase().trim();
|
|
156
|
+
const project = match[2].trim();
|
|
157
|
+
// Extract significant words from title
|
|
158
|
+
const words = usTitle.split(/\s+/).filter(w => w.length > 3);
|
|
159
|
+
for (const word of words) {
|
|
160
|
+
// Only learn if not already a default pattern
|
|
161
|
+
if (!this.isDefaultPattern(word)) {
|
|
162
|
+
this.learnedPatterns.set(word, project);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Check if word is in default patterns
|
|
169
|
+
*/
|
|
170
|
+
isDefaultPattern(word) {
|
|
171
|
+
const lowerWord = word.toLowerCase();
|
|
172
|
+
for (const patterns of Object.values(DEFAULT_KEYWORD_PATTERNS)) {
|
|
173
|
+
if (patterns.some(p => p.includes(lowerWord) || lowerWord.includes(p))) {
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Resolve project for a single user story
|
|
181
|
+
*/
|
|
182
|
+
resolveForUserStory(usContent) {
|
|
183
|
+
const lowerContent = usContent.toLowerCase();
|
|
184
|
+
// 1. Single project → auto-select
|
|
185
|
+
if (this.structureConfig.projects.length === 1) {
|
|
186
|
+
const project = this.structureConfig.projects[0];
|
|
187
|
+
return {
|
|
188
|
+
resolved: true,
|
|
189
|
+
projectId: project.id,
|
|
190
|
+
confidence: 'high',
|
|
191
|
+
reason: 'Single project available - auto-selected'
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// 2. Check learned patterns (highest priority after single project)
|
|
195
|
+
for (const [keyword, project] of this.learnedPatterns) {
|
|
196
|
+
if (lowerContent.includes(keyword.toLowerCase())) {
|
|
197
|
+
// Validate project still exists
|
|
198
|
+
if (this.structureConfig.projects.some(p => p.id === project)) {
|
|
199
|
+
return {
|
|
200
|
+
resolved: true,
|
|
201
|
+
projectId: project,
|
|
202
|
+
confidence: 'high',
|
|
203
|
+
reason: `Matched learned pattern: "${keyword}" → ${project}`,
|
|
204
|
+
matchedKeywords: [keyword]
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// 3. Match against actual project IDs in config
|
|
210
|
+
const matchedProjects = this.matchProjectsByKeywords(lowerContent);
|
|
211
|
+
if (matchedProjects.length === 1) {
|
|
212
|
+
const match = matchedProjects[0];
|
|
213
|
+
return {
|
|
214
|
+
resolved: true,
|
|
215
|
+
projectId: match.projectId,
|
|
216
|
+
confidence: match.confidence > 0.7 ? 'high' : 'medium',
|
|
217
|
+
reason: `Keyword match: ${match.matchedKeywords.join(', ')}`,
|
|
218
|
+
matchedKeywords: match.matchedKeywords
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
if (matchedProjects.length > 1) {
|
|
222
|
+
// Multiple matches - return highest confidence
|
|
223
|
+
const sorted = matchedProjects.sort((a, b) => b.confidence - a.confidence);
|
|
224
|
+
const best = sorted[0];
|
|
225
|
+
if (best.confidence > 0.6 && best.confidence > sorted[1].confidence * 1.3) {
|
|
226
|
+
// Clear winner (>30% higher than runner-up)
|
|
227
|
+
return {
|
|
228
|
+
resolved: true,
|
|
229
|
+
projectId: best.projectId,
|
|
230
|
+
confidence: 'medium',
|
|
231
|
+
reason: `Best keyword match (${Math.round(best.confidence * 100)}%): ${best.matchedKeywords.join(', ')}`,
|
|
232
|
+
matchedKeywords: best.matchedKeywords
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// 4. Use CrossCuttingDetector for more sophisticated analysis
|
|
237
|
+
const crossCuttingResult = this.crossCuttingDetector.detect(usContent);
|
|
238
|
+
if (crossCuttingResult.suggestedProjects.length === 1) {
|
|
239
|
+
// Single project suggested by cross-cutting detection
|
|
240
|
+
const suggestedType = crossCuttingResult.suggestedProjects[0];
|
|
241
|
+
const mappedProject = this.mapSuggestedTypeToProject(suggestedType);
|
|
242
|
+
if (mappedProject) {
|
|
243
|
+
const matchedKeywords = crossCuttingResult.detectedPatterns
|
|
244
|
+
.filter(p => p.suggestedProject === suggestedType)
|
|
245
|
+
.map(p => p.matched);
|
|
246
|
+
return {
|
|
247
|
+
resolved: true,
|
|
248
|
+
projectId: mappedProject,
|
|
249
|
+
confidence: crossCuttingResult.confidence,
|
|
250
|
+
reason: `Cross-cutting analysis: ${suggestedType} → ${mappedProject}`,
|
|
251
|
+
matchedKeywords
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (crossCuttingResult.isCrossCutting && crossCuttingResult.suggestedProjects.length > 1) {
|
|
256
|
+
// Multiple projects detected - this is a cross-project US
|
|
257
|
+
// Return first match with medium confidence and note the ambiguity
|
|
258
|
+
const firstType = crossCuttingResult.suggestedProjects[0];
|
|
259
|
+
const mappedProject = this.mapSuggestedTypeToProject(firstType);
|
|
260
|
+
if (mappedProject) {
|
|
261
|
+
return {
|
|
262
|
+
resolved: true,
|
|
263
|
+
projectId: mappedProject,
|
|
264
|
+
confidence: 'medium',
|
|
265
|
+
reason: `Cross-project detected (${crossCuttingResult.suggestedProjects.join(', ')}) - using ${firstType}`,
|
|
266
|
+
matchedKeywords: crossCuttingResult.detectedPatterns.map(p => p.matched)
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// 5. No clear resolution
|
|
271
|
+
return {
|
|
272
|
+
resolved: false,
|
|
273
|
+
confidence: 'low',
|
|
274
|
+
reason: 'Could not determine project from content - user selection required'
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Map suggested project type (frontend, backend, etc.) to actual project ID
|
|
279
|
+
*/
|
|
280
|
+
mapSuggestedTypeToProject(suggestedType) {
|
|
281
|
+
const lowerType = suggestedType.toLowerCase();
|
|
282
|
+
// First, check if any project ID directly matches the type
|
|
283
|
+
for (const project of this.structureConfig.projects) {
|
|
284
|
+
const lowerId = project.id.toLowerCase();
|
|
285
|
+
const lowerName = (project.name || '').toLowerCase();
|
|
286
|
+
if (lowerId === lowerType || lowerName === lowerType) {
|
|
287
|
+
return project.id;
|
|
288
|
+
}
|
|
289
|
+
// Check if project ID contains the type (e.g., "my-frontend" contains "frontend")
|
|
290
|
+
if (lowerId.includes(lowerType) || lowerType.includes(lowerId)) {
|
|
291
|
+
return project.id;
|
|
292
|
+
}
|
|
293
|
+
// Check common mappings
|
|
294
|
+
if ((lowerType === 'frontend' && (lowerId.includes('fe') || lowerId.includes('ui') || lowerId.includes('web') || lowerId.includes('client'))) ||
|
|
295
|
+
(lowerType === 'backend' && (lowerId.includes('be') || lowerId.includes('api') || lowerId.includes('server') || lowerId.includes('service'))) ||
|
|
296
|
+
(lowerType === 'mobile' && (lowerId.includes('mobile') || lowerId.includes('app') || lowerId.includes('ios') || lowerId.includes('android'))) ||
|
|
297
|
+
(lowerType === 'infrastructure' && (lowerId.includes('infra') || lowerId.includes('devops') || lowerId.includes('platform'))) ||
|
|
298
|
+
(lowerType === 'shared' && (lowerId.includes('shared') || lowerId.includes('common') || lowerId.includes('lib')))) {
|
|
299
|
+
return project.id;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// If only one project exists, use it (fallback)
|
|
303
|
+
if (this.structureConfig.projects.length === 1) {
|
|
304
|
+
return this.structureConfig.projects[0].id;
|
|
305
|
+
}
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Resolve board for a user story (2-level structures only)
|
|
310
|
+
*/
|
|
311
|
+
resolveBoard(usContent, projectId) {
|
|
312
|
+
if (this.structureConfig.level !== 2) {
|
|
313
|
+
return {
|
|
314
|
+
resolved: false,
|
|
315
|
+
confidence: 'high',
|
|
316
|
+
reason: 'Board not required for 1-level structure'
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
const boards = this.structureConfig.boardsByProject?.[projectId] ?? [];
|
|
320
|
+
// Single board → auto-select
|
|
321
|
+
if (boards.length === 1) {
|
|
322
|
+
return {
|
|
323
|
+
resolved: true,
|
|
324
|
+
boardId: boards[0].id,
|
|
325
|
+
confidence: 'high',
|
|
326
|
+
reason: 'Single board available - auto-selected'
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
if (boards.length === 0) {
|
|
330
|
+
return {
|
|
331
|
+
resolved: false,
|
|
332
|
+
confidence: 'low',
|
|
333
|
+
reason: `No boards found for project "${projectId}"`
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
const lowerContent = usContent.toLowerCase();
|
|
337
|
+
// Match against board keywords
|
|
338
|
+
for (const board of boards) {
|
|
339
|
+
// Check board's own keywords
|
|
340
|
+
if (board.keywords) {
|
|
341
|
+
for (const keyword of board.keywords) {
|
|
342
|
+
if (lowerContent.includes(keyword.toLowerCase())) {
|
|
343
|
+
return {
|
|
344
|
+
resolved: true,
|
|
345
|
+
boardId: board.id,
|
|
346
|
+
confidence: 'high',
|
|
347
|
+
reason: `Board keyword match: "${keyword}"`,
|
|
348
|
+
matchedKeywords: [keyword]
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Check default board keywords
|
|
354
|
+
const boardPatterns = DEFAULT_BOARD_KEYWORDS[board.id.toLowerCase()];
|
|
355
|
+
if (boardPatterns) {
|
|
356
|
+
for (const pattern of boardPatterns) {
|
|
357
|
+
if (lowerContent.includes(pattern)) {
|
|
358
|
+
return {
|
|
359
|
+
resolved: true,
|
|
360
|
+
boardId: board.id,
|
|
361
|
+
confidence: 'medium',
|
|
362
|
+
reason: `Default board pattern match: "${pattern}"`,
|
|
363
|
+
matchedKeywords: [pattern]
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
resolved: false,
|
|
371
|
+
confidence: 'low',
|
|
372
|
+
reason: 'Could not determine board from content - user selection required'
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Match content against project keywords
|
|
377
|
+
*/
|
|
378
|
+
matchProjectsByKeywords(content) {
|
|
379
|
+
const results = [];
|
|
380
|
+
for (const project of this.structureConfig.projects) {
|
|
381
|
+
const projectId = project.id.toLowerCase();
|
|
382
|
+
const matchedKeywords = [];
|
|
383
|
+
// Check if project ID appears directly
|
|
384
|
+
if (content.includes(projectId)) {
|
|
385
|
+
matchedKeywords.push(projectId);
|
|
386
|
+
}
|
|
387
|
+
// Check default patterns that might map to this project
|
|
388
|
+
for (const [patternType, patterns] of Object.entries(DEFAULT_KEYWORD_PATTERNS)) {
|
|
389
|
+
// Match pattern type to project ID
|
|
390
|
+
if (projectId.includes(patternType) || patternType.includes(projectId.split('-')[0])) {
|
|
391
|
+
for (const pattern of patterns) {
|
|
392
|
+
if (content.includes(pattern)) {
|
|
393
|
+
if (!matchedKeywords.includes(pattern)) {
|
|
394
|
+
matchedKeywords.push(pattern);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (matchedKeywords.length > 0) {
|
|
401
|
+
// Calculate confidence based on number of matches
|
|
402
|
+
const confidence = Math.min(0.9, 0.3 + (matchedKeywords.length * 0.15));
|
|
403
|
+
results.push({
|
|
404
|
+
projectId: project.id,
|
|
405
|
+
confidence,
|
|
406
|
+
matchedKeywords
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return results;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Resolve project context for an entire increment description
|
|
414
|
+
*/
|
|
415
|
+
resolveForIncrement(incrementDescription) {
|
|
416
|
+
// Use CrossCuttingDetector for sophisticated analysis
|
|
417
|
+
const crossCuttingResult = this.crossCuttingDetector.detect(incrementDescription);
|
|
418
|
+
const isCrossProject = crossCuttingResult.isCrossCutting;
|
|
419
|
+
// Get default project
|
|
420
|
+
let defaultProject = this.structureConfig.projects[0]?.id ?? 'default';
|
|
421
|
+
let defaultBoard;
|
|
422
|
+
// Build suggestions map from cross-cutting detection
|
|
423
|
+
const suggestions = new Map();
|
|
424
|
+
if (!isCrossProject && crossCuttingResult.suggestedProjects.length === 1) {
|
|
425
|
+
// Single project detected - use it as default
|
|
426
|
+
const suggestedType = crossCuttingResult.suggestedProjects[0];
|
|
427
|
+
const mappedProject = this.mapSuggestedTypeToProject(suggestedType);
|
|
428
|
+
if (mappedProject) {
|
|
429
|
+
defaultProject = mappedProject;
|
|
430
|
+
suggestions.set('default', {
|
|
431
|
+
resolved: true,
|
|
432
|
+
projectId: mappedProject,
|
|
433
|
+
confidence: crossCuttingResult.confidence,
|
|
434
|
+
reason: crossCuttingResult.reason ?? `Detected: ${suggestedType}`
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
else if (isCrossProject) {
|
|
439
|
+
// Multiple projects detected - build suggestions per detected type
|
|
440
|
+
for (const suggestedType of crossCuttingResult.suggestedProjects) {
|
|
441
|
+
const mappedProject = this.mapSuggestedTypeToProject(suggestedType);
|
|
442
|
+
if (mappedProject) {
|
|
443
|
+
const patterns = crossCuttingResult.detectedPatterns
|
|
444
|
+
.filter(p => p.suggestedProject === suggestedType);
|
|
445
|
+
suggestions.set(suggestedType, {
|
|
446
|
+
resolved: true,
|
|
447
|
+
projectId: mappedProject,
|
|
448
|
+
confidence: crossCuttingResult.confidence,
|
|
449
|
+
reason: `Detected ${suggestedType} patterns`,
|
|
450
|
+
matchedKeywords: patterns.map(p => p.matched)
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
// Use first detected project as default
|
|
455
|
+
if (crossCuttingResult.suggestedProjects.length > 0) {
|
|
456
|
+
const firstType = crossCuttingResult.suggestedProjects[0];
|
|
457
|
+
const mappedProject = this.mapSuggestedTypeToProject(firstType);
|
|
458
|
+
if (mappedProject) {
|
|
459
|
+
defaultProject = mappedProject;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
// Fallback to simple resolution
|
|
465
|
+
const resolution = this.resolveForUserStory(incrementDescription);
|
|
466
|
+
if (resolution.resolved && resolution.projectId) {
|
|
467
|
+
defaultProject = resolution.projectId;
|
|
468
|
+
suggestions.set('default', resolution);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
// For 2-level, also resolve default board
|
|
472
|
+
if (this.structureConfig.level === 2 && defaultProject) {
|
|
473
|
+
const boardResolution = this.resolveBoard(incrementDescription, defaultProject);
|
|
474
|
+
if (boardResolution.resolved && boardResolution.boardId) {
|
|
475
|
+
defaultBoard = boardResolution.boardId;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return {
|
|
479
|
+
isCrossProject,
|
|
480
|
+
defaultProject,
|
|
481
|
+
defaultBoard,
|
|
482
|
+
suggestions,
|
|
483
|
+
structureLevel: this.structureConfig.level,
|
|
484
|
+
crossCuttingResult,
|
|
485
|
+
detectedPatterns: crossCuttingResult.detectedPatterns
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Detect if description indicates cross-project work
|
|
490
|
+
*/
|
|
491
|
+
detectCrossProject(description) {
|
|
492
|
+
// Keywords that indicate cross-project work
|
|
493
|
+
const crossProjectIndicators = [
|
|
494
|
+
'frontend and backend',
|
|
495
|
+
'fe and be',
|
|
496
|
+
'client and server',
|
|
497
|
+
'mobile and api',
|
|
498
|
+
'multiple repos',
|
|
499
|
+
'across projects',
|
|
500
|
+
'shared between',
|
|
501
|
+
'full stack',
|
|
502
|
+
'end to end',
|
|
503
|
+
'e2e'
|
|
504
|
+
];
|
|
505
|
+
for (const indicator of crossProjectIndicators) {
|
|
506
|
+
if (description.includes(indicator)) {
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
// Count distinct project-type keywords
|
|
511
|
+
const projectTypes = new Set();
|
|
512
|
+
if (this.matchesKeywords(description, DEFAULT_KEYWORD_PATTERNS.frontend)) {
|
|
513
|
+
projectTypes.add('frontend');
|
|
514
|
+
}
|
|
515
|
+
if (this.matchesKeywords(description, DEFAULT_KEYWORD_PATTERNS.backend)) {
|
|
516
|
+
projectTypes.add('backend');
|
|
517
|
+
}
|
|
518
|
+
if (this.matchesKeywords(description, DEFAULT_KEYWORD_PATTERNS.mobile)) {
|
|
519
|
+
projectTypes.add('mobile');
|
|
520
|
+
}
|
|
521
|
+
if (this.matchesKeywords(description, DEFAULT_KEYWORD_PATTERNS.infrastructure)) {
|
|
522
|
+
projectTypes.add('infrastructure');
|
|
523
|
+
}
|
|
524
|
+
return projectTypes.size >= 2;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Check if content matches any keywords
|
|
528
|
+
*/
|
|
529
|
+
matchesKeywords(content, keywords) {
|
|
530
|
+
return keywords.some(k => content.includes(k.toLowerCase()));
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Detect cross-cutting concerns using the integrated detector
|
|
534
|
+
* Returns full detection result for advanced use cases
|
|
535
|
+
*/
|
|
536
|
+
detectCrossCuttingConcerns(description) {
|
|
537
|
+
return this.crossCuttingDetector.detect(description);
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Get the cross-cutting detector instance for direct access
|
|
541
|
+
*/
|
|
542
|
+
getCrossCuttingDetector() {
|
|
543
|
+
return this.crossCuttingDetector;
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Format available projects for display
|
|
547
|
+
*/
|
|
548
|
+
formatProjectsForDisplay() {
|
|
549
|
+
const lines = [];
|
|
550
|
+
lines.push(`Structure Level: ${this.structureConfig.level}-level`);
|
|
551
|
+
lines.push('');
|
|
552
|
+
lines.push('Available Projects:');
|
|
553
|
+
for (const project of this.structureConfig.projects) {
|
|
554
|
+
lines.push(` - ${project.id}${project.name !== project.id ? ` (${project.name})` : ''}`);
|
|
555
|
+
if (this.structureConfig.level === 2 && this.structureConfig.boardsByProject) {
|
|
556
|
+
const boards = this.structureConfig.boardsByProject[project.id] ?? [];
|
|
557
|
+
for (const board of boards) {
|
|
558
|
+
lines.push(` └── ${board.id}${board.name !== board.id ? ` (${board.name})` : ''}`);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return lines.join('\n');
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Create a project resolver instance (sync - no pattern learning)
|
|
567
|
+
*/
|
|
568
|
+
export function createProjectResolver(projectRoot, options = {}) {
|
|
569
|
+
return new ProjectResolver(projectRoot, { logger: options.logger });
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Create a project resolver instance with pattern learning (async)
|
|
573
|
+
*
|
|
574
|
+
* This awaits learnFromExistingSpecs() to ensure patterns are available
|
|
575
|
+
* before the resolver is used.
|
|
576
|
+
*/
|
|
577
|
+
export async function createProjectResolverWithPatterns(projectRoot, options = {}) {
|
|
578
|
+
const resolver = new ProjectResolver(projectRoot, { logger: options.logger });
|
|
579
|
+
try {
|
|
580
|
+
await resolver.learnFromExistingSpecs();
|
|
581
|
+
}
|
|
582
|
+
catch {
|
|
583
|
+
// Pattern learning is optional - continue without it
|
|
584
|
+
}
|
|
585
|
+
return resolver;
|
|
586
|
+
}
|
|
587
|
+
//# sourceMappingURL=project-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-resolver.js","sourceRoot":"","sources":["../../../src/utils/project-resolver.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "0.33.
|
|
3
|
+
"version": "0.33.3",
|
|
4
4
|
"description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,6 +50,16 @@
|
|
|
50
50
|
}
|
|
51
51
|
]
|
|
52
52
|
},
|
|
53
|
+
{
|
|
54
|
+
"matcher": "Write",
|
|
55
|
+
"matcher_content": "\\.specweave/increments/\\d{3,4}E?-[^/]+/spec\\.md",
|
|
56
|
+
"hooks": [
|
|
57
|
+
{
|
|
58
|
+
"type": "command",
|
|
59
|
+
"command": "bash -c 'W=\"${CLAUDE_PLUGIN_ROOT}/hooks/universal/fail-fast-wrapper.sh\"; S=\"${CLAUDE_PLUGIN_ROOT}/hooks/v2/guards/per-us-project-validator.sh\"; [[ -x \"$W\" ]] && exec \"$W\" \"$S\" || (cat >/dev/null && printf \"{\\\"decision\\\":\\\"allow\\\"}\")'"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
53
63
|
{
|
|
54
64
|
"matcher": "Write|Edit",
|
|
55
65
|
"matcher_content": "\\.specweave/docs/internal/specs/_features/",
|