driftdetect-mcp 0.5.0 → 0.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/bin/server.js +0 -0
- package/dist/enterprise-server.d.ts.map +1 -1
- package/dist/enterprise-server.js +17 -2
- package/dist/enterprise-server.js.map +1 -1
- package/dist/tools/analysis/constraints.d.ts +40 -0
- package/dist/tools/analysis/constraints.d.ts.map +1 -0
- package/dist/tools/analysis/constraints.js +236 -0
- package/dist/tools/analysis/constraints.js.map +1 -0
- package/dist/tools/analysis/decisions.d.ts +54 -0
- package/dist/tools/analysis/decisions.d.ts.map +1 -0
- package/dist/tools/analysis/decisions.js +307 -0
- package/dist/tools/analysis/decisions.js.map +1 -0
- package/dist/tools/analysis/go.d.ts +22 -0
- package/dist/tools/analysis/go.d.ts.map +1 -0
- package/dist/tools/analysis/go.js +214 -0
- package/dist/tools/analysis/go.js.map +1 -0
- package/dist/tools/analysis/index.d.ts +5 -0
- package/dist/tools/analysis/index.d.ts.map +1 -1
- package/dist/tools/analysis/index.js +209 -0
- package/dist/tools/analysis/index.js.map +1 -1
- package/dist/tools/analysis/simulate.d.ts +27 -0
- package/dist/tools/analysis/simulate.d.ts.map +1 -0
- package/dist/tools/analysis/simulate.js +89 -0
- package/dist/tools/analysis/simulate.js.map +1 -0
- package/dist/tools/analysis/wpf.d.ts +23 -0
- package/dist/tools/analysis/wpf.d.ts.map +1 -0
- package/dist/tools/analysis/wpf.js +240 -0
- package/dist/tools/analysis/wpf.js.map +1 -0
- package/dist/tools/detail/file-patterns.d.ts +3 -2
- package/dist/tools/detail/file-patterns.d.ts.map +1 -1
- package/dist/tools/detail/file-patterns.js +20 -12
- package/dist/tools/detail/file-patterns.js.map +1 -1
- package/dist/tools/detail/files-list.d.ts +3 -3
- package/dist/tools/detail/files-list.d.ts.map +1 -1
- package/dist/tools/detail/files-list.js +28 -11
- package/dist/tools/detail/files-list.js.map +1 -1
- package/dist/tools/orchestration/context.d.ts +15 -1
- package/dist/tools/orchestration/context.d.ts.map +1 -1
- package/dist/tools/orchestration/context.js +248 -4
- package/dist/tools/orchestration/context.js.map +1 -1
- package/package.json +31 -16
- package/LICENSE +0 -21
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detail tool that returns all patterns found in a specific file.
|
|
5
5
|
* Shows pattern details, locations within the file, and outliers.
|
|
6
|
+
*
|
|
7
|
+
* Uses IndexStore (by-file.json) for file-to-pattern mapping.
|
|
6
8
|
*/
|
|
7
|
-
import type { ManifestStore } from 'driftdetect-core';
|
|
8
9
|
export interface FilePatternLocation {
|
|
9
10
|
line: number;
|
|
10
11
|
column?: number;
|
|
@@ -27,7 +28,7 @@ export interface FilePatternData {
|
|
|
27
28
|
outlierCount: number;
|
|
28
29
|
categories: string[];
|
|
29
30
|
}
|
|
30
|
-
export declare function handleFilePatterns(
|
|
31
|
+
export declare function handleFilePatterns(projectRoot: string, args: {
|
|
31
32
|
file: string;
|
|
32
33
|
category?: string;
|
|
33
34
|
}): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-patterns.d.ts","sourceRoot":"","sources":["../../../src/tools/detail/file-patterns.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"file-patterns.d.ts","sourceRoot":"","sources":["../../../src/tools/detail/file-patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAsH7D"}
|
|
@@ -3,28 +3,36 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detail tool that returns all patterns found in a specific file.
|
|
5
5
|
* Shows pattern details, locations within the file, and outliers.
|
|
6
|
+
*
|
|
7
|
+
* Uses IndexStore (by-file.json) for file-to-pattern mapping.
|
|
6
8
|
*/
|
|
9
|
+
import { IndexStore, PatternStore } from 'driftdetect-core';
|
|
7
10
|
import { createResponseBuilder, Errors } from '../../infrastructure/index.js';
|
|
8
|
-
export async function handleFilePatterns(
|
|
11
|
+
export async function handleFilePatterns(projectRoot, args) {
|
|
9
12
|
const builder = createResponseBuilder();
|
|
10
13
|
if (!args.file) {
|
|
11
14
|
throw Errors.missingParameter('file');
|
|
12
15
|
}
|
|
13
|
-
|
|
14
|
-
const
|
|
16
|
+
// Use IndexStore for file-to-pattern mapping
|
|
17
|
+
const indexStore = new IndexStore({ rootDir: projectRoot });
|
|
18
|
+
await indexStore.initialize();
|
|
19
|
+
const fileIndex = await indexStore.getFileIndex();
|
|
15
20
|
// Normalize file path
|
|
16
21
|
const filePath = args.file.replace(/^\.\//, '');
|
|
17
|
-
// Check if file exists in
|
|
18
|
-
const
|
|
19
|
-
if (!
|
|
22
|
+
// Check if file exists in index
|
|
23
|
+
const patternIds = fileIndex?.patterns[filePath];
|
|
24
|
+
if (!patternIds || patternIds.length === 0) {
|
|
20
25
|
throw Errors.notFound('file', filePath);
|
|
21
26
|
}
|
|
27
|
+
// Load pattern store to get full pattern details
|
|
28
|
+
const patternStore = new PatternStore({ rootDir: projectRoot });
|
|
29
|
+
await patternStore.initialize();
|
|
22
30
|
// Get patterns for this file
|
|
23
31
|
const patterns = [];
|
|
24
32
|
const categories = new Set();
|
|
25
33
|
let outlierCount = 0;
|
|
26
|
-
for (const patternId of
|
|
27
|
-
const pattern =
|
|
34
|
+
for (const patternId of patternIds) {
|
|
35
|
+
const pattern = patternStore.get(patternId);
|
|
28
36
|
if (!pattern)
|
|
29
37
|
continue;
|
|
30
38
|
// Filter by category if specified
|
|
@@ -37,10 +45,10 @@ export async function handleFilePatterns(store, args) {
|
|
|
37
45
|
.filter(loc => loc.file === filePath)
|
|
38
46
|
.map(loc => {
|
|
39
47
|
const result = {
|
|
40
|
-
line: loc.
|
|
48
|
+
line: loc.line,
|
|
41
49
|
};
|
|
42
|
-
if (loc.
|
|
43
|
-
result.
|
|
50
|
+
if (loc.column) {
|
|
51
|
+
result.column = loc.column;
|
|
44
52
|
}
|
|
45
53
|
return result;
|
|
46
54
|
});
|
|
@@ -54,7 +62,7 @@ export async function handleFilePatterns(store, args) {
|
|
|
54
62
|
name: pattern.name,
|
|
55
63
|
category: pattern.category,
|
|
56
64
|
subcategory: pattern.subcategory ?? '',
|
|
57
|
-
confidence: Math.round(pattern.confidence * 100) / 100,
|
|
65
|
+
confidence: Math.round(pattern.confidence.score * 100) / 100,
|
|
58
66
|
locations: fileLocations,
|
|
59
67
|
isOutlier: !!outlier,
|
|
60
68
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-patterns.js","sourceRoot":"","sources":["../../../src/tools/detail/file-patterns.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"file-patterns.js","sourceRoot":"","sources":["../../../src/tools/detail/file-patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detail tool that lists files matching a glob pattern with their pattern counts.
|
|
5
5
|
* Supports pagination for large codebases.
|
|
6
|
+
*
|
|
7
|
+
* Uses IndexStore (by-file.json) for file-to-pattern mapping.
|
|
6
8
|
*/
|
|
7
|
-
import type { ManifestStore } from 'driftdetect-core';
|
|
8
9
|
export interface FileEntry {
|
|
9
10
|
file: string;
|
|
10
11
|
patternCount: number;
|
|
11
12
|
categories: string[];
|
|
12
|
-
lastScanned?: string;
|
|
13
13
|
}
|
|
14
14
|
export interface FilesListData {
|
|
15
15
|
files: FileEntry[];
|
|
16
16
|
totalFiles: number;
|
|
17
17
|
totalPatterns: number;
|
|
18
18
|
}
|
|
19
|
-
export declare function handleFilesList(
|
|
19
|
+
export declare function handleFilesList(projectRoot: string, args: {
|
|
20
20
|
path?: string;
|
|
21
21
|
category?: string;
|
|
22
22
|
limit?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files-list.d.ts","sourceRoot":"","sources":["../../../src/tools/detail/files-list.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"files-list.d.ts","sourceRoot":"","sources":["../../../src/tools/detail/files-list.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAID,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IACJ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA2G7D"}
|
|
@@ -3,26 +3,43 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detail tool that lists files matching a glob pattern with their pattern counts.
|
|
5
5
|
* Supports pagination for large codebases.
|
|
6
|
+
*
|
|
7
|
+
* Uses IndexStore (by-file.json) for file-to-pattern mapping.
|
|
6
8
|
*/
|
|
9
|
+
import { IndexStore, PatternStore } from 'driftdetect-core';
|
|
7
10
|
import { createResponseBuilder, createCursor, parseCursor } from '../../infrastructure/index.js';
|
|
8
11
|
const DEFAULT_LIMIT = 20;
|
|
9
|
-
export async function handleFilesList(
|
|
12
|
+
export async function handleFilesList(projectRoot, args) {
|
|
10
13
|
const builder = createResponseBuilder();
|
|
11
|
-
|
|
12
|
-
const
|
|
14
|
+
// Use IndexStore for file-to-pattern mapping
|
|
15
|
+
const indexStore = new IndexStore({ rootDir: projectRoot });
|
|
16
|
+
await indexStore.initialize();
|
|
17
|
+
const fileIndex = await indexStore.getFileIndex();
|
|
18
|
+
if (!fileIndex || Object.keys(fileIndex.patterns).length === 0) {
|
|
19
|
+
return builder
|
|
20
|
+
.withSummary('0 files with 0 pattern instances.')
|
|
21
|
+
.withData({ files: [], totalFiles: 0, totalPatterns: 0 })
|
|
22
|
+
.withHints({
|
|
23
|
+
nextActions: ['Run drift scan to discover patterns'],
|
|
24
|
+
relatedTools: ['drift_file_patterns', 'drift_patterns_list'],
|
|
25
|
+
})
|
|
26
|
+
.buildContent();
|
|
27
|
+
}
|
|
13
28
|
const limit = args.limit ?? DEFAULT_LIMIT;
|
|
14
29
|
const offset = args.cursor ? parseCursor(args.cursor).offset : 0;
|
|
15
30
|
const pathPattern = args.path ?? '**/*';
|
|
16
|
-
// Get all files from
|
|
17
|
-
const allFiles = Object.entries(
|
|
31
|
+
// Get all files from index
|
|
32
|
+
const allFiles = Object.entries(fileIndex.patterns);
|
|
18
33
|
// Filter by path pattern (simple glob matching)
|
|
19
34
|
let filteredFiles = allFiles.filter(([filePath]) => matchGlob(filePath, pathPattern));
|
|
35
|
+
// Load pattern store to get categories
|
|
36
|
+
const patternStore = new PatternStore({ rootDir: projectRoot });
|
|
37
|
+
await patternStore.initialize();
|
|
20
38
|
// Build file entries with pattern info
|
|
21
|
-
let fileEntries = filteredFiles.map(([filePath,
|
|
22
|
-
const patternIds = fileData.patterns;
|
|
39
|
+
let fileEntries = filteredFiles.map(([filePath, patternIds]) => {
|
|
23
40
|
const categories = new Set();
|
|
24
41
|
for (const patternId of patternIds) {
|
|
25
|
-
const pattern =
|
|
42
|
+
const pattern = patternStore.get(patternId);
|
|
26
43
|
if (pattern) {
|
|
27
44
|
categories.add(pattern.category);
|
|
28
45
|
}
|
|
@@ -31,7 +48,6 @@ export async function handleFilesList(store, args) {
|
|
|
31
48
|
file: filePath,
|
|
32
49
|
patternCount: patternIds.length,
|
|
33
50
|
categories: Array.from(categories).sort(),
|
|
34
|
-
lastScanned: fileData.lastScanned,
|
|
35
51
|
};
|
|
36
52
|
});
|
|
37
53
|
// Filter by category if specified
|
|
@@ -87,12 +103,13 @@ export async function handleFilesList(store, args) {
|
|
|
87
103
|
function matchGlob(filePath, pattern) {
|
|
88
104
|
if (pattern === '**/*' || pattern === '*')
|
|
89
105
|
return true;
|
|
106
|
+
// Escape special regex chars first, then handle glob patterns
|
|
90
107
|
const regexPattern = pattern
|
|
108
|
+
.replace(/\./g, '\\.')
|
|
91
109
|
.replace(/\*\*/g, '{{GLOBSTAR}}')
|
|
92
110
|
.replace(/\*/g, '[^/]*')
|
|
93
111
|
.replace(/{{GLOBSTAR}}/g, '.*')
|
|
94
|
-
.replace(/\?/g, '.')
|
|
95
|
-
.replace(/\./g, '\\.');
|
|
112
|
+
.replace(/\?/g, '.');
|
|
96
113
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
97
114
|
return regex.test(filePath);
|
|
98
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files-list.js","sourceRoot":"","sources":["../../../src/tools/detail/files-list.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"files-list.js","sourceRoot":"","sources":["../../../src/tools/detail/files-list.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAcjG,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAmB,EACnB,IAKC;IAED,MAAM,OAAO,GAAG,qBAAqB,EAAiB,CAAC;IAEvD,6CAA6C;IAC7C,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IAC5D,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC;IAE9B,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,YAAY,EAAE,CAAC;IAElD,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/D,OAAO,OAAO;aACX,WAAW,CAAC,mCAAmC,CAAC;aAChD,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;aACxD,SAAS,CAAC;YACT,WAAW,EAAE,CAAC,qCAAqC,CAAC;YACpD,YAAY,EAAE,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;SAC7D,CAAC;aACD,YAAY,EAAE,CAAC;IACpB,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,aAAa,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC;IAExC,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEpD,gDAAgD;IAChD,IAAI,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,CACjD,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,CACjC,CAAC;IAEF,uCAAuC;IACvC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IAChE,MAAM,YAAY,CAAC,UAAU,EAAE,CAAC;IAEhC,uCAAuC;IACvC,IAAI,WAAW,GAAgB,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE;QAC1E,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QAErC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC5C,IAAI,OAAO,EAAE,CAAC;gBACZ,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,YAAY,EAAE,UAAU,CAAC,MAAM;YAC/B,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE;SAC1C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,kCAAkC;IAClC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAS,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED,8CAA8C;IAC9C,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC;IAE5D,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC;IACtC,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAE9E,mBAAmB;IACnB,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;IAE5C,MAAM,IAAI,GAAkB;QAC1B,KAAK,EAAE,cAAc;QACrB,UAAU;QACV,aAAa;KACd,CAAC;IAEF,gBAAgB;IAChB,IAAI,OAAO,GAAG,GAAG,UAAU,eAAe,aAAa,qBAAqB,CAAC;IAC7E,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACtC,OAAO,GAAG,aAAa,IAAI,CAAC,IAAI,MAAM,OAAO,EAAE,CAAC;IAClD,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,IAAI,gBAAgB,IAAI,CAAC,QAAQ,YAAY,CAAC;IACvD,CAAC;IAED,iBAAiB;IACjB,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,cAAc,CAAC;YACrB,MAAM,EAAE,YAAY,CAAC,MAAM,GAAG,KAAK,EAAE,KAAK,CAAC;YAC3C,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO;SACX,WAAW,CAAC,OAAO,CAAC;SACpB,QAAQ,CAAC,IAAI,CAAC;SACd,SAAS,CAAC;QACT,WAAW,EAAE,cAAc,CAAC,MAAM,GAAG,CAAC;YACpC,CAAC,CAAC;gBACE,kEAAkE;gBAClE,OAAO,CAAC,CAAC,CAAC,eAAe,YAAY,CAAC,MAAM,GAAG,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE;aACvF,CAAC,MAAM,CAAC,OAAO,CAAC;YACnB,CAAC,CAAC,CAAC,qCAAqC,CAAC;QAC3C,YAAY,EAAE,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KAC7D,CAAC;SACD,YAAY,EAAE,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,QAAgB,EAAE,OAAe;IAClD,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAEvD,8DAA8D;IAC9D,MAAM,YAAY,GAAG,OAAO;SACzB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC;SAChC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC;SAC9B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAEvB,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Enhanced with Language Intelligence for cross-language semantic analysis.
|
|
13
13
|
*/
|
|
14
|
-
import { PatternStore, ManifestStore, BoundaryStore, CallGraphStore, DNAStore } from 'driftdetect-core';
|
|
14
|
+
import { PatternStore, ManifestStore, BoundaryStore, CallGraphStore, DNAStore, type ConstraintCategory } from 'driftdetect-core';
|
|
15
15
|
export type TaskIntent = 'add_feature' | 'fix_bug' | 'refactor' | 'security_audit' | 'understand_code' | 'add_test';
|
|
16
16
|
export interface RelevantPattern {
|
|
17
17
|
id: string;
|
|
@@ -79,6 +79,18 @@ export interface SemanticInsights {
|
|
|
79
79
|
serviceCount: number;
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
+
/** Relevant constraint for the task */
|
|
83
|
+
export interface RelevantConstraint {
|
|
84
|
+
id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
category: ConstraintCategory;
|
|
87
|
+
type: string;
|
|
88
|
+
condition: string;
|
|
89
|
+
enforcement: 'error' | 'warning' | 'info';
|
|
90
|
+
confidence: number;
|
|
91
|
+
guidance: string;
|
|
92
|
+
why: string;
|
|
93
|
+
}
|
|
82
94
|
export interface ContextPackage {
|
|
83
95
|
summary: string;
|
|
84
96
|
relevantPatterns: RelevantPattern[];
|
|
@@ -89,6 +101,8 @@ export interface ContextPackage {
|
|
|
89
101
|
deeperDive: DeeperDive[];
|
|
90
102
|
/** Semantic insights from Language Intelligence */
|
|
91
103
|
semanticInsights?: SemanticInsights;
|
|
104
|
+
/** Architectural constraints that apply to this task */
|
|
105
|
+
constraints?: RelevantConstraint[];
|
|
92
106
|
/** Project context when targeting a specific project */
|
|
93
107
|
projectContext?: Record<string, unknown>;
|
|
94
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/tools/orchestration/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EACd,QAAQ,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/tools/orchestration/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Enhanced with Language Intelligence for cross-language semantic analysis.
|
|
13
13
|
*/
|
|
14
|
-
import { PatternStore, ManifestStore, BoundaryStore, CallGraphStore, DNAStore, createLanguageIntelligence, } from 'driftdetect-core';
|
|
14
|
+
import { PatternStore, ManifestStore, BoundaryStore, CallGraphStore, DNAStore, createLanguageIntelligence, createConstraintStore, } from 'driftdetect-core';
|
|
15
15
|
import { createResponseBuilder, resolveProject, formatProjectContext } from '../../infrastructure/index.js';
|
|
16
16
|
import * as fs from 'fs/promises';
|
|
17
17
|
import * as path from 'path';
|
|
@@ -258,8 +258,10 @@ export async function handleContext(stores, projectRoot, args) {
|
|
|
258
258
|
const deeperDive = generateDeeperDive(intent, focus, relevantPatterns, suggestedFiles);
|
|
259
259
|
// Generate semantic insights from Language Intelligence
|
|
260
260
|
const semanticInsights = await generateSemanticInsights(effectiveRoot, suggestedFiles, focus);
|
|
261
|
+
// Get relevant constraints for this task
|
|
262
|
+
const constraints = await getRelevantConstraints(effectiveRoot, intent, focus, suggestedFiles);
|
|
261
263
|
// Build summary
|
|
262
|
-
let summary = buildSummary(intent, focus, relevantPatterns, suggestedFiles, warnings, semanticInsights);
|
|
264
|
+
let summary = buildSummary(intent, focus, relevantPatterns, suggestedFiles, warnings, semanticInsights, constraints);
|
|
263
265
|
// Add project context to summary if using a different project
|
|
264
266
|
if (resolution.fromRegistry && resolution.project) {
|
|
265
267
|
summary = `[Project: ${resolution.project.name}] ${summary}`;
|
|
@@ -273,7 +275,16 @@ export async function handleContext(stores, projectRoot, args) {
|
|
|
273
275
|
confidence,
|
|
274
276
|
deeperDive,
|
|
275
277
|
...(semanticInsights && { semanticInsights }),
|
|
278
|
+
...(constraints.length > 0 && { constraints }),
|
|
276
279
|
};
|
|
280
|
+
// Add constraint-related guidance
|
|
281
|
+
if (constraints.length > 0) {
|
|
282
|
+
const errorConstraints = constraints.filter(c => c.enforcement === 'error');
|
|
283
|
+
if (errorConstraints.length > 0) {
|
|
284
|
+
guidance.keyInsights.unshift(`⚠️ ${errorConstraints.length} mandatory constraint(s) apply - violations will cause errors`);
|
|
285
|
+
}
|
|
286
|
+
guidance.decisionPoints.push('Review constraints below before implementing - they define what code MUST do');
|
|
287
|
+
}
|
|
277
288
|
// Add project context to response
|
|
278
289
|
const projectContext = formatProjectContext(resolution);
|
|
279
290
|
return builder
|
|
@@ -496,7 +507,7 @@ function generateDeeperDive(intent, _focus, patterns, files) {
|
|
|
496
507
|
}
|
|
497
508
|
return suggestions;
|
|
498
509
|
}
|
|
499
|
-
function buildSummary(intent, focus, patterns, files, warnings, semanticInsights) {
|
|
510
|
+
function buildSummary(intent, focus, patterns, files, warnings, semanticInsights, constraints) {
|
|
500
511
|
const intentLabels = {
|
|
501
512
|
add_feature: 'Adding feature',
|
|
502
513
|
fix_bug: 'Fixing bug',
|
|
@@ -537,7 +548,21 @@ function buildSummary(intent, focus, patterns, files, warnings, semanticInsights
|
|
|
537
548
|
semanticParts.push(`${stats.serviceCount} service(s)`);
|
|
538
549
|
}
|
|
539
550
|
if (semanticParts.length > 0) {
|
|
540
|
-
summary += `Semantic analysis: ${semanticParts.join(', ')}
|
|
551
|
+
summary += `Semantic analysis: ${semanticParts.join(', ')}. `;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
// Add constraint info to summary
|
|
555
|
+
if (constraints && constraints.length > 0) {
|
|
556
|
+
const errorCount = constraints.filter(c => c.enforcement === 'error').length;
|
|
557
|
+
const warningCount = constraints.filter(c => c.enforcement === 'warning').length;
|
|
558
|
+
if (errorCount > 0) {
|
|
559
|
+
summary += `🔒 ${errorCount} mandatory constraint(s). `;
|
|
560
|
+
}
|
|
561
|
+
else if (warningCount > 0) {
|
|
562
|
+
summary += `${constraints.length} constraint(s) apply. `;
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
summary += `${constraints.length} constraint(s) for reference. `;
|
|
541
566
|
}
|
|
542
567
|
}
|
|
543
568
|
return summary;
|
|
@@ -652,6 +677,225 @@ async function generateSemanticInsights(projectRoot, suggestedFiles, focus) {
|
|
|
652
677
|
return undefined;
|
|
653
678
|
}
|
|
654
679
|
}
|
|
680
|
+
// =============================================================================
|
|
681
|
+
// Constraint Integration
|
|
682
|
+
// =============================================================================
|
|
683
|
+
/**
|
|
684
|
+
* Get constraints relevant to the current task
|
|
685
|
+
*
|
|
686
|
+
* Maps task intent to constraint categories and filters constraints
|
|
687
|
+
* that apply to the suggested files.
|
|
688
|
+
*/
|
|
689
|
+
async function getRelevantConstraints(projectRoot, intent, focus, suggestedFiles) {
|
|
690
|
+
try {
|
|
691
|
+
// Initialize constraint store
|
|
692
|
+
const constraintStore = createConstraintStore({ rootDir: projectRoot });
|
|
693
|
+
await constraintStore.initialize();
|
|
694
|
+
// Map intent to relevant constraint categories
|
|
695
|
+
const intentToCategories = {
|
|
696
|
+
add_feature: ['api', 'auth', 'data', 'error', 'validation', 'logging', 'structural'],
|
|
697
|
+
fix_bug: ['error', 'data', 'validation', 'logging'],
|
|
698
|
+
refactor: ['structural', 'api', 'data', 'performance'],
|
|
699
|
+
security_audit: ['security', 'auth', 'data', 'validation'],
|
|
700
|
+
understand_code: ['api', 'data', 'structural', 'auth'],
|
|
701
|
+
add_test: ['test', 'error', 'data', 'api'],
|
|
702
|
+
};
|
|
703
|
+
const relevantCategories = intentToCategories[intent] ?? [];
|
|
704
|
+
// Get active constraints (approved + high-confidence discovered)
|
|
705
|
+
const activeConstraints = constraintStore.getActive(0.85);
|
|
706
|
+
// Filter to relevant categories
|
|
707
|
+
let filtered = activeConstraints.filter(c => relevantCategories.includes(c.category));
|
|
708
|
+
// Further filter to constraints that apply to suggested files
|
|
709
|
+
if (suggestedFiles.length > 0) {
|
|
710
|
+
filtered = filtered.filter(c => {
|
|
711
|
+
// If constraint has no file scope, it applies globally
|
|
712
|
+
if (!c.scope.files || c.scope.files.length === 0) {
|
|
713
|
+
return true;
|
|
714
|
+
}
|
|
715
|
+
// Check if any suggested file matches the constraint scope
|
|
716
|
+
return suggestedFiles.some(sf => constraintAppliesToFile(c, sf.file));
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
// Also include constraints that match the focus term
|
|
720
|
+
const focusLower = focus.toLowerCase();
|
|
721
|
+
const focusMatches = activeConstraints.filter(c => !filtered.includes(c) && (c.name.toLowerCase().includes(focusLower) ||
|
|
722
|
+
c.description.toLowerCase().includes(focusLower)));
|
|
723
|
+
filtered = [...filtered, ...focusMatches];
|
|
724
|
+
// Sort by enforcement level (errors first) then confidence
|
|
725
|
+
filtered.sort((a, b) => {
|
|
726
|
+
const levelOrder = { error: 0, warning: 1, info: 2 };
|
|
727
|
+
const levelDiff = levelOrder[a.enforcement.level] - levelOrder[b.enforcement.level];
|
|
728
|
+
if (levelDiff !== 0)
|
|
729
|
+
return levelDiff;
|
|
730
|
+
return b.confidence.score - a.confidence.score;
|
|
731
|
+
});
|
|
732
|
+
// Limit to top 10 most relevant
|
|
733
|
+
const top = filtered.slice(0, 10);
|
|
734
|
+
// Convert to RelevantConstraint format
|
|
735
|
+
return top.map(c => ({
|
|
736
|
+
id: c.id,
|
|
737
|
+
name: c.name,
|
|
738
|
+
category: c.category,
|
|
739
|
+
type: c.invariant.type,
|
|
740
|
+
condition: c.invariant.condition,
|
|
741
|
+
enforcement: c.enforcement.level,
|
|
742
|
+
confidence: Math.round(c.confidence.score * 100) / 100,
|
|
743
|
+
guidance: c.enforcement.guidance,
|
|
744
|
+
why: generateConstraintWhy(c, intent, focus),
|
|
745
|
+
}));
|
|
746
|
+
}
|
|
747
|
+
catch {
|
|
748
|
+
// Constraint store not available or error - return empty
|
|
749
|
+
return [];
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Check if a constraint applies to a specific file
|
|
754
|
+
*/
|
|
755
|
+
function constraintAppliesToFile(constraint, filePath) {
|
|
756
|
+
const scope = constraint.scope;
|
|
757
|
+
// Check exclusions first
|
|
758
|
+
if (scope.exclude?.files?.length) {
|
|
759
|
+
for (const pattern of scope.exclude.files) {
|
|
760
|
+
if (matchGlob(filePath, pattern)) {
|
|
761
|
+
return false;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (scope.exclude?.directories?.length) {
|
|
766
|
+
for (const dir of scope.exclude.directories) {
|
|
767
|
+
if (filePath.includes(dir)) {
|
|
768
|
+
return false;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
// Check inclusions
|
|
773
|
+
if (scope.files?.length) {
|
|
774
|
+
return scope.files.some(pattern => matchGlob(filePath, pattern));
|
|
775
|
+
}
|
|
776
|
+
// Check language match
|
|
777
|
+
if (constraint.language !== 'all') {
|
|
778
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
779
|
+
const langExtensions = {
|
|
780
|
+
typescript: ['.ts', '.tsx'],
|
|
781
|
+
javascript: ['.js', '.jsx', '.mjs', '.cjs'],
|
|
782
|
+
python: ['.py'],
|
|
783
|
+
java: ['.java'],
|
|
784
|
+
csharp: ['.cs'],
|
|
785
|
+
php: ['.php'],
|
|
786
|
+
};
|
|
787
|
+
const exts = langExtensions[constraint.language];
|
|
788
|
+
if (exts && !exts.includes(ext)) {
|
|
789
|
+
return false;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
// If no specific file scope, constraint applies to all matching language files
|
|
793
|
+
return true;
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Simple glob matching (supports * and **)
|
|
797
|
+
*/
|
|
798
|
+
function matchGlob(filePath, pattern) {
|
|
799
|
+
const regexPattern = pattern
|
|
800
|
+
.replace(/\*\*/g, '{{GLOBSTAR}}')
|
|
801
|
+
.replace(/\*/g, '[^/]*')
|
|
802
|
+
.replace(/{{GLOBSTAR}}/g, '.*')
|
|
803
|
+
.replace(/\//g, '\\/');
|
|
804
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
805
|
+
return regex.test(filePath);
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Generate explanation for why a constraint is relevant
|
|
809
|
+
*/
|
|
810
|
+
function generateConstraintWhy(constraint, intent, focus) {
|
|
811
|
+
const focusLower = focus.toLowerCase();
|
|
812
|
+
// Check if constraint name/description matches focus
|
|
813
|
+
if (constraint.name.toLowerCase().includes(focusLower) ||
|
|
814
|
+
constraint.description.toLowerCase().includes(focusLower)) {
|
|
815
|
+
return `Directly related to "${focus}" - this constraint must be satisfied`;
|
|
816
|
+
}
|
|
817
|
+
// Intent-specific explanations
|
|
818
|
+
const intentExplanations = {
|
|
819
|
+
add_feature: {
|
|
820
|
+
api: 'API constraints ensure new endpoints follow established patterns',
|
|
821
|
+
auth: 'Authentication constraints protect new features',
|
|
822
|
+
data: 'Data access constraints ensure proper data handling',
|
|
823
|
+
error: 'Error handling constraints ensure robust error management',
|
|
824
|
+
validation: 'Validation constraints ensure input safety',
|
|
825
|
+
logging: 'Logging constraints ensure observability',
|
|
826
|
+
structural: 'Structural constraints maintain code organization',
|
|
827
|
+
security: 'Security constraints protect against vulnerabilities',
|
|
828
|
+
test: 'Test constraints ensure adequate coverage',
|
|
829
|
+
performance: 'Performance constraints prevent regressions',
|
|
830
|
+
},
|
|
831
|
+
fix_bug: {
|
|
832
|
+
error: 'Error handling constraints may reveal the bug pattern',
|
|
833
|
+
data: 'Data constraints ensure fix doesn\'t break data integrity',
|
|
834
|
+
validation: 'Validation constraints may be the root cause',
|
|
835
|
+
logging: 'Logging constraints help debug the issue',
|
|
836
|
+
api: 'API constraints ensure fix maintains compatibility',
|
|
837
|
+
auth: 'Auth constraints ensure fix doesn\'t create security holes',
|
|
838
|
+
security: 'Security constraints must be maintained during fix',
|
|
839
|
+
structural: 'Structural constraints guide where fix should go',
|
|
840
|
+
test: 'Test constraints ensure fix is properly tested',
|
|
841
|
+
performance: 'Performance constraints ensure fix doesn\'t regress',
|
|
842
|
+
},
|
|
843
|
+
refactor: {
|
|
844
|
+
structural: 'Structural constraints guide refactoring direction',
|
|
845
|
+
api: 'API constraints ensure refactor maintains compatibility',
|
|
846
|
+
data: 'Data constraints ensure refactor preserves data handling',
|
|
847
|
+
performance: 'Performance constraints ensure refactor improves efficiency',
|
|
848
|
+
error: 'Error handling must be preserved during refactor',
|
|
849
|
+
auth: 'Auth patterns must be maintained',
|
|
850
|
+
security: 'Security patterns must be preserved',
|
|
851
|
+
validation: 'Validation must be maintained',
|
|
852
|
+
logging: 'Logging must be preserved',
|
|
853
|
+
test: 'Tests must continue to pass',
|
|
854
|
+
},
|
|
855
|
+
security_audit: {
|
|
856
|
+
security: 'Security constraints define required protections',
|
|
857
|
+
auth: 'Auth constraints ensure proper authentication',
|
|
858
|
+
data: 'Data constraints protect sensitive information',
|
|
859
|
+
validation: 'Validation constraints prevent injection attacks',
|
|
860
|
+
api: 'API constraints ensure secure endpoints',
|
|
861
|
+
error: 'Error handling must not leak sensitive info',
|
|
862
|
+
logging: 'Logging must not expose sensitive data',
|
|
863
|
+
structural: 'Structure affects security boundaries',
|
|
864
|
+
test: 'Security tests must exist',
|
|
865
|
+
performance: 'Performance affects DoS resistance',
|
|
866
|
+
},
|
|
867
|
+
understand_code: {
|
|
868
|
+
api: 'API constraints explain endpoint requirements',
|
|
869
|
+
data: 'Data constraints explain data flow rules',
|
|
870
|
+
structural: 'Structural constraints explain code organization',
|
|
871
|
+
auth: 'Auth constraints explain security model',
|
|
872
|
+
error: 'Error constraints explain error handling approach',
|
|
873
|
+
security: 'Security constraints explain protection model',
|
|
874
|
+
validation: 'Validation constraints explain input requirements',
|
|
875
|
+
logging: 'Logging constraints explain observability approach',
|
|
876
|
+
test: 'Test constraints explain testing strategy',
|
|
877
|
+
performance: 'Performance constraints explain optimization rules',
|
|
878
|
+
},
|
|
879
|
+
add_test: {
|
|
880
|
+
test: 'Test constraints define testing requirements',
|
|
881
|
+
error: 'Error constraints show what error cases to test',
|
|
882
|
+
data: 'Data constraints show what data scenarios to test',
|
|
883
|
+
api: 'API constraints show what endpoints need testing',
|
|
884
|
+
auth: 'Auth constraints show security scenarios to test',
|
|
885
|
+
security: 'Security constraints show attack vectors to test',
|
|
886
|
+
validation: 'Validation constraints show input cases to test',
|
|
887
|
+
logging: 'Logging constraints show what to verify in logs',
|
|
888
|
+
structural: 'Structure affects test organization',
|
|
889
|
+
performance: 'Performance constraints show what to benchmark',
|
|
890
|
+
},
|
|
891
|
+
};
|
|
892
|
+
const explanation = intentExplanations[intent]?.[constraint.category];
|
|
893
|
+
if (explanation) {
|
|
894
|
+
return explanation;
|
|
895
|
+
}
|
|
896
|
+
// Default explanation
|
|
897
|
+
return `${constraint.category} constraint with ${Math.round(constraint.confidence.score * 100)}% confidence`;
|
|
898
|
+
}
|
|
655
899
|
/**
|
|
656
900
|
* Find source files matching the focus term
|
|
657
901
|
*/
|