@bryan-thompson/inspector-assessment-cli 1.26.6 → 1.26.7
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/build/__tests__/assessment-runner/assessment-executor.test.js +248 -0
- package/build/__tests__/assessment-runner/config-builder.test.js +289 -0
- package/build/__tests__/assessment-runner/index.test.js +41 -0
- package/build/__tests__/assessment-runner/server-config.test.js +249 -0
- package/build/__tests__/assessment-runner/server-connection.test.js +221 -0
- package/build/__tests__/assessment-runner/source-loader.test.js +341 -0
- package/build/__tests__/assessment-runner/tool-wrapper.test.js +114 -0
- package/build/__tests__/assessment-runner-facade.test.js +118 -0
- package/build/assess-full.js +26 -1254
- package/build/lib/assessment-runner/assessment-executor.js +323 -0
- package/build/lib/assessment-runner/config-builder.js +127 -0
- package/build/lib/assessment-runner/index.js +20 -0
- package/build/lib/assessment-runner/server-config.js +78 -0
- package/build/lib/assessment-runner/server-connection.js +80 -0
- package/build/lib/assessment-runner/source-loader.js +139 -0
- package/build/lib/assessment-runner/tool-wrapper.js +40 -0
- package/build/lib/assessment-runner/types.js +8 -0
- package/build/lib/assessment-runner.js +6 -740
- package/build/lib/comparison-handler.js +84 -0
- package/build/lib/result-output.js +154 -0
- package/package.json +1 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source File Loading
|
|
3
|
+
*
|
|
4
|
+
* Handles recursive source file discovery with gitignore support.
|
|
5
|
+
*
|
|
6
|
+
* @module cli/lib/assessment-runner/source-loader
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from "fs";
|
|
9
|
+
import * as path from "path";
|
|
10
|
+
/** Maximum file size (in characters) to include in source code analysis */
|
|
11
|
+
const MAX_SOURCE_FILE_SIZE = 100_000;
|
|
12
|
+
/**
|
|
13
|
+
* Load optional files from source code path
|
|
14
|
+
*
|
|
15
|
+
* @param sourcePath - Path to source code directory
|
|
16
|
+
* @returns Object containing loaded source files
|
|
17
|
+
*/
|
|
18
|
+
export function loadSourceFiles(sourcePath) {
|
|
19
|
+
const result = {};
|
|
20
|
+
// Search for README in source directory and parent directories (up to 3 levels)
|
|
21
|
+
// This handles cases where --source points to a subdirectory but README is at repo root
|
|
22
|
+
const readmePaths = ["README.md", "readme.md", "Readme.md"];
|
|
23
|
+
let readmeFound = false;
|
|
24
|
+
// First try the source directory itself
|
|
25
|
+
for (const readmePath of readmePaths) {
|
|
26
|
+
const fullPath = path.join(sourcePath, readmePath);
|
|
27
|
+
if (fs.existsSync(fullPath)) {
|
|
28
|
+
result.readmeContent = fs.readFileSync(fullPath, "utf-8");
|
|
29
|
+
readmeFound = true;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// If not found, search parent directories (up to 3 levels)
|
|
34
|
+
if (!readmeFound) {
|
|
35
|
+
let currentDir = sourcePath;
|
|
36
|
+
for (let i = 0; i < 3; i++) {
|
|
37
|
+
const parentDir = path.dirname(currentDir);
|
|
38
|
+
if (parentDir === currentDir)
|
|
39
|
+
break; // Reached filesystem root
|
|
40
|
+
for (const readmePath of readmePaths) {
|
|
41
|
+
const fullPath = path.join(parentDir, readmePath);
|
|
42
|
+
if (fs.existsSync(fullPath)) {
|
|
43
|
+
result.readmeContent = fs.readFileSync(fullPath, "utf-8");
|
|
44
|
+
readmeFound = true;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (readmeFound)
|
|
49
|
+
break;
|
|
50
|
+
currentDir = parentDir;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const packagePath = path.join(sourcePath, "package.json");
|
|
54
|
+
if (fs.existsSync(packagePath)) {
|
|
55
|
+
result.packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
|
|
56
|
+
}
|
|
57
|
+
const manifestPath = path.join(sourcePath, "manifest.json");
|
|
58
|
+
if (fs.existsSync(manifestPath)) {
|
|
59
|
+
result.manifestRaw = fs.readFileSync(manifestPath, "utf-8");
|
|
60
|
+
try {
|
|
61
|
+
result.manifestJson = JSON.parse(result.manifestRaw);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
console.warn("[Assessment] Failed to parse manifest.json");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
result.sourceCodeFiles = new Map();
|
|
68
|
+
// Include config files for portability analysis
|
|
69
|
+
const sourceExtensions = [
|
|
70
|
+
".ts",
|
|
71
|
+
".js",
|
|
72
|
+
".py",
|
|
73
|
+
".go",
|
|
74
|
+
".rs",
|
|
75
|
+
".json",
|
|
76
|
+
".sh",
|
|
77
|
+
".yaml",
|
|
78
|
+
".yml",
|
|
79
|
+
];
|
|
80
|
+
// Parse .gitignore patterns
|
|
81
|
+
const gitignorePatterns = [];
|
|
82
|
+
const gitignorePath = path.join(sourcePath, ".gitignore");
|
|
83
|
+
if (fs.existsSync(gitignorePath)) {
|
|
84
|
+
const gitignoreContent = fs.readFileSync(gitignorePath, "utf-8");
|
|
85
|
+
for (const line of gitignoreContent.split("\n")) {
|
|
86
|
+
const trimmed = line.trim();
|
|
87
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
88
|
+
continue;
|
|
89
|
+
// Convert gitignore pattern to regex
|
|
90
|
+
const pattern = trimmed
|
|
91
|
+
.replace(/\./g, "\\.")
|
|
92
|
+
.replace(/\*\*/g, ".*")
|
|
93
|
+
.replace(/\*/g, "[^/]*")
|
|
94
|
+
.replace(/\?/g, ".");
|
|
95
|
+
try {
|
|
96
|
+
gitignorePatterns.push(new RegExp(pattern));
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Skip invalid patterns
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const isGitignored = (relativePath) => {
|
|
104
|
+
return gitignorePatterns.some((pattern) => pattern.test(relativePath));
|
|
105
|
+
};
|
|
106
|
+
const loadSourceDir = (dir, prefix = "") => {
|
|
107
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
108
|
+
for (const entry of entries) {
|
|
109
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
110
|
+
continue;
|
|
111
|
+
const fullPath = path.join(dir, entry.name);
|
|
112
|
+
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
113
|
+
// Skip gitignored files
|
|
114
|
+
if (isGitignored(relativePath))
|
|
115
|
+
continue;
|
|
116
|
+
if (entry.isDirectory()) {
|
|
117
|
+
loadSourceDir(fullPath, relativePath);
|
|
118
|
+
}
|
|
119
|
+
else if (sourceExtensions.some((ext) => entry.name.endsWith(ext))) {
|
|
120
|
+
try {
|
|
121
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
122
|
+
if (content.length < MAX_SOURCE_FILE_SIZE) {
|
|
123
|
+
result.sourceCodeFiles.set(relativePath, content);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Skip unreadable files
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
try {
|
|
133
|
+
loadSourceDir(sourcePath);
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
console.warn("[Assessment] Could not load source files:", e);
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Call Wrapper
|
|
3
|
+
*
|
|
4
|
+
* Creates a wrapper around MCP client.callTool() for assessment context.
|
|
5
|
+
*
|
|
6
|
+
* @module cli/lib/assessment-runner/tool-wrapper
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Create callTool wrapper for assessment context
|
|
10
|
+
*
|
|
11
|
+
* @param client - Connected MCP client
|
|
12
|
+
* @returns Wrapped callTool function
|
|
13
|
+
*/
|
|
14
|
+
export function createCallToolWrapper(client) {
|
|
15
|
+
return async (name, params) => {
|
|
16
|
+
try {
|
|
17
|
+
const response = await client.callTool({
|
|
18
|
+
name,
|
|
19
|
+
arguments: params,
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
content: response.content,
|
|
23
|
+
isError: response.isError || false,
|
|
24
|
+
structuredContent: response
|
|
25
|
+
.structuredContent,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
isError: true,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|