sdd-mcp-server 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/services/AnswerValidator.d.ts +7 -0
- package/dist/application/services/AnswerValidator.js +52 -0
- package/dist/application/services/AnswerValidator.js.map +1 -0
- package/dist/application/services/DescriptionAnalyzer.d.ts +28 -0
- package/dist/application/services/DescriptionAnalyzer.js +184 -0
- package/dist/application/services/DescriptionAnalyzer.js.map +1 -0
- package/dist/application/services/DescriptionEnricher.d.ts +15 -0
- package/dist/application/services/DescriptionEnricher.js +77 -0
- package/dist/application/services/DescriptionEnricher.js.map +1 -0
- package/dist/application/services/QuestionGenerator.d.ts +7 -0
- package/dist/application/services/QuestionGenerator.js +30 -0
- package/dist/application/services/QuestionGenerator.js.map +1 -0
- package/dist/application/services/RequirementsClarificationService.d.ts +22 -51
- package/dist/application/services/RequirementsClarificationService.js +44 -419
- package/dist/application/services/RequirementsClarificationService.js.map +1 -1
- package/dist/application/services/SteeringContextLoader.d.ts +11 -0
- package/dist/application/services/SteeringContextLoader.js +90 -0
- package/dist/application/services/SteeringContextLoader.js.map +1 -0
- package/dist/application/services/clarification-questions.d.ts +15 -0
- package/dist/application/services/clarification-questions.js +99 -0
- package/dist/application/services/clarification-questions.js.map +1 -0
- package/dist/domain/types.d.ts +17 -0
- package/dist/infrastructure/di/container.js +18 -0
- package/dist/infrastructure/di/container.js.map +1 -1
- package/dist/infrastructure/di/types.d.ts +5 -0
- package/dist/infrastructure/di/types.js +5 -0
- package/dist/infrastructure/di/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ClarificationQuestion, ClarificationAnswers, AnswerValidationResult } from "../../domain/types.js";
|
|
2
|
+
export declare class AnswerValidator {
|
|
3
|
+
/**
|
|
4
|
+
* Validate user-provided clarification answers
|
|
5
|
+
*/
|
|
6
|
+
validate(questions: ClarificationQuestion[], answers: ClarificationAnswers): AnswerValidationResult;
|
|
7
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { injectable } from "inversify";
|
|
8
|
+
import { ANSWER_VALIDATION } from "./clarification-constants.js";
|
|
9
|
+
let AnswerValidator = class AnswerValidator {
|
|
10
|
+
/**
|
|
11
|
+
* Validate user-provided clarification answers
|
|
12
|
+
*/
|
|
13
|
+
validate(questions, answers) {
|
|
14
|
+
const missingRequired = [];
|
|
15
|
+
const tooShort = [];
|
|
16
|
+
const containsInvalidContent = [];
|
|
17
|
+
for (const question of questions) {
|
|
18
|
+
const answer = answers[question.id]?.trim() || "";
|
|
19
|
+
// Check for missing required answers
|
|
20
|
+
if (question.required && !answer) {
|
|
21
|
+
missingRequired.push(question.question);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
// Check for too-short answers
|
|
25
|
+
if (answer && answer.length < ANSWER_VALIDATION.MIN_ANSWER_LENGTH) {
|
|
26
|
+
tooShort.push({
|
|
27
|
+
question: question.question,
|
|
28
|
+
minLength: ANSWER_VALIDATION.MIN_ANSWER_LENGTH,
|
|
29
|
+
currentLength: answer.length,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// Check for potentially malicious content
|
|
33
|
+
if (answer && ANSWER_VALIDATION.INVALID_CONTENT_PATTERN.test(answer)) {
|
|
34
|
+
containsInvalidContent.push(question.question);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const valid = missingRequired.length === 0 &&
|
|
38
|
+
tooShort.length === 0 &&
|
|
39
|
+
containsInvalidContent.length === 0;
|
|
40
|
+
return {
|
|
41
|
+
valid,
|
|
42
|
+
missingRequired,
|
|
43
|
+
tooShort,
|
|
44
|
+
containsInvalidContent,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
AnswerValidator = __decorate([
|
|
49
|
+
injectable()
|
|
50
|
+
], AnswerValidator);
|
|
51
|
+
export { AnswerValidator };
|
|
52
|
+
//# sourceMappingURL=AnswerValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnswerValidator.js","sourceRoot":"","sources":["../../../src/application/services/AnswerValidator.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAMvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAG1D,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B;;OAEG;IACH,QAAQ,CACN,SAAkC,EAClC,OAA6B;QAE7B,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,MAAM,QAAQ,GAIT,EAAE,CAAC;QACR,MAAM,sBAAsB,GAAa,EAAE,CAAC;QAE5C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAElD,qCAAqC;YACrC,IAAI,QAAQ,CAAC,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACxC,SAAS;YACX,CAAC;YAED,8BAA8B;YAC9B,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,iBAAiB,CAAC,iBAAiB,EAAE,CAAC;gBAClE,QAAQ,CAAC,IAAI,CAAC;oBACZ,QAAQ,EAAE,QAAQ,CAAC,QAAQ;oBAC3B,SAAS,EAAE,iBAAiB,CAAC,iBAAiB;oBAC9C,aAAa,EAAE,MAAM,CAAC,MAAM;iBAC7B,CAAC,CAAC;YACL,CAAC;YAED,0CAA0C;YAC1C,IAAI,MAAM,IAAI,iBAAiB,CAAC,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrE,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GACT,eAAe,CAAC,MAAM,KAAK,CAAC;YAC5B,QAAQ,CAAC,MAAM,KAAK,CAAC;YACrB,sBAAsB,CAAC,MAAM,KAAK,CAAC,CAAC;QAEtC,OAAO;YACL,KAAK;YACL,eAAe;YACf,QAAQ;YACR,sBAAsB;SACvB,CAAC;IACJ,CAAC;CACF,CAAA;AApDY,eAAe;IAD3B,UAAU,EAAE;GACA,eAAe,CAoD3B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ClarificationAnalysis, SteeringContext } from "../../domain/types.js";
|
|
2
|
+
export declare class DescriptionAnalyzer {
|
|
3
|
+
/**
|
|
4
|
+
* Analyzes a project description for completeness using scored semantic detection
|
|
5
|
+
*/
|
|
6
|
+
analyze(description: string, context: SteeringContext): ClarificationAnalysis;
|
|
7
|
+
/**
|
|
8
|
+
* Score semantic presence using keyword density approach
|
|
9
|
+
* Returns 0-100 based on presence and density of matching patterns
|
|
10
|
+
*/
|
|
11
|
+
private scoreSemanticPresence;
|
|
12
|
+
/**
|
|
13
|
+
* Detect ambiguous terms in the description
|
|
14
|
+
*/
|
|
15
|
+
private detectAmbiguousTerms;
|
|
16
|
+
/**
|
|
17
|
+
* Calculate overall quality score based on presence of elements
|
|
18
|
+
*/
|
|
19
|
+
private calculateQualityScore;
|
|
20
|
+
/**
|
|
21
|
+
* Identify which elements are missing considering steering context
|
|
22
|
+
*/
|
|
23
|
+
private identifyMissingElements;
|
|
24
|
+
/**
|
|
25
|
+
* Extract context around a matched term for better clarity
|
|
26
|
+
*/
|
|
27
|
+
private extractContext;
|
|
28
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { injectable } from "inversify";
|
|
8
|
+
import { QUALITY_SCORE_WEIGHTS, PATTERN_DETECTION, AMBIGUOUS_TERMS, } from "./clarification-constants.js";
|
|
9
|
+
let DescriptionAnalyzer = class DescriptionAnalyzer {
|
|
10
|
+
/**
|
|
11
|
+
* Analyzes a project description for completeness using scored semantic detection
|
|
12
|
+
*/
|
|
13
|
+
analyze(description, context) {
|
|
14
|
+
// Handle empty descriptions
|
|
15
|
+
if (!description || description.trim().length === 0) {
|
|
16
|
+
return {
|
|
17
|
+
qualityScore: 0,
|
|
18
|
+
whyScore: 0,
|
|
19
|
+
whoScore: 0,
|
|
20
|
+
whatScore: 0,
|
|
21
|
+
successScore: 0,
|
|
22
|
+
hasWhy: false,
|
|
23
|
+
hasWho: false,
|
|
24
|
+
hasWhat: false,
|
|
25
|
+
hasSuccessCriteria: false,
|
|
26
|
+
missingElements: ["WHY", "WHO", "WHAT", "Success Criteria"],
|
|
27
|
+
ambiguousTerms: [],
|
|
28
|
+
needsClarification: true,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// Calculate semantic scores (0-100 each)
|
|
32
|
+
const whyScore = this.scoreSemanticPresence(description, PATTERN_DETECTION.WHY_PATTERNS);
|
|
33
|
+
const whoScore = this.scoreSemanticPresence(description, PATTERN_DETECTION.WHO_PATTERNS);
|
|
34
|
+
const whatScore = this.scoreSemanticPresence(description, PATTERN_DETECTION.WHAT_PATTERNS);
|
|
35
|
+
const successScore = this.scoreSemanticPresence(description, PATTERN_DETECTION.SUCCESS_PATTERNS);
|
|
36
|
+
// Derive boolean presence (threshold: 30%)
|
|
37
|
+
const hasWhy = whyScore > 30;
|
|
38
|
+
const hasWho = whoScore > 30;
|
|
39
|
+
const hasWhat = whatScore > 30;
|
|
40
|
+
const hasSuccessCriteria = successScore > 30;
|
|
41
|
+
// Detect ambiguous terms
|
|
42
|
+
const ambiguousTerms = this.detectAmbiguousTerms(description);
|
|
43
|
+
// Calculate overall quality score
|
|
44
|
+
const qualityScore = this.calculateQualityScore({
|
|
45
|
+
hasWhy,
|
|
46
|
+
hasWho,
|
|
47
|
+
hasWhat,
|
|
48
|
+
hasSuccessCriteria,
|
|
49
|
+
ambiguousTermCount: ambiguousTerms.length,
|
|
50
|
+
descriptionLength: description.length,
|
|
51
|
+
});
|
|
52
|
+
// Determine missing elements considering steering context
|
|
53
|
+
const missingElements = this.identifyMissingElements({ hasWhy, hasWho, hasWhat, hasSuccessCriteria }, context);
|
|
54
|
+
// Need clarification if score below threshold or missing critical elements
|
|
55
|
+
const needsClarification = qualityScore < QUALITY_SCORE_WEIGHTS.MIN_ACCEPTABLE_SCORE ||
|
|
56
|
+
missingElements.length > 0;
|
|
57
|
+
return {
|
|
58
|
+
qualityScore,
|
|
59
|
+
whyScore,
|
|
60
|
+
whoScore,
|
|
61
|
+
whatScore,
|
|
62
|
+
successScore,
|
|
63
|
+
hasWhy,
|
|
64
|
+
hasWho,
|
|
65
|
+
hasWhat,
|
|
66
|
+
hasSuccessCriteria,
|
|
67
|
+
missingElements,
|
|
68
|
+
ambiguousTerms,
|
|
69
|
+
needsClarification,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Score semantic presence using keyword density approach
|
|
74
|
+
* Returns 0-100 based on presence and density of matching patterns
|
|
75
|
+
*/
|
|
76
|
+
scoreSemanticPresence(description, patterns) {
|
|
77
|
+
const words = description
|
|
78
|
+
.toLowerCase()
|
|
79
|
+
.split(/\s+/)
|
|
80
|
+
.filter((w) => w.length > 0);
|
|
81
|
+
if (words.length === 0)
|
|
82
|
+
return 0;
|
|
83
|
+
const matchedWords = words.filter((word) => patterns.some((pattern) => pattern.test(word)));
|
|
84
|
+
if (matchedWords.length === 0)
|
|
85
|
+
return 0;
|
|
86
|
+
// Base score for any presence
|
|
87
|
+
const coverage = 50;
|
|
88
|
+
// Density score based on percentage of matched words
|
|
89
|
+
const density = (matchedWords.length / words.length) * 100;
|
|
90
|
+
// Total score capped at 100
|
|
91
|
+
return Math.min(100, coverage + density);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Detect ambiguous terms in the description
|
|
95
|
+
*/
|
|
96
|
+
detectAmbiguousTerms(description) {
|
|
97
|
+
const ambiguousTerms = [];
|
|
98
|
+
for (const { pattern, suggestion } of AMBIGUOUS_TERMS) {
|
|
99
|
+
const matches = description.match(pattern);
|
|
100
|
+
if (matches) {
|
|
101
|
+
for (const match of matches) {
|
|
102
|
+
const context = this.extractContext(description, match);
|
|
103
|
+
ambiguousTerms.push({
|
|
104
|
+
term: match,
|
|
105
|
+
context,
|
|
106
|
+
suggestion,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return ambiguousTerms;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Calculate overall quality score based on presence of elements
|
|
115
|
+
*/
|
|
116
|
+
calculateQualityScore(metrics) {
|
|
117
|
+
let score = 0;
|
|
118
|
+
// WHY is most important
|
|
119
|
+
if (metrics.hasWhy)
|
|
120
|
+
score += QUALITY_SCORE_WEIGHTS.HAS_WHY;
|
|
121
|
+
// WHO is critical
|
|
122
|
+
if (metrics.hasWho)
|
|
123
|
+
score += QUALITY_SCORE_WEIGHTS.HAS_WHO;
|
|
124
|
+
// WHAT is essential
|
|
125
|
+
if (metrics.hasWhat)
|
|
126
|
+
score += QUALITY_SCORE_WEIGHTS.HAS_WHAT;
|
|
127
|
+
// Success criteria
|
|
128
|
+
if (metrics.hasSuccessCriteria)
|
|
129
|
+
score += QUALITY_SCORE_WEIGHTS.HAS_SUCCESS;
|
|
130
|
+
// Penalize ambiguous terms
|
|
131
|
+
const ambiguityPenalty = Math.min(QUALITY_SCORE_WEIGHTS.MAX_AMBIGUITY_PENALTY, metrics.ambiguousTermCount * QUALITY_SCORE_WEIGHTS.AMBIGUITY_PENALTY);
|
|
132
|
+
score -= ambiguityPenalty;
|
|
133
|
+
// Length bonus - adequate detail
|
|
134
|
+
if (metrics.descriptionLength > QUALITY_SCORE_WEIGHTS.LENGTH_BONUS_THRESHOLD_1)
|
|
135
|
+
score += QUALITY_SCORE_WEIGHTS.LENGTH_BONUS_POINTS;
|
|
136
|
+
if (metrics.descriptionLength > QUALITY_SCORE_WEIGHTS.LENGTH_BONUS_THRESHOLD_2)
|
|
137
|
+
score += QUALITY_SCORE_WEIGHTS.LENGTH_BONUS_POINTS;
|
|
138
|
+
if (metrics.descriptionLength > QUALITY_SCORE_WEIGHTS.LENGTH_BONUS_THRESHOLD_3)
|
|
139
|
+
score += QUALITY_SCORE_WEIGHTS.LENGTH_BONUS_POINTS;
|
|
140
|
+
return Math.max(0, Math.min(100, score));
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Identify which elements are missing considering steering context
|
|
144
|
+
*/
|
|
145
|
+
identifyMissingElements(presence, context) {
|
|
146
|
+
const missing = [];
|
|
147
|
+
// WHY is required unless product context exists
|
|
148
|
+
if (!presence.hasWhy && !context.hasProductContext) {
|
|
149
|
+
missing.push("Business justification (WHY)");
|
|
150
|
+
}
|
|
151
|
+
// WHO is required unless target users documented
|
|
152
|
+
if (!presence.hasWho && !context.hasTargetUsers) {
|
|
153
|
+
missing.push("Target users (WHO)");
|
|
154
|
+
}
|
|
155
|
+
// WHAT is always required
|
|
156
|
+
if (!presence.hasWhat) {
|
|
157
|
+
missing.push("Core features (WHAT)");
|
|
158
|
+
}
|
|
159
|
+
// Success criteria always required
|
|
160
|
+
if (!presence.hasSuccessCriteria) {
|
|
161
|
+
missing.push("Success criteria");
|
|
162
|
+
}
|
|
163
|
+
return missing;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Extract context around a matched term for better clarity
|
|
167
|
+
*/
|
|
168
|
+
extractContext(description, term) {
|
|
169
|
+
const index = description.toLowerCase().indexOf(term.toLowerCase());
|
|
170
|
+
if (index === -1)
|
|
171
|
+
return "";
|
|
172
|
+
const start = Math.max(0, index - 30);
|
|
173
|
+
const end = Math.min(description.length, index + term.length + 30);
|
|
174
|
+
const context = description.substring(start, end);
|
|
175
|
+
return ((start > 0 ? "..." : "") +
|
|
176
|
+
context +
|
|
177
|
+
(end < description.length ? "..." : ""));
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
DescriptionAnalyzer = __decorate([
|
|
181
|
+
injectable()
|
|
182
|
+
], DescriptionAnalyzer);
|
|
183
|
+
export { DescriptionAnalyzer };
|
|
184
|
+
//# sourceMappingURL=DescriptionAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DescriptionAnalyzer.js","sourceRoot":"","sources":["../../../src/application/services/DescriptionAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ClarificationQuestion, ClarificationAnswers, EnrichedProjectDescription } from "../../domain/types.js";
|
|
2
|
+
export declare class DescriptionEnricher {
|
|
3
|
+
/**
|
|
4
|
+
* Synthesize enriched project description from original + clarification answers
|
|
5
|
+
*/
|
|
6
|
+
synthesize(originalDescription: string, questions: ClarificationQuestion[], answers: ClarificationAnswers): EnrichedProjectDescription;
|
|
7
|
+
/**
|
|
8
|
+
* Extract all answers for a specific question category
|
|
9
|
+
*/
|
|
10
|
+
private extractAnswersByCategory;
|
|
11
|
+
/**
|
|
12
|
+
* Build enriched description with 5W1H structure
|
|
13
|
+
*/
|
|
14
|
+
private buildEnrichedDescription;
|
|
15
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { injectable } from "inversify";
|
|
8
|
+
import { QuestionCategory, } from "../../domain/types.js";
|
|
9
|
+
let DescriptionEnricher = class DescriptionEnricher {
|
|
10
|
+
/**
|
|
11
|
+
* Synthesize enriched project description from original + clarification answers
|
|
12
|
+
*/
|
|
13
|
+
synthesize(originalDescription, questions, answers) {
|
|
14
|
+
const why = this.extractAnswersByCategory(questions, answers, QuestionCategory.WHY);
|
|
15
|
+
const who = this.extractAnswersByCategory(questions, answers, QuestionCategory.WHO);
|
|
16
|
+
const what = this.extractAnswersByCategory(questions, answers, QuestionCategory.WHAT);
|
|
17
|
+
const how = this.extractAnswersByCategory(questions, answers, QuestionCategory.HOW);
|
|
18
|
+
const successCriteria = this.extractAnswersByCategory(questions, answers, QuestionCategory.SUCCESS);
|
|
19
|
+
const enriched = this.buildEnrichedDescription({
|
|
20
|
+
original: originalDescription,
|
|
21
|
+
why,
|
|
22
|
+
who,
|
|
23
|
+
what,
|
|
24
|
+
how,
|
|
25
|
+
successCriteria,
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
original: originalDescription,
|
|
29
|
+
why,
|
|
30
|
+
who,
|
|
31
|
+
what,
|
|
32
|
+
how,
|
|
33
|
+
successCriteria,
|
|
34
|
+
enriched,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Extract all answers for a specific question category
|
|
39
|
+
*/
|
|
40
|
+
extractAnswersByCategory(questions, answers, category) {
|
|
41
|
+
const categoryQuestions = questions.filter((q) => q.category === category);
|
|
42
|
+
const categoryAnswers = categoryQuestions
|
|
43
|
+
.map((q) => answers[q.id])
|
|
44
|
+
.filter((a) => a && a.trim().length > 0);
|
|
45
|
+
return categoryAnswers.join(" ");
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build enriched description with 5W1H structure
|
|
49
|
+
*/
|
|
50
|
+
buildEnrichedDescription(components) {
|
|
51
|
+
const parts = [];
|
|
52
|
+
if (components.original) {
|
|
53
|
+
parts.push(`## Original Description\n${components.original}`);
|
|
54
|
+
}
|
|
55
|
+
if (components.why) {
|
|
56
|
+
parts.push(`## Business Justification (Why)\n${components.why}`);
|
|
57
|
+
}
|
|
58
|
+
if (components.who) {
|
|
59
|
+
parts.push(`## Target Users (Who)\n${components.who}`);
|
|
60
|
+
}
|
|
61
|
+
if (components.what) {
|
|
62
|
+
parts.push(`## Core Features (What)\n${components.what}`);
|
|
63
|
+
}
|
|
64
|
+
if (components.how) {
|
|
65
|
+
parts.push(`## Technical Approach (How)\n${components.how}`);
|
|
66
|
+
}
|
|
67
|
+
if (components.successCriteria) {
|
|
68
|
+
parts.push(`## Success Criteria\n${components.successCriteria}`);
|
|
69
|
+
}
|
|
70
|
+
return parts.join("\n\n");
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
DescriptionEnricher = __decorate([
|
|
74
|
+
injectable()
|
|
75
|
+
], DescriptionEnricher);
|
|
76
|
+
export { DescriptionEnricher };
|
|
77
|
+
//# sourceMappingURL=DescriptionEnricher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DescriptionEnricher.js","sourceRoot":"","sources":["../../../src/application/services/DescriptionEnricher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ClarificationQuestion, ClarificationAnalysis, SteeringContext } from "../../domain/types.js";
|
|
2
|
+
export declare class QuestionGenerator {
|
|
3
|
+
/**
|
|
4
|
+
* Generate clarification questions based on analysis and steering context
|
|
5
|
+
*/
|
|
6
|
+
generateQuestions(analysis: ClarificationAnalysis, context: SteeringContext): ClarificationQuestion[];
|
|
7
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { injectable } from "inversify";
|
|
8
|
+
import { CLARIFICATION_QUESTIONS } from "./clarification-questions.js";
|
|
9
|
+
let QuestionGenerator = class QuestionGenerator {
|
|
10
|
+
/**
|
|
11
|
+
* Generate clarification questions based on analysis and steering context
|
|
12
|
+
*/
|
|
13
|
+
generateQuestions(analysis, context) {
|
|
14
|
+
return Object.values(CLARIFICATION_QUESTIONS)
|
|
15
|
+
.filter((template) => template.condition(analysis, context))
|
|
16
|
+
.map((template) => ({
|
|
17
|
+
id: template.id,
|
|
18
|
+
category: template.category,
|
|
19
|
+
question: template.question,
|
|
20
|
+
why: template.rationale,
|
|
21
|
+
examples: template.examples,
|
|
22
|
+
required: template.required,
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
QuestionGenerator = __decorate([
|
|
27
|
+
injectable()
|
|
28
|
+
], QuestionGenerator);
|
|
29
|
+
export { QuestionGenerator };
|
|
30
|
+
//# sourceMappingURL=QuestionGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuestionGenerator.js","sourceRoot":"","sources":["../../../src/application/services/QuestionGenerator.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAMvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAC5B;;OAEG;IACH,iBAAiB,CACf,QAA+B,EAC/B,OAAwB;QAExB,OAAO,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC;aAC1C,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;aAC3D,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAClB,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,GAAG,EAAE,QAAQ,CAAC,SAAS;YACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;SAC5B,CAAC,CAAC,CAAC;IACR,CAAC;CACF,CAAA;AAnBY,iBAAiB;IAD7B,UAAU,EAAE;GACA,iBAAiB,CAmB7B"}
|
|
@@ -1,9 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LoggerPort } from "../../domain/ports.js";
|
|
2
2
|
import { ClarificationQuestion, EnrichedProjectDescription, ClarificationResult, ClarificationAnswers, AnswerValidationResult } from "../../domain/types.js";
|
|
3
|
+
import { SteeringContextLoader } from "./SteeringContextLoader.js";
|
|
4
|
+
import { DescriptionAnalyzer } from "./DescriptionAnalyzer.js";
|
|
5
|
+
import { QuestionGenerator } from "./QuestionGenerator.js";
|
|
6
|
+
import { AnswerValidator } from "./AnswerValidator.js";
|
|
7
|
+
import { DescriptionEnricher } from "./DescriptionEnricher.js";
|
|
8
|
+
/**
|
|
9
|
+
* Orchestrator service for requirements clarification workflow
|
|
10
|
+
*
|
|
11
|
+
* Delegates to specialized services:
|
|
12
|
+
* - SteeringContextLoader: Loads steering documents
|
|
13
|
+
* - DescriptionAnalyzer: Analyzes description quality
|
|
14
|
+
* - QuestionGenerator: Generates clarification questions
|
|
15
|
+
* - AnswerValidator: Validates user answers
|
|
16
|
+
* - DescriptionEnricher: Synthesizes enriched descriptions
|
|
17
|
+
*/
|
|
3
18
|
export declare class RequirementsClarificationService {
|
|
4
|
-
private readonly fileSystem;
|
|
5
19
|
private readonly logger;
|
|
6
|
-
|
|
20
|
+
private readonly steeringLoader;
|
|
21
|
+
private readonly analyzer;
|
|
22
|
+
private readonly questionGenerator;
|
|
23
|
+
private readonly answerValidator;
|
|
24
|
+
private readonly enricher;
|
|
25
|
+
constructor(logger: LoggerPort, steeringLoader: SteeringContextLoader, analyzer: DescriptionAnalyzer, questionGenerator: QuestionGenerator, answerValidator: AnswerValidator, enricher: DescriptionEnricher);
|
|
7
26
|
/**
|
|
8
27
|
* Analyzes a project description to determine if clarification is needed
|
|
9
28
|
*/
|
|
@@ -16,52 +35,4 @@ export declare class RequirementsClarificationService {
|
|
|
16
35
|
* Synthesizes an enriched project description from original + answers
|
|
17
36
|
*/
|
|
18
37
|
synthesizeDescription(originalDescription: string, questions: ClarificationQuestion[], answers: ClarificationAnswers): EnrichedProjectDescription;
|
|
19
|
-
/**
|
|
20
|
-
* Performs the core analysis of the description
|
|
21
|
-
*/
|
|
22
|
-
private performAnalysis;
|
|
23
|
-
/**
|
|
24
|
-
* Generates targeted clarification questions based on analysis
|
|
25
|
-
*/
|
|
26
|
-
private generateQuestions;
|
|
27
|
-
/**
|
|
28
|
-
* Load steering documents for context
|
|
29
|
-
*/
|
|
30
|
-
private loadSteeringContext;
|
|
31
|
-
/**
|
|
32
|
-
* Detects if description contains WHY (business justification)
|
|
33
|
-
*/
|
|
34
|
-
private detectWhy;
|
|
35
|
-
/**
|
|
36
|
-
* Detects if description contains WHO (target users)
|
|
37
|
-
*/
|
|
38
|
-
private detectWho;
|
|
39
|
-
/**
|
|
40
|
-
* Detects if description contains WHAT (features, scope)
|
|
41
|
-
*/
|
|
42
|
-
private detectWhat;
|
|
43
|
-
/**
|
|
44
|
-
* Detects if description contains success criteria
|
|
45
|
-
*/
|
|
46
|
-
private detectSuccessCriteria;
|
|
47
|
-
/**
|
|
48
|
-
* Detects ambiguous terms that need clarification
|
|
49
|
-
*/
|
|
50
|
-
private detectAmbiguousTerms;
|
|
51
|
-
/**
|
|
52
|
-
* Extracts surrounding context for an ambiguous term
|
|
53
|
-
*/
|
|
54
|
-
private extractContext;
|
|
55
|
-
/**
|
|
56
|
-
* Calculates quality score based on completeness and clarity
|
|
57
|
-
*/
|
|
58
|
-
private calculateQualityScore;
|
|
59
|
-
/**
|
|
60
|
-
* Extracts answers for a specific category
|
|
61
|
-
*/
|
|
62
|
-
private extractAnswersByCategory;
|
|
63
|
-
/**
|
|
64
|
-
* Builds the enriched description from all components
|
|
65
|
-
*/
|
|
66
|
-
private buildEnrichedDescription;
|
|
67
38
|
}
|