common-qa-mcp 0.6.0 → 0.7.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.
Files changed (37) hide show
  1. package/README.md +37 -79
  2. package/dist/adapters/remoteMcp/adapter.d.ts +3 -0
  3. package/dist/adapters/remoteMcp/adapter.d.ts.map +1 -1
  4. package/dist/adapters/remoteMcp/adapter.js +1 -1
  5. package/dist/adapters/remoteMcp/adapter.js.map +1 -1
  6. package/dist/adapters/simplifyqa/adapter.d.ts +19 -0
  7. package/dist/adapters/simplifyqa/adapter.d.ts.map +1 -1
  8. package/dist/adapters/simplifyqa/adapter.js +69 -6
  9. package/dist/adapters/simplifyqa/adapter.js.map +1 -1
  10. package/dist/adapters/simplifyqa/mapper.d.ts.map +1 -1
  11. package/dist/adapters/simplifyqa/mapper.js +10 -0
  12. package/dist/adapters/simplifyqa/mapper.js.map +1 -1
  13. package/dist/adapters/types.d.ts +8 -3
  14. package/dist/adapters/types.d.ts.map +1 -1
  15. package/dist/domain/types.d.ts +10 -0
  16. package/dist/domain/types.d.ts.map +1 -1
  17. package/dist/initAgents.d.ts.map +1 -1
  18. package/dist/initAgents.js +101 -15
  19. package/dist/initAgents.js.map +1 -1
  20. package/dist/server.d.ts.map +1 -1
  21. package/dist/server.js +95 -1
  22. package/dist/server.js.map +1 -1
  23. package/dist/tools/gapAnalysis.tools.d.ts +31 -0
  24. package/dist/tools/gapAnalysis.tools.d.ts.map +1 -0
  25. package/dist/tools/gapAnalysis.tools.js +287 -0
  26. package/dist/tools/gapAnalysis.tools.js.map +1 -0
  27. package/dist/tools/impactAnalysis.tools.d.ts +17 -0
  28. package/dist/tools/impactAnalysis.tools.d.ts.map +1 -0
  29. package/dist/tools/impactAnalysis.tools.js +352 -0
  30. package/dist/tools/impactAnalysis.tools.js.map +1 -0
  31. package/dist/tools/objects.tools.d.ts.map +1 -1
  32. package/dist/tools/objects.tools.js +63 -12
  33. package/dist/tools/objects.tools.js.map +1 -1
  34. package/dist/tools/testcase.tools.d.ts.map +1 -1
  35. package/dist/tools/testcase.tools.js +9 -3
  36. package/dist/tools/testcase.tools.js.map +1 -1
  37. package/package.json +1 -1
