igel-qe-core 1.0.8 → 1.0.9
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/cli/index.js +24 -7
- package/dist/mcp/server.js +23 -8
- package/package.json +1 -1
- package/src/cli/index.ts +24 -7
- package/src/deploy/requirements.txt +1 -0
- package/src/mcp/server.ts +22 -8
package/dist/cli/index.js
CHANGED
|
@@ -15,9 +15,26 @@ program
|
|
|
15
15
|
.description("IGEL QE Developer Experience CLI")
|
|
16
16
|
.version("1.0.0");
|
|
17
17
|
// ── helpers ────────────────────────────────────────────────────────────────────
|
|
18
|
+
function getSystemPython() {
|
|
19
|
+
for (const cmd of ["python3", "python", "py"]) {
|
|
20
|
+
try {
|
|
21
|
+
const res = spawnSync(cmd, ["--version"], { stdio: "ignore" });
|
|
22
|
+
if (res.status === 0 || res.status === null) {
|
|
23
|
+
return cmd;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Continue
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return "python3";
|
|
31
|
+
}
|
|
18
32
|
function getPythonBin() {
|
|
19
|
-
const
|
|
20
|
-
|
|
33
|
+
const isWin = process.platform === "win32";
|
|
34
|
+
const venv = isWin
|
|
35
|
+
? join(PROJECT_ROOT, ".venv", "Scripts", "python.exe")
|
|
36
|
+
: join(PROJECT_ROOT, ".venv", "bin", "python");
|
|
37
|
+
return existsSync(venv) ? venv : getSystemPython();
|
|
21
38
|
}
|
|
22
39
|
function resolveRequirementsPath() {
|
|
23
40
|
const primary = join(PROJECT_ROOT, "requirements.txt");
|
|
@@ -196,11 +213,11 @@ function listFrameworkContextFiles(workspaceRoot) {
|
|
|
196
213
|
return Array.from(new Set(found)).sort();
|
|
197
214
|
}
|
|
198
215
|
function isCopilotCliAvailable() {
|
|
199
|
-
const check = spawnSync("copilot", ["--version"], { encoding: "utf-8" });
|
|
216
|
+
const check = spawnSync("copilot", ["--version"], { encoding: "utf-8", shell: process.platform === "win32" });
|
|
200
217
|
return check.status === 0;
|
|
201
218
|
}
|
|
202
219
|
function isCopilotAuthenticated(workspaceRoot) {
|
|
203
|
-
const probe = spawnSync("copilot", ["-C", workspaceRoot, "-p", "Reply with exactly OK.", "--allow-all-tools", "--no-color", "-s"], { encoding: "utf-8" });
|
|
220
|
+
const probe = spawnSync("copilot", ["-C", workspaceRoot, "-p", "Reply with exactly OK.", "--allow-all-tools", "--no-color", "-s"], { encoding: "utf-8", shell: process.platform === "win32" });
|
|
204
221
|
return probe.status === 0;
|
|
205
222
|
}
|
|
206
223
|
function ensureCopilotLogin(workspaceRoot) {
|
|
@@ -210,7 +227,7 @@ function ensureCopilotLogin(workspaceRoot) {
|
|
|
210
227
|
return true;
|
|
211
228
|
console.log(chalk.yellow(" ⚠ GitHub Copilot CLI is not authenticated."));
|
|
212
229
|
console.log(chalk.yellow(" → Please complete Copilot login to continue context enrichment."));
|
|
213
|
-
const login = spawnSync("copilot", ["login"], { stdio: "inherit", encoding: "utf-8" });
|
|
230
|
+
const login = spawnSync("copilot", ["login"], { stdio: "inherit", encoding: "utf-8", shell: process.platform === "win32" });
|
|
214
231
|
if (login.status !== 0)
|
|
215
232
|
return false;
|
|
216
233
|
return isCopilotAuthenticated(workspaceRoot);
|
|
@@ -237,7 +254,7 @@ function enrichWithCopilotCli(workspaceRoot, contextFiles) {
|
|
|
237
254
|
"--allow-all-paths",
|
|
238
255
|
"--no-color",
|
|
239
256
|
"-s",
|
|
240
|
-
], { encoding: "utf-8" });
|
|
257
|
+
], { encoding: "utf-8", shell: process.platform === "win32" });
|
|
241
258
|
if (result.status === 0) {
|
|
242
259
|
updated += 1;
|
|
243
260
|
}
|
|
@@ -345,7 +362,7 @@ program
|
|
|
345
362
|
if (!existsSync(venvPath)) {
|
|
346
363
|
console.log(chalk.yellow("1. Creating virtual environment…"));
|
|
347
364
|
try {
|
|
348
|
-
execSync(
|
|
365
|
+
execSync(`${getSystemPython()} -m venv .venv`, { cwd: PROJECT_ROOT, stdio: "inherit" });
|
|
349
366
|
console.log(chalk.green(" ✓ venv created"));
|
|
350
367
|
}
|
|
351
368
|
catch (e) {
|
package/dist/mcp/server.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
-
import { spawn } from "child_process";
|
|
6
|
+
import { spawn, spawnSync } from "child_process";
|
|
7
7
|
import path from "path";
|
|
8
8
|
import { fileURLToPath } from "url";
|
|
9
9
|
import fs from "fs";
|
|
@@ -11,18 +11,33 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
11
11
|
// Project root: dist/mcp/server.js -> ../../ = project root
|
|
12
12
|
const PROJECT_ROOT = path.resolve(__dirname, '..', '..');
|
|
13
13
|
// Resolve the correct Python executable:
|
|
14
|
-
// 1. Check for a local .venv
|
|
15
|
-
// 2. Fall back to system python3 / python
|
|
14
|
+
// 1. Check for a local .venv (Linux or Windows path layouts)
|
|
15
|
+
// 2. Fall back to system python3 / python / py
|
|
16
16
|
function resolvePythonExecutable() {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const isWin = process.platform === 'win32';
|
|
18
|
+
const candidates = isWin
|
|
19
|
+
? [
|
|
20
|
+
path.join(PROJECT_ROOT, '.venv', 'Scripts', 'python.exe'),
|
|
21
|
+
path.join(PROJECT_ROOT, '.venv', 'Scripts', 'python'),
|
|
22
|
+
]
|
|
23
|
+
: [
|
|
24
|
+
path.join(PROJECT_ROOT, '.venv', 'bin', 'python'),
|
|
25
|
+
path.join(PROJECT_ROOT, '.venv', 'bin', 'python3'),
|
|
26
|
+
];
|
|
21
27
|
for (const c of candidates) {
|
|
22
28
|
if (fs.existsSync(c))
|
|
23
29
|
return c;
|
|
24
30
|
}
|
|
25
|
-
// Check system python3 / python
|
|
31
|
+
// Check system python3 / python / py
|
|
32
|
+
for (const cmd of ['python3', 'python', 'py']) {
|
|
33
|
+
try {
|
|
34
|
+
const res = spawnSync(cmd, ['--version'], { stdio: 'ignore' });
|
|
35
|
+
if (res.status === 0 || res.status === null) {
|
|
36
|
+
return cmd;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
}
|
|
26
41
|
return 'python3';
|
|
27
42
|
}
|
|
28
43
|
const server = new Server({
|
package/package.json
CHANGED
package/src/cli/index.ts
CHANGED
|
@@ -21,9 +21,26 @@ program
|
|
|
21
21
|
|
|
22
22
|
// ── helpers ────────────────────────────────────────────────────────────────────
|
|
23
23
|
|
|
24
|
+
function getSystemPython(): string {
|
|
25
|
+
for (const cmd of ["python3", "python", "py"]) {
|
|
26
|
+
try {
|
|
27
|
+
const res = spawnSync(cmd, ["--version"], { stdio: "ignore" });
|
|
28
|
+
if (res.status === 0 || res.status === null) {
|
|
29
|
+
return cmd;
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
// Continue
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return "python3";
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
function getPythonBin(): string {
|
|
25
|
-
const
|
|
26
|
-
|
|
39
|
+
const isWin = process.platform === "win32";
|
|
40
|
+
const venv = isWin
|
|
41
|
+
? join(PROJECT_ROOT, ".venv", "Scripts", "python.exe")
|
|
42
|
+
: join(PROJECT_ROOT, ".venv", "bin", "python");
|
|
43
|
+
return existsSync(venv) ? venv : getSystemPython();
|
|
27
44
|
}
|
|
28
45
|
|
|
29
46
|
function resolveRequirementsPath(): string | null {
|
|
@@ -206,7 +223,7 @@ function listFrameworkContextFiles(workspaceRoot: string): string[] {
|
|
|
206
223
|
}
|
|
207
224
|
|
|
208
225
|
function isCopilotCliAvailable(): boolean {
|
|
209
|
-
const check = spawnSync("copilot", ["--version"], { encoding: "utf-8" });
|
|
226
|
+
const check = spawnSync("copilot", ["--version"], { encoding: "utf-8", shell: process.platform === "win32" });
|
|
210
227
|
return check.status === 0;
|
|
211
228
|
}
|
|
212
229
|
|
|
@@ -214,7 +231,7 @@ function isCopilotAuthenticated(workspaceRoot: string): boolean {
|
|
|
214
231
|
const probe = spawnSync(
|
|
215
232
|
"copilot",
|
|
216
233
|
["-C", workspaceRoot, "-p", "Reply with exactly OK.", "--allow-all-tools", "--no-color", "-s"],
|
|
217
|
-
{ encoding: "utf-8" },
|
|
234
|
+
{ encoding: "utf-8", shell: process.platform === "win32" },
|
|
218
235
|
);
|
|
219
236
|
return probe.status === 0;
|
|
220
237
|
}
|
|
@@ -226,7 +243,7 @@ function ensureCopilotLogin(workspaceRoot: string): boolean {
|
|
|
226
243
|
console.log(chalk.yellow(" ⚠ GitHub Copilot CLI is not authenticated."));
|
|
227
244
|
console.log(chalk.yellow(" → Please complete Copilot login to continue context enrichment."));
|
|
228
245
|
|
|
229
|
-
const login = spawnSync("copilot", ["login"], { stdio: "inherit", encoding: "utf-8" });
|
|
246
|
+
const login = spawnSync("copilot", ["login"], { stdio: "inherit", encoding: "utf-8", shell: process.platform === "win32" });
|
|
230
247
|
if (login.status !== 0) return false;
|
|
231
248
|
return isCopilotAuthenticated(workspaceRoot);
|
|
232
249
|
}
|
|
@@ -258,7 +275,7 @@ function enrichWithCopilotCli(workspaceRoot: string, contextFiles: string[]): {
|
|
|
258
275
|
"--no-color",
|
|
259
276
|
"-s",
|
|
260
277
|
],
|
|
261
|
-
{ encoding: "utf-8" },
|
|
278
|
+
{ encoding: "utf-8", shell: process.platform === "win32" },
|
|
262
279
|
);
|
|
263
280
|
|
|
264
281
|
if (result.status === 0) {
|
|
@@ -376,7 +393,7 @@ program
|
|
|
376
393
|
if (!existsSync(venvPath)) {
|
|
377
394
|
console.log(chalk.yellow("1. Creating virtual environment…"));
|
|
378
395
|
try {
|
|
379
|
-
execSync(
|
|
396
|
+
execSync(`${getSystemPython()} -m venv .venv`, { cwd: PROJECT_ROOT, stdio: "inherit" });
|
|
380
397
|
console.log(chalk.green(" ✓ venv created"));
|
|
381
398
|
} catch (e: unknown) {
|
|
382
399
|
console.log(chalk.yellow(` ⚠ venv setup skipped: ${e instanceof Error ? e.message : String(e)}`));
|
|
@@ -28,6 +28,7 @@ pydantic>=2.7.0
|
|
|
28
28
|
eval_type_backport>=0.2.0; python_version < "3.10"
|
|
29
29
|
tenacity==9.0.0
|
|
30
30
|
rich==13.9.4
|
|
31
|
+
PyYAML>=6.0.1
|
|
31
32
|
|
|
32
33
|
# OSS local reranker (CrossEncoder — free, runs on CPU/GPU)
|
|
33
34
|
# Default model: BAAI/bge-reranker-v2-m3 (multilingual, best open-source for IGEL DE/EN)
|
package/src/mcp/server.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
-
import { spawn } from "child_process";
|
|
6
|
+
import { spawn, spawnSync } from "child_process";
|
|
7
7
|
import path from "path";
|
|
8
8
|
import { fileURLToPath } from "url";
|
|
9
9
|
import fs from "fs";
|
|
@@ -14,17 +14,31 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
14
14
|
const PROJECT_ROOT = path.resolve(__dirname, '..', '..');
|
|
15
15
|
|
|
16
16
|
// Resolve the correct Python executable:
|
|
17
|
-
// 1. Check for a local .venv
|
|
18
|
-
// 2. Fall back to system python3 / python
|
|
17
|
+
// 1. Check for a local .venv (Linux or Windows path layouts)
|
|
18
|
+
// 2. Fall back to system python3 / python / py
|
|
19
19
|
function resolvePythonExecutable(): string {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const isWin = process.platform === 'win32';
|
|
21
|
+
const candidates = isWin
|
|
22
|
+
? [
|
|
23
|
+
path.join(PROJECT_ROOT, '.venv', 'Scripts', 'python.exe'),
|
|
24
|
+
path.join(PROJECT_ROOT, '.venv', 'Scripts', 'python'),
|
|
25
|
+
]
|
|
26
|
+
: [
|
|
27
|
+
path.join(PROJECT_ROOT, '.venv', 'bin', 'python'),
|
|
28
|
+
path.join(PROJECT_ROOT, '.venv', 'bin', 'python3'),
|
|
29
|
+
];
|
|
24
30
|
for (const c of candidates) {
|
|
25
31
|
if (fs.existsSync(c)) return c;
|
|
26
32
|
}
|
|
27
|
-
// Check system python3 / python
|
|
33
|
+
// Check system python3 / python / py
|
|
34
|
+
for (const cmd of ['python3', 'python', 'py']) {
|
|
35
|
+
try {
|
|
36
|
+
const res = spawnSync(cmd, ['--version'], { stdio: 'ignore' });
|
|
37
|
+
if (res.status === 0 || res.status === null) {
|
|
38
|
+
return cmd;
|
|
39
|
+
}
|
|
40
|
+
} catch {}
|
|
41
|
+
}
|
|
28
42
|
return 'python3';
|
|
29
43
|
}
|
|
30
44
|
|