@@ -0,0 +1,287 @@
1
+ import { z } from 'zod';
2
+ import { ok, err } from '../mcpResult.js';
3
+ import { computeDrift } from './storySync.tools.js';
4
+ const NOT_CONNECTED = 'Not connected to a product. Use qa_connect first — gap_analysis needs a live backend.';
5
+ // ponytail: fixed concurrency; raise if a real 500-story sprint feels slow.
6
+ const CONCURRENCY = 8;
7
+ const DEFAULT_SCAN_LIMIT = 500;
8
+ async function parallelMap(items, limit, fn) {
9
+ const out = new Array(items.length);
10
+ let cursor = 0;
11
+ async function worker() {
12
+ while (cursor < items.length) {
13
+ const i = cursor++;
14
+ out[i] = await fn(items[i]);
15
+ }
16
+ }
17
+ const workers = Array.from({ length: Math.min(limit, items.length) }, () => worker());
18
+ await Promise.all(workers);
19
+ return out;
20
+ }
21
+ function totalOf(rows) {
22
+ const t = rows.totalCount;
23
+ return typeof t === 'number' ? t : undefined;
24
+ }
25
+ function escCell(v) {
26
+ return String(v ?? '').replace(/\|/g, '\\|').replace(/\r?\n/g, ' ');
27
+ }
28
+ async function resolveScope(adapter, input, scanLimit) {
29
+ if (input.sprintId) {
30
+ const stories = await adapter.listStories({ sprintId: input.sprintId, limit: scanLimit });
31
+ return { kind: 'sprint', id: input.sprintId, label: `Sprint ${input.sprintId}`, stories, ...(totalOf(stories) && totalOf(stories) > stories.length ? { truncated: true } : {}) };
32
+ }
33
+ if (input.releaseId) {
34
+ const stories = await adapter.listStories({ releaseId: input.releaseId, limit: scanLimit });
35
+ return { kind: 'release', id: input.releaseId, label: `Release ${input.releaseId}`, stories, ...(totalOf(stories) && totalOf(stories) > stories.length ? { truncated: true } : {}) };
36
+ }
37
+ if (input.epicId) {
38
+ const stories = await adapter.listStories({
39
+ limit: scanLimit,
40
+ filters: [{ column: 'epicId', value: input.epicId }],
41
+ });
42
+ return { kind: 'epic', id: input.epicId, label: `Epic ${input.epicId}`, stories };
43
+ }
44
+ if (input.featureId) {
45
+ const stories = await adapter.listStories({
46
+ limit: scanLimit,
47
+ filters: [{ column: 'featureId', value: input.featureId }],
48
+ });
49
+ return { kind: 'feature', id: input.featureId, label: `Feature ${input.featureId}`, stories };
50
+ }
51
+ if (input.storyIds && input.storyIds.length) {
52
+ // Story ids — pull each via getStory (we need ACs downstream anyway) and derive summaries.
53
+ const details = await parallelMap(input.storyIds, CONCURRENCY, (id) => adapter.getStory(id));
54
+ const stories = details.map((s) => ({
55
+ id: s.id,
56
+ ...(s.key ? { key: s.key } : {}),
57
+ title: s.title,
58
+ ...(s.status ? { status: s.status } : {}),
59
+ }));
60
+ return { kind: 'storyIds', id: input.storyIds.join(','), label: `${input.storyIds.length} stor${input.storyIds.length === 1 ? 'y' : 'ies'}`, stories };
61
+ }
62
+ // projectWide
63
+ const stories = await adapter.listStories({ limit: scanLimit });
64
+ return {
65
+ kind: 'project',
66
+ id: 'projectWide',
67
+ label: 'Whole project',
68
+ stories,
69
+ ...(totalOf(stories) && totalOf(stories) > stories.length ? { truncated: true } : {}),
70
+ };
71
+ }
72
+ function classify(acCount, tcCount, uncoveredCount) {
73
+ if (acCount === 0)
74
+ return 'no_ac';
75
+ if (tcCount === 0)
76
+ return 'no_tests';
77
+ if (uncoveredCount > 0)
78
+ return 'partial';
79
+ return 'covered';
80
+ }
81
+ export async function analyzeOneStory(adapter, storyRow, sensitivity) {
82
+ const story = await adapter.getStory(storyRow.id);
83
+ const acList = (story.acceptanceCriteria ?? []).map((s) => s.trim()).filter(Boolean);
84
+ // TCs linked to this story. Manual + automation both count for coverage headcount; only manual
85
+ // gets a drift report (automation TCs have recorded steps, not AC-derived — computeDrift would
86
+ // false-positive `ac_added` on every AC).
87
+ const tcSummaries = await adapter.listTestCases({ storyId: storyRow.id });
88
+ const manualIds = tcSummaries.map((t) => t.id);
89
+ const driftReports = [];
90
+ if (acList.length > 0 && manualIds.length > 0) {
91
+ const tcs = await parallelMap(manualIds, CONCURRENCY, (id) => adapter.getTestCase(id));
92
+ for (const tc of tcs) {
93
+ if (tc.category !== 'manual')
94
+ continue;
95
+ driftReports.push(computeDrift(story, tc, sensitivity));
96
+ }
97
+ }
98
+ // Uncovered = ACs that EVERY manual TC flagged as ac_added (nothing matched them).
99
+ // If no manual TCs ran drift, treat every AC as uncovered.
100
+ let uncoveredAcs;
101
+ if (acList.length === 0) {
102
+ uncoveredAcs = [];
103
+ }
104
+ else if (driftReports.length === 0) {
105
+ uncoveredAcs = acList.slice();
106
+ }
107
+ else {
108
+ uncoveredAcs = acList.filter((ac) => driftReports.every((d) => d.signals.some((s) => s.kind === 'ac_added' && s.text === ac)));
109
+ }
110
+ const verdict = classify(acList.length, tcSummaries.length, uncoveredAcs.length);
111
+ return {
112
+ id: story.id,
113
+ ...(story.key ? { key: story.key } : {}),
114
+ title: story.title,
115
+ acCount: acList.length,
116
+ tcCount: tcSummaries.length,
117
+ verdict,
118
+ uncoveredAcs,
119
+ driftReports,
120
+ };
121
+ }
122
+ async function findOrphanTcs(adapter, scanLimit) {
123
+ // Project-wide TC scan for TCs with an empty storyRef. Only cheap on providers whose listTestCases
124
+ // returns storyRef on summaries — SQA's summaries don't, so we fall back to getTestCase per row.
125
+ // ponytail: bounded by scanLimit; a genuinely huge project would need a dedicated 'orphan-tc' query.
126
+ const summaries = await adapter.listTestCases({ limit: scanLimit });
127
+ const details = await parallelMap(summaries, CONCURRENCY, (s) => adapter.getTestCase(s.id));
128
+ return details
129
+ .filter((tc) => !tc.storyRef || tc.storyRef.trim().length === 0)
130
+ .map((tc) => ({ id: tc.id ?? '', title: tc.title, storyRef: null }));
131
+ }
132
+ function gapScoreFor(counts) {
133
+ if (counts.total === 0)
134
+ return 100;
135
+ return Math.round((100 * (counts.covered + 0.5 * counts.partial)) / counts.total);
136
+ }
137
+ function renderText(scope, stories, orphans, score) {
138
+ const counts = {
139
+ total: stories.length,
140
+ covered: stories.filter((s) => s.verdict === 'covered').length,
141
+ partial: stories.filter((s) => s.verdict === 'partial').length,
142
+ noTests: stories.filter((s) => s.verdict === 'no_tests').length,
143
+ noAc: stories.filter((s) => s.verdict === 'no_ac').length,
144
+ uncoveredAcs: stories.reduce((n, s) => n + s.uncoveredAcs.length, 0),
145
+ orphanTcs: orphans.length,
146
+ };
147
+ const label = score >= 85 ? 'strong' : score >= 60 ? 'ok' : score >= 30 ? 'needs work' : 'critical';
148
+ const truncNote = scope.truncated ? ` _(scan capped at ${stories.length}; raise \`scanLimit\` for full view)_` : '';
149
+ const header = `**${scope.label}** · ${counts.total} stor${counts.total === 1 ? 'y' : 'ies'} · GAP SCORE ${score}/100 (${label})${truncNote}`;
150
+ const summary = `Coverage: ${counts.covered} covered · ${counts.partial} partial · ${counts.noTests} no_tests · ${counts.noAc} no_ac\n` +
151
+ `Signals: ${counts.uncoveredAcs} uncovered AC${counts.uncoveredAcs === 1 ? '' : 's'}${orphans.length ? ` · ${orphans.length} orphan TC${orphans.length === 1 ? '' : 's'}` : ''}`;
152
+ const table = '| story | ACs | TCs | uncovered | verdict |\n|---|---|---|---|---|\n' +
153
+ stories
154
+ .map((s) => `| ${escCell(s.key ?? s.id)} ${escCell(s.title)} | ${s.acCount} | ${s.tcCount} | ${s.verdict === 'no_ac' ? '—' : s.uncoveredAcs.length} | ${s.verdict === 'no_tests' ? 'NO_TESTS' : s.verdict === 'no_ac' ? 'NO_AC' : s.verdict} |`)
155
+ .join('\n');
156
+ const uncoveredList = stories
157
+ .flatMap((s) => s.uncoveredAcs.map((ac) => ` • ${s.key ?? s.id} — ${ac.length > 100 ? ac.slice(0, 97) + '…' : ac}`))
158
+ .slice(0, 10);
159
+ const uncoveredBlock = uncoveredList.length
160
+ ? `\n\nUncovered ACs${uncoveredList.length >= 10 ? ' (top 10)' : ''}:\n${uncoveredList.join('\n')}`
161
+ : '';
162
+ const orphanBlock = orphans.length
163
+ ? `\n\nOrphan TCs (no linked story):\n${orphans.slice(0, 10).map((o) => ` • ${o.id} "${o.title}"`).join('\n')}${orphans.length > 10 ? `\n … and ${orphans.length - 10} more` : ''}`
164
+ : '';
165
+ const actions = [];
166
+ for (const s of stories) {
167
+ if (s.verdict === 'no_tests' && s.acCount > 0) {
168
+ actions.push(` • tc_draft_create for ${s.key ?? s.id} (${s.acCount} AC${s.acCount === 1 ? '' : 's'} — no test yet)`);
169
+ }
170
+ else if (s.verdict === 'partial') {
171
+ for (const d of s.driftReports) {
172
+ if (d.proposedOps.length > 0) {
173
+ actions.push(` • tc_draft_open ${d.testCaseId} → apply ${d.proposedOps.length} op${d.proposedOps.length === 1 ? '' : 's'} for ${s.key ?? s.id}`);
174
+ }
175
+ }
176
+ }
177
+ else if (s.verdict === 'no_ac') {
178
+ actions.push(` • story_update ${s.key ?? s.id} to add acceptanceCriteria`);
179
+ }
180
+ }
181
+ const actionBlock = actions.length
182
+ ? `\n\nNext actions the caller can chain (nothing has been done):\n${actions.slice(0, 15).join('\n')}${actions.length > 15 ? `\n … and ${actions.length - 15} more` : ''}`
183
+ : '';
184
+ return `${header}\n\n${summary}\n\n${table}${uncoveredBlock}${orphanBlock}${actionBlock}`;
185
+ }
186
+ export function registerGapAnalysisTools(server, deps) {
187
+ server.registerTool('gap_analysis', {
188
+ title: 'Coverage / gap report across a scope (sprint, release, epic, feature, stories, project)',
189
+ description: 'Aggregate COVERAGE report — for a chosen scope, walks each story and reports which have no ' +
190
+ 'tests, which have ACs not covered by any linked test case, which have no acceptance criteria ' +
191
+ 'at all, and (for release / projectWide scopes) which TCs are unlinked to any story. ' +
192
+ 'READ-ONLY: writes nothing, but emits a "Next actions" hint block for the agent to chain into ' +
193
+ 'tc_draft_create / tc_draft_open+update+save / story_update after asking the user.\n\n' +
194
+ 'PICK EXACTLY ONE SCOPE — the tool errors if zero or more than one is provided:\n' +
195
+ ' • `sprintId` — recommended for sprint reviews\n' +
196
+ ' • `releaseId` — release readiness across all sprints in the release\n' +
197
+ ' • `epicId` — coverage on one epic\n' +
198
+ ' • `featureId` — coverage on one feature\n' +
199
+ ' • `storyIds[]` — hand-picked batch (or a single story: the same info story_sync_testcases returns, wrapped in the gap format)\n' +
200
+ ' • `projectWide: true` — every story (expensive; prefer a narrower scope when the user\'s ' +
201
+ 'question is really about a sprint / release / area)\n\n' +
202
+ 'Reuses the same AC↔step matching as `story_sync_testcases` (Jaccard, sensitivity strict / ' +
203
+ 'normal / loose). Automation test cases COUNT toward `tcCount` but do NOT run drift ' +
204
+ '(their steps are recorded, not AC-derived — computeDrift would false-flag every AC as ' +
205
+ 'uncovered). Orphan-TC detection runs only for `releaseId` / `projectWide` scopes.\n\n' +
206
+ 'When the user\'s question is about a single story, prefer `story_sync_testcases` if they ' +
207
+ 'want the drift ops to apply; use this tool if they want a coverage verdict / report.',
208
+ inputSchema: {
209
+ sprintId: z.string().optional().describe('Sprint id (from list_sprints).'),
210
+ releaseId: z.string().optional().describe('Release id (from list_releases).'),
211
+ epicId: z.string().optional().describe('Epic numeric id or business key (EP_123).'),
212
+ featureId: z.string().optional().describe('Feature numeric id or business key (FT_123).'),
213
+ storyIds: z.array(z.string()).optional().describe('One or more story ids/keys (US_123).'),
214
+ projectWide: z.boolean().optional().describe('Set true to scan every story in the project (bounded by scanLimit). Prefer a narrower ' +
215
+ 'scope when possible — projectWide fans out into many adapter calls.'),
216
+ sensitivity: z.enum(['strict', 'normal', 'loose']).optional().describe('AC↔step match strictness (same as story_sync_testcases). Default `normal`.'),
217
+ scanLimit: z.number().int().positive().optional().describe('Cap on the initial listStories fetch (and, for release/projectWide, the orphan-TC scan). ' +
218
+ 'Default 500. Raise for a genuinely huge project.'),
219
+ },
220
+ annotations: { readOnlyHint: true },
221
+ }, async (input) => {
222
+ const adapter = deps.getAdapter();
223
+ if (!adapter)
224
+ return err(NOT_CONNECTED);
225
+ if (!adapter.listStories || !adapter.getStory) {
226
+ return err('This product does not expose a user-story backlog — gap_analysis needs listStories + getStory.');
227
+ }
228
+ // Exactly-one-scope guard. `storyIds: []` counts as absent.
229
+ const scopeKeys = [
230
+ input.sprintId ? 'sprintId' : null,
231
+ input.releaseId ? 'releaseId' : null,
232
+ input.epicId ? 'epicId' : null,
233
+ input.featureId ? 'featureId' : null,
234
+ input.storyIds && input.storyIds.length > 0 ? 'storyIds' : null,
235
+ input.projectWide === true ? 'projectWide' : null,
236
+ ].filter(Boolean);
237
+ if (scopeKeys.length === 0) {
238
+ return err('Pick a scope: pass exactly one of `sprintId`, `releaseId`, `epicId`, `featureId`, ' +
239
+ '`storyIds`, or `projectWide: true`. ASK the user which scope fits their question — do not guess.');
240
+ }
241
+ if (scopeKeys.length > 1) {
242
+ return err(`Pick exactly one scope — got ${scopeKeys.length}: ${scopeKeys.join(', ')}.`);
243
+ }
244
+ const sensitivity = input.sensitivity ?? 'normal';
245
+ const scanLimit = input.scanLimit ?? DEFAULT_SCAN_LIMIT;
246
+ try {
247
+ const scope = await resolveScope(adapter, input, scanLimit);
248
+ if (scope.stories.length === 0) {
249
+ return ok(`**${scope.label}** — no stories in scope.`, {
250
+ scope: { kind: scope.kind, id: scope.id, label: scope.label },
251
+ gapScore: 100,
252
+ counts: { total: 0, covered: 0, partial: 0, noTests: 0, noAc: 0, uncoveredAcs: 0, orphanTcs: 0 },
253
+ stories: [],
254
+ orphanTcs: [],
255
+ });
256
+ }
257
+ const stories = await parallelMap(scope.stories, CONCURRENCY, (s) => analyzeOneStory(adapter, s, sensitivity));
258
+ // Orphan TC scan only for release / projectWide — cheaper scopes don't justify a full-project TC read.
259
+ let orphans = [];
260
+ if (scope.kind === 'release' || scope.kind === 'project') {
261
+ orphans = await findOrphanTcs(adapter, scanLimit);
262
+ }
263
+ const counts = {
264
+ total: stories.length,
265
+ covered: stories.filter((s) => s.verdict === 'covered').length,
266
+ partial: stories.filter((s) => s.verdict === 'partial').length,
267
+ noTests: stories.filter((s) => s.verdict === 'no_tests').length,
268
+ noAc: stories.filter((s) => s.verdict === 'no_ac').length,
269
+ uncoveredAcs: stories.reduce((n, s) => n + s.uncoveredAcs.length, 0),
270
+ orphanTcs: orphans.length,
271
+ };
272
+ const gapScore = gapScoreFor(counts);
273
+ const text = renderText(scope, stories, orphans, gapScore);
274
+ return ok(text, {
275
+ scope: { kind: scope.kind, id: scope.id, label: scope.label, ...(scope.truncated ? { truncated: true } : {}) },
276
+ gapScore,
277
+ counts,
278
+ stories,
279
+ orphanTcs: orphans,
280
+ });
281
+ }
282
+ catch (e) {
283
+ return err(e instanceof Error ? e.message : String(e));
284
+ }
285
+ });
286
+ }
287
+ //# sourceMappingURL=gapAnalysis.tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gapAnalysis.tools.js","sourceRoot":"","sources":["../../src/tools/gapAnalysis.tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAapD,MAAM,aAAa,GACjB,uFAAuF,CAAC;AAE1F,4EAA4E;AAC5E,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAsB/B,KAAK,UAAU,WAAW,CAAO,KAAU,EAAE,KAAa,EAAE,EAA2B;IACrF,MAAM,GAAG,GAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,UAAU,MAAM;QACnB,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;YACnB,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,IAAe;IAC9B,MAAM,CAAC,GAAI,IAAgC,CAAC,UAAU,CAAC;IACvD,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/C,CAAC;AAED,SAAS,OAAO,CAAC,CAAU;IACzB,OAAO,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,OAAwB,EACxB,KAOC,EACD,SAAiB;IAEjB,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC3F,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACpL,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAY,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7F,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,WAAW,KAAK,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACxL,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAY,CAAC;YACzC,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;SACrD,CAAC,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC;IACpF,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAY,CAAC;YACzC,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;SAC3D,CAAC,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,WAAW,KAAK,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC;IAChG,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC5C,2FAA2F;QAC3F,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,QAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9F,MAAM,OAAO,GAAmB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClD,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChC,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,CAAC,CAAC,CAAC;QACJ,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,QAAQ,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC;IACzJ,CAAC;IACD,cAAc;IACd,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAY,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACjE,OAAO;QACL,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,eAAe;QACtB,OAAO;QACP,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvF,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,OAAe,EAAE,OAAe,EAAE,cAAsB;IACxE,IAAI,OAAO,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAClC,IAAI,OAAO,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IACrC,IAAI,cAAc,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAwB,EACxB,QAAsB,EACtB,WAAwB;IAExB,MAAM,KAAK,GAAU,MAAM,OAAO,CAAC,QAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAErF,+FAA+F;IAC/F,+FAA+F;IAC/F,0CAA0C;IAC1C,MAAM,WAAW,GAAgB,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;IACvF,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAkB,EAAE,CAAC;IACvC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QACvF,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,IAAI,EAAE,CAAC,QAAQ,KAAK,QAAQ;gBAAE,SAAS;YACvC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,mFAAmF;IACnF,2DAA2D;IAC3D,IAAI,YAAsB,CAAC;IAC3B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,YAAY,GAAG,EAAE,CAAC;IACpB,CAAC;SAAM,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAClC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CACzF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACjF,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,MAAM,CAAC,MAAM;QACtB,OAAO,EAAE,WAAW,CAAC,MAAM;QAC3B,OAAO;QACP,YAAY;QACZ,YAAY;KACb,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,OAAwB,EACxB,SAAiB;IAEjB,mGAAmG;IACnG,iGAAiG;IACjG,qGAAqG;IACrG,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5F,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC;SAC/D,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,WAAW,CAAC,MAA2D;IAC9E,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AACpF,CAAC;AAED,SAAS,UAAU,CACjB,KAAkB,EAClB,OAAsB,EACtB,OAAmB,EACnB,KAAa;IAEb,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,MAAM;QAC9D,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,MAAM;QAC9D,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,MAAM;QAC/D,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,MAAM;QACzD,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;QACpE,SAAS,EAAE,OAAO,CAAC,MAAM;KAC1B,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC;IACpG,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,OAAO,CAAC,MAAM,uCAAuC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpH,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,KAAK,QAAQ,MAAM,CAAC,KAAK,QAAQ,MAAM,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,gBAAgB,KAAK,SAAS,KAAK,IAAI,SAAS,EAAE,CAAC;IAC9I,MAAM,OAAO,GACX,aAAa,MAAM,CAAC,OAAO,cAAc,MAAM,CAAC,OAAO,cAAc,MAAM,CAAC,OAAO,eAAe,MAAM,CAAC,IAAI,UAAU;QACvH,aAAa,MAAM,CAAC,YAAY,gBAAgB,MAAM,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,MAAM,aAAa,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpL,MAAM,KAAK,GACT,sEAAsE;QACtE,OAAO;aACJ,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,MAAM,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CACtO;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEhB,MAAM,aAAa,GAAG,OAAO;SAC1B,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;SACpH,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM;QACzC,CAAC,CAAC,oBAAoB,aAAa,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACnG,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM;QAChC,CAAC,CAAC,sCAAsC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACtL,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,OAAO,KAAK,UAAU,IAAI,CAAC,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;QACzH,CAAC;aAAM,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACnC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;gBAC/B,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC7B,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,UAAU,YAAY,CAAC,CAAC,WAAW,CAAC,MAAM,MAAM,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpJ,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,4BAA4B,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM;QAChC,CAAC,CAAC,mEAAmE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3K,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,GAAG,MAAM,OAAO,OAAO,OAAO,KAAK,GAAG,cAAc,GAAG,WAAW,GAAG,WAAW,EAAE,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAAiB,EAAE,IAA0B;IACpF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,yFAAyF;QAChG,WAAW,EACT,6FAA6F;YAC7F,+FAA+F;YAC/F,sFAAsF;YACtF,+FAA+F;YAC/F,uFAAuF;YACvF,kFAAkF;YAClF,sDAAsD;YACtD,2EAA2E;YAC3E,4CAA4C;YAC5C,+CAA+C;YAC/C,oIAAoI;YACpI,6FAA6F;YAC7F,yDAAyD;YACzD,4FAA4F;YAC5F,qFAAqF;YACrF,wFAAwF;YACxF,uFAAuF;YACvF,2FAA2F;YAC3F,sFAAsF;QACxF,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;YAC1E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YAC7E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YACnF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;YACzF,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;YACzF,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAC1C,wFAAwF;gBACxF,qEAAqE,CACtE;YACD,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACpE,4EAA4E,CAC7E;YACD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACxD,2FAA2F;gBAC3F,kDAAkD,CACnD;SACF;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO;YAAE,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC9C,OAAO,GAAG,CAAC,gGAAgG,CAAC,CAAC;QAC/G,CAAC;QAED,4DAA4D;QAC5D,MAAM,SAAS,GAAG;YAChB,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;YAClC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;YACpC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YAC9B,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;YACpC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;YAC/D,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;SAClD,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;QAC9B,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,GAAG,CACR,oFAAoF;gBACpF,kGAAkG,CACnG,CAAC;QACJ,CAAC;QACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,GAAG,CAAC,gCAAgC,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3F,CAAC;QAED,MAAM,WAAW,GAAgB,KAAK,CAAC,WAAW,IAAI,QAAQ,CAAC;QAC/D,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,kBAAkB,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;YAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,OAAO,EAAE,CAAC,KAAK,KAAK,CAAC,KAAK,2BAA2B,EAAE;oBACrD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;oBAC7D,QAAQ,EAAE,GAAG;oBACb,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE;oBAChG,OAAO,EAAE,EAAE;oBACX,SAAS,EAAE,EAAE;iBACd,CAAC,CAAC;YACL,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAClE,eAAe,CAAC,OAAO,EAAE,CAAC,EAAE,WAAW,CAAC,CACzC,CAAC;YAEF,uGAAuG;YACvG,IAAI,OAAO,GAAe,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACzD,OAAO,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACpD,CAAC;YAED,MAAM,MAAM,GAAG;gBACb,KAAK,EAAE,OAAO,CAAC,MAAM;gBACrB,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,MAAM;gBAC9D,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,MAAM;gBAC9D,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,MAAM;gBAC/D,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,MAAM;gBACzD,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpE,SAAS,EAAE,OAAO,CAAC,MAAM;aAC1B,CAAC;YACF,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC3D,OAAO,EAAE,CAAC,IAAI,EAAE;gBACd,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;gBAC9G,QAAQ;gBACR,MAAM;gBACN,OAAO;gBACP,SAAS,EAAE,OAAO;aACnB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ProviderAdapter } from '../adapters/types.js';
3
+ /**
4
+ * impact_analysis — blast-radius report from a single anchor (defect | testcase | story | sprint |
5
+ * release). Walks up and down the graph via existing adapter reads. READ-ONLY: emits a verdict
6
+ * (READY / NEEDS_ATTENTION / AT_RISK) and a downstream suggestion block; never mutates state.
7
+ *
8
+ * Verdict rule (kept dumb on purpose — tune when a user says it is wrong):
9
+ * openCritical > 0 OR uncoveredAcs > 0.3 * totalAcs → AT_RISK
10
+ * openMajor > 0 OR storiesWithNoTests > 0 → NEEDS_ATTENTION
11
+ * else → READY
12
+ */
13
+ export type ImpactAnalysisToolsDeps = {
14
+ getAdapter: () => ProviderAdapter | null;
15
+ };
16
+ export declare function registerImpactAnalysisTools(server: McpServer, deps: ImpactAnalysisToolsDeps): void;
17
+ //# sourceMappingURL=impactAnalysis.tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impactAnalysis.tools.d.ts","sourceRoot":"","sources":["../../src/tools/impactAnalysis.tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI5D;;;;;;;;;GASG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,UAAU,EAAE,MAAM,eAAe,GAAG,IAAI,CAAC;CAC1C,CAAC;AA6HF,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAqRlG"}