@rk0429/agentic-relay 19.14.2 → 19.14.4
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/self-update.d.ts +17 -1
- package/dist/application/self-update.js +97 -22
- package/dist/application/self-update.js.map +1 -1
- package/dist/infrastructure/backends/backend-registry.js +3 -26
- package/dist/infrastructure/backends/backend-registry.js.map +1 -1
- package/dist/infrastructure/process/process-executor.d.ts +2 -2
- package/dist/infrastructure/process/process-executor.js +4 -4
- package/dist/infrastructure/process/process-executor.js.map +1 -1
- package/dist/infrastructure/process/resolve-command.d.ts +28 -0
- package/dist/infrastructure/process/resolve-command.js +125 -0
- package/dist/infrastructure/process/resolve-command.js.map +1 -0
- package/dist/interfaces/mcp/relay-mcp-server.js +1 -1
- package/package.json +3 -1
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export type PackageManagerKind = "npm" | "pnpm" | "volta" | "unknown";
|
|
2
|
+
export interface PackageManagerInfo {
|
|
3
|
+
kind: PackageManagerKind;
|
|
4
|
+
command: string;
|
|
5
|
+
installArgs: (pkg: string) => string[];
|
|
6
|
+
listArgs: (pkg: string) => string[];
|
|
7
|
+
}
|
|
1
8
|
export interface UpdateCheckResult {
|
|
2
9
|
currentVersion: string;
|
|
3
10
|
latestVersion: string;
|
|
@@ -11,4 +18,13 @@ export declare function verifyInstalledVersion(expectedVersion: string): Promise
|
|
|
11
18
|
}>;
|
|
12
19
|
export declare function getCurrentVersion(): Promise<string>;
|
|
13
20
|
export declare function isNewerVersion(current: string, latest: string): boolean;
|
|
14
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Detect which package manager installed the currently running agentic-relay.
|
|
23
|
+
*
|
|
24
|
+
* Uses `import.meta.filename` (symlink-resolved absolute path of the current
|
|
25
|
+
* module) to identify the installation directory, then matches against known
|
|
26
|
+
* directory patterns for each package manager.
|
|
27
|
+
*
|
|
28
|
+
* @param modulePathOverride - Override the module path for testing.
|
|
29
|
+
*/
|
|
30
|
+
export declare function detectPackageManager(modulePathOverride?: string): PackageManagerInfo;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import crossSpawn from "cross-spawn";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -18,49 +18,70 @@ export async function checkForUpdate() {
|
|
|
18
18
|
}
|
|
19
19
|
export async function performUpdate(check) {
|
|
20
20
|
const pm = detectPackageManager();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
if (pm.kind === "unknown") {
|
|
22
|
+
throw new Error("Could not determine the package manager that installed agentic-relay.\n" +
|
|
23
|
+
"Please update manually using the package manager you used to install it.");
|
|
24
|
+
}
|
|
25
|
+
const args = pm.installArgs(`${PACKAGE_NAME}@${check.latestVersion}`);
|
|
24
26
|
const exitCode = await new Promise((resolve, reject) => {
|
|
25
|
-
const child =
|
|
27
|
+
const child = crossSpawn(pm.command, args, { stdio: "inherit" });
|
|
26
28
|
child.on("error", reject);
|
|
27
29
|
child.on("close", (code) => resolve(code ?? 1));
|
|
28
30
|
});
|
|
29
31
|
if (exitCode !== 0) {
|
|
30
|
-
throw new Error(`${pm} exited with code ${exitCode}.\nManual update: ${pm} ${args.join(" ")}`);
|
|
32
|
+
throw new Error(`${pm.command} exited with code ${exitCode}.\nManual update: ${pm.command} ${args.join(" ")}`);
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
export async function verifyInstalledVersion(expectedVersion) {
|
|
34
36
|
const pm = detectPackageManager();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
if (pm.kind === "unknown") {
|
|
38
|
+
return { installed: "unknown", match: false };
|
|
39
|
+
}
|
|
40
|
+
if (pm.kind === "volta") {
|
|
41
|
+
const installed = await getVoltaInstalledVersion();
|
|
42
|
+
return { installed, match: installed === expectedVersion };
|
|
43
|
+
}
|
|
44
|
+
const args = pm.listArgs(PACKAGE_NAME);
|
|
38
45
|
const output = await new Promise((resolve, reject) => {
|
|
39
46
|
let stdout = "";
|
|
40
|
-
const child =
|
|
47
|
+
const child = crossSpawn(pm.command, args, { stdio: ["ignore", "pipe", "ignore"] });
|
|
41
48
|
child.stdout?.on("data", (chunk) => {
|
|
42
49
|
stdout += chunk.toString();
|
|
43
50
|
});
|
|
44
51
|
child.on("error", reject);
|
|
45
52
|
child.on("close", () => resolve(stdout));
|
|
46
53
|
});
|
|
47
|
-
const installed = parseInstalledVersion(output, pm);
|
|
54
|
+
const installed = parseInstalledVersion(output, pm.kind);
|
|
48
55
|
return { installed, match: installed === expectedVersion };
|
|
49
56
|
}
|
|
50
|
-
function parseInstalledVersion(json,
|
|
57
|
+
function parseInstalledVersion(json, _kind) {
|
|
51
58
|
try {
|
|
52
59
|
const data = JSON.parse(json);
|
|
53
|
-
|
|
54
|
-
const deps = data.dependencies;
|
|
55
|
-
return deps?.[PACKAGE_NAME]?.version ?? "unknown";
|
|
56
|
-
}
|
|
57
|
-
const deps = data.dependencies;
|
|
58
|
-
return deps?.[PACKAGE_NAME]?.version ?? "unknown";
|
|
60
|
+
return data.dependencies?.[PACKAGE_NAME]?.version ?? "unknown";
|
|
59
61
|
}
|
|
60
62
|
catch {
|
|
61
63
|
return "unknown";
|
|
62
64
|
}
|
|
63
65
|
}
|
|
66
|
+
async function getVoltaInstalledVersion() {
|
|
67
|
+
const output = await new Promise((resolve, reject) => {
|
|
68
|
+
let stdout = "";
|
|
69
|
+
const child = crossSpawn("volta", ["list", PACKAGE_NAME, "--format=plain"], {
|
|
70
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
71
|
+
});
|
|
72
|
+
child.stdout?.on("data", (chunk) => {
|
|
73
|
+
stdout += chunk.toString();
|
|
74
|
+
});
|
|
75
|
+
child.on("error", reject);
|
|
76
|
+
child.on("close", () => resolve(stdout));
|
|
77
|
+
});
|
|
78
|
+
// volta list output format: "package @rk0429/agentic-relay@19.14.3 (default)"
|
|
79
|
+
const match = new RegExp(`${escapeRegExp(PACKAGE_NAME)}@(\\S+)`).exec(output);
|
|
80
|
+
return match?.[1] ?? "unknown";
|
|
81
|
+
}
|
|
82
|
+
function escapeRegExp(s) {
|
|
83
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
84
|
+
}
|
|
64
85
|
export async function getCurrentVersion() {
|
|
65
86
|
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
66
87
|
const packageJsonPath = path.resolve(dirname, "..", "..", "package.json");
|
|
@@ -92,11 +113,65 @@ export function isNewerVersion(current, latest) {
|
|
|
92
113
|
}
|
|
93
114
|
return false;
|
|
94
115
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
116
|
+
const PM_INFO = {
|
|
117
|
+
npm: {
|
|
118
|
+
command: "npm",
|
|
119
|
+
installArgs: (pkg) => ["install", "-g", pkg],
|
|
120
|
+
listArgs: (pkg) => ["ls", "-g", pkg, "--json"],
|
|
121
|
+
},
|
|
122
|
+
pnpm: {
|
|
123
|
+
command: "pnpm",
|
|
124
|
+
installArgs: (pkg) => ["add", "-g", pkg],
|
|
125
|
+
listArgs: (pkg) => ["list", "-g", pkg, "--json"],
|
|
126
|
+
},
|
|
127
|
+
volta: {
|
|
128
|
+
command: "volta",
|
|
129
|
+
installArgs: (pkg) => ["install", pkg],
|
|
130
|
+
listArgs: (pkg) => ["list", pkg, "--format=plain"],
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Detect which package manager installed the currently running agentic-relay.
|
|
135
|
+
*
|
|
136
|
+
* Uses `import.meta.filename` (symlink-resolved absolute path of the current
|
|
137
|
+
* module) to identify the installation directory, then matches against known
|
|
138
|
+
* directory patterns for each package manager.
|
|
139
|
+
*
|
|
140
|
+
* @param modulePathOverride - Override the module path for testing.
|
|
141
|
+
*/
|
|
142
|
+
export function detectPackageManager(modulePathOverride) {
|
|
143
|
+
const modulePath = normalisePathSeparators(modulePathOverride ?? import.meta.filename ?? fileURLToPath(import.meta.url));
|
|
144
|
+
const kind = classifyInstallPath(modulePath);
|
|
145
|
+
if (kind === "unknown") {
|
|
146
|
+
return {
|
|
147
|
+
kind: "unknown",
|
|
148
|
+
command: "",
|
|
149
|
+
installArgs: () => [],
|
|
150
|
+
listArgs: () => [],
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return { kind, ...PM_INFO[kind] };
|
|
154
|
+
}
|
|
155
|
+
function classifyInstallPath(modulePath) {
|
|
156
|
+
// Volta: $VOLTA_HOME/tools/image/packages/<pkg>/...
|
|
157
|
+
if (/\/tools\/image\/packages\//i.test(modulePath)) {
|
|
158
|
+
return "volta";
|
|
159
|
+
}
|
|
160
|
+
// pnpm: {pnpmHome}/global/v11/... or legacy global/5/...
|
|
161
|
+
if (/\/pnpm\/global\/(?:v?\d+)\//i.test(modulePath)) {
|
|
162
|
+
return "pnpm";
|
|
163
|
+
}
|
|
164
|
+
// pnpm: also match /.pnpm/ (store-based layout)
|
|
165
|
+
if (/\/\.pnpm\//i.test(modulePath)) {
|
|
98
166
|
return "pnpm";
|
|
99
167
|
}
|
|
100
|
-
|
|
168
|
+
// npm: {prefix}/lib/node_modules/<pkg>/... or {prefix}/node_modules/<pkg>/...
|
|
169
|
+
if (/\/node_modules\//i.test(modulePath)) {
|
|
170
|
+
return "npm";
|
|
171
|
+
}
|
|
172
|
+
return "unknown";
|
|
173
|
+
}
|
|
174
|
+
function normalisePathSeparators(p) {
|
|
175
|
+
return p.replace(/\\/g, "/");
|
|
101
176
|
}
|
|
102
177
|
//# sourceMappingURL=self-update.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"self-update.js","sourceRoot":"","sources":["../../src/application/self-update.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"self-update.js","sourceRoot":"","sources":["../../src/application/self-update.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,32 +1,9 @@
|
|
|
1
|
-
import { access } from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
1
|
import { BACKEND_TYPES } from "../../core/types.js";
|
|
2
|
+
import { resolveCommand } from "../process/resolve-command.js";
|
|
4
3
|
class PathCommandAvailabilityChecker {
|
|
5
4
|
async isAvailable(command) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
await access(command);
|
|
9
|
-
return true;
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
const pathValue = process.env.PATH ?? "";
|
|
16
|
-
for (const segment of pathValue.split(path.delimiter)) {
|
|
17
|
-
if (!segment) {
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
const candidate = path.join(segment, command);
|
|
21
|
-
try {
|
|
22
|
-
await access(candidate);
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return false;
|
|
5
|
+
const resolved = await resolveCommand(command, process.env);
|
|
6
|
+
return resolved !== null;
|
|
30
7
|
}
|
|
31
8
|
}
|
|
32
9
|
export class BackendRegistry {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-registry.js","sourceRoot":"","sources":["../../../src/infrastructure/backends/backend-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backend-registry.js","sourceRoot":"","sources":["../../../src/infrastructure/backends/backend-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAiB/D,MAAM,8BAA8B;IAClC,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5D,OAAO,QAAQ,KAAK,IAAI,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,eAAe;IAEP;IACA;IAFnB,YACmB,UAAsC,IAAI,8BAA8B,EAAE,EAC1E,mBAAyD,EAAE;QAD3D,YAAO,GAAP,OAAO,CAAmE;QAC1E,qBAAgB,GAAhB,gBAAgB,CAA2C;IAC3E,CAAC;IAEG,UAAU,CAAC,IAAiB;QACjC,OAAO;YACL,IAAI;YACJ,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI;YAC5C,aAAa,EAAE,gBAAgB,CAAC,IAAI,CAAC;SACtC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,eAAe;QAC1B,MAAM,SAAS,GAAkB,EAAE,CAAC;QAEpC,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACzC,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpD,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AAED,SAAS,gBAAgB,CAAC,IAAiB;IACzC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO;gBACL,QAAQ,EAAE,CAAC,mBAAmB,EAAE,OAAO,CAAC;aACzC,CAAC;QACJ,KAAK,OAAO;YACV,OAAO;gBACL,QAAQ,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,CAAC;aACpE,CAAC;QACJ,KAAK,QAAQ;YACX,OAAO;gBACL,QAAQ,EAAE,EAAE;gBACZ,iBAAiB,EAAE;oBACjB,YAAY,EAAE;wBACZ,YAAY,EAAE,KAAK;qBACpB;oBACD,MAAM,EAAE;wBACN,SAAS,EAAE;4BACT,qBAAqB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;4BACzC,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;4BAC5B,gBAAgB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;4BACpC,aAAa,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;yBAClC;qBACF;iBACF;aACF,CAAC;IACN,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import crossSpawn from "cross-spawn";
|
|
2
2
|
export interface ProcessExecutionInput {
|
|
3
3
|
command: string;
|
|
4
4
|
args: string[];
|
|
@@ -35,7 +35,7 @@ export interface InteractiveProcessRunner {
|
|
|
35
35
|
run(input: InteractiveProcessInput): Promise<number>;
|
|
36
36
|
}
|
|
37
37
|
export interface ChildProcessExecutorDependencies {
|
|
38
|
-
spawnProcess?: typeof
|
|
38
|
+
spawnProcess?: typeof crossSpawn;
|
|
39
39
|
platform?: NodeJS.Platform;
|
|
40
40
|
killProcess?: typeof process.kill;
|
|
41
41
|
setTimer?: typeof setTimeout;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import crossSpawn from "cross-spawn";
|
|
2
2
|
import { RelayError } from "../../core/errors.js";
|
|
3
3
|
const DEFAULT_PROCESS_TERMINATION_GRACE_MS = 5_000;
|
|
4
4
|
export class ChildProcessExecutor {
|
|
@@ -7,7 +7,7 @@ export class ChildProcessExecutor {
|
|
|
7
7
|
this.dependencies = dependencies;
|
|
8
8
|
}
|
|
9
9
|
async execute(input) {
|
|
10
|
-
const spawnProcess = this.dependencies.spawnProcess ??
|
|
10
|
+
const spawnProcess = this.dependencies.spawnProcess ?? crossSpawn;
|
|
11
11
|
const platform = this.dependencies.platform ?? process.platform;
|
|
12
12
|
return new Promise((resolve, reject) => {
|
|
13
13
|
const child = spawnProcess(input.command, input.args, {
|
|
@@ -73,7 +73,7 @@ export class ChildProcessExecutor {
|
|
|
73
73
|
export class ChildProcessInteractiveRunner {
|
|
74
74
|
async run(input) {
|
|
75
75
|
return new Promise((resolve, reject) => {
|
|
76
|
-
const child =
|
|
76
|
+
const child = crossSpawn(input.command, input.args, {
|
|
77
77
|
cwd: input.cwd,
|
|
78
78
|
env: input.env,
|
|
79
79
|
stdio: "inherit",
|
|
@@ -92,7 +92,7 @@ export class ChildProcessInteractiveRunner {
|
|
|
92
92
|
function createProcessTreeKiller(child, dependencies) {
|
|
93
93
|
const platform = dependencies.platform ?? process.platform;
|
|
94
94
|
const killProcess = dependencies.killProcess ?? process.kill.bind(process);
|
|
95
|
-
const spawnProcess = dependencies.spawnProcess ??
|
|
95
|
+
const spawnProcess = dependencies.spawnProcess ?? crossSpawn;
|
|
96
96
|
const setTimerFn = dependencies.setTimer ?? setTimeout;
|
|
97
97
|
const clearTimerFn = dependencies.clearTimer ?? clearTimeout;
|
|
98
98
|
const terminationGraceMs = dependencies.terminationGraceMs ?? DEFAULT_PROCESS_TERMINATION_GRACE_MS;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-executor.js","sourceRoot":"","sources":["../../../src/infrastructure/process/process-executor.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"process-executor.js","sourceRoot":"","sources":["../../../src/infrastructure/process/process-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface ResolvedCommand {
|
|
2
|
+
resolvedPath: string;
|
|
3
|
+
isBatchFile: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Resolve a command name to an absolute path, respecting PATHEXT on Windows.
|
|
7
|
+
*
|
|
8
|
+
* Used by both command availability detection and process execution to ensure
|
|
9
|
+
* consistent resolution. On Windows, `.cmd`/`.bat` shims (e.g. those created
|
|
10
|
+
* by Volta) are discovered via PATHEXT, which libuv's `search_path()` does
|
|
11
|
+
* not consult.
|
|
12
|
+
*
|
|
13
|
+
* Notable differences from libuv's `search_path()`:
|
|
14
|
+
* - Does not search the current directory before PATH segments.
|
|
15
|
+
* - PATH fallback when the variable is unset may differ.
|
|
16
|
+
*
|
|
17
|
+
* These differences are acceptable for agentic-relay's call sites, where
|
|
18
|
+
* commands are fixed backend names (claude/codex/gemini) resolved via PATH.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveCommand(command: string, env: NodeJS.ProcessEnv, platform?: NodeJS.Platform): Promise<ResolvedCommand | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Look up an environment variable key case-insensitively.
|
|
23
|
+
*
|
|
24
|
+
* On Windows, env variable names are case-insensitive (e.g. `PATH` vs `Path`).
|
|
25
|
+
* Node.js normalises keys for `process.env` on Windows, but when env objects
|
|
26
|
+
* are spread or merged (as in CliBackendExecutor), casing may vary.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getEnvInsensitive(env: NodeJS.ProcessEnv, key: string): string | undefined;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const WIN32_PATHEXT_DEFAULTS = [".COM", ".EXE", ".BAT", ".CMD"];
|
|
4
|
+
/**
|
|
5
|
+
* Resolve a command name to an absolute path, respecting PATHEXT on Windows.
|
|
6
|
+
*
|
|
7
|
+
* Used by both command availability detection and process execution to ensure
|
|
8
|
+
* consistent resolution. On Windows, `.cmd`/`.bat` shims (e.g. those created
|
|
9
|
+
* by Volta) are discovered via PATHEXT, which libuv's `search_path()` does
|
|
10
|
+
* not consult.
|
|
11
|
+
*
|
|
12
|
+
* Notable differences from libuv's `search_path()`:
|
|
13
|
+
* - Does not search the current directory before PATH segments.
|
|
14
|
+
* - PATH fallback when the variable is unset may differ.
|
|
15
|
+
*
|
|
16
|
+
* These differences are acceptable for agentic-relay's call sites, where
|
|
17
|
+
* commands are fixed backend names (claude/codex/gemini) resolved via PATH.
|
|
18
|
+
*/
|
|
19
|
+
export async function resolveCommand(command, env, platform = process.platform) {
|
|
20
|
+
if (path.isAbsolute(command) ||
|
|
21
|
+
command.includes(path.sep) ||
|
|
22
|
+
(platform === "win32" && command.includes("/"))) {
|
|
23
|
+
return resolveExplicitPath(command, env, platform);
|
|
24
|
+
}
|
|
25
|
+
if (platform !== "win32") {
|
|
26
|
+
return resolveUnixCommand(command, env);
|
|
27
|
+
}
|
|
28
|
+
return resolveWindowsCommand(command, env);
|
|
29
|
+
}
|
|
30
|
+
async function resolveExplicitPath(command, env, platform) {
|
|
31
|
+
if (await fileExists(command)) {
|
|
32
|
+
return {
|
|
33
|
+
resolvedPath: command,
|
|
34
|
+
isBatchFile: platform === "win32" && isBatchExtension(path.extname(command)),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (platform === "win32" && !path.extname(command)) {
|
|
38
|
+
return resolveWithExtensions(command, getPathext(env));
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
async function resolveUnixCommand(command, env) {
|
|
43
|
+
const pathValue = env.PATH ?? "";
|
|
44
|
+
for (const segment of pathValue.split(path.delimiter)) {
|
|
45
|
+
if (!segment) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const candidate = path.join(segment, command);
|
|
49
|
+
if (await fileExists(candidate)) {
|
|
50
|
+
return { resolvedPath: candidate, isBatchFile: false };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
async function resolveWindowsCommand(command, env) {
|
|
56
|
+
const pathext = getPathext(env);
|
|
57
|
+
const pathValue = getEnvInsensitive(env, "PATH") ?? "";
|
|
58
|
+
for (const segment of pathValue.split(path.delimiter)) {
|
|
59
|
+
if (!segment) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (path.extname(command)) {
|
|
63
|
+
const candidate = path.join(segment, command);
|
|
64
|
+
if (await fileExists(candidate)) {
|
|
65
|
+
return {
|
|
66
|
+
resolvedPath: candidate,
|
|
67
|
+
isBatchFile: isBatchExtension(path.extname(candidate)),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const resolved = await resolveWithExtensions(path.join(segment, command), pathext);
|
|
73
|
+
if (resolved) {
|
|
74
|
+
return resolved;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
async function resolveWithExtensions(basePath, pathext) {
|
|
80
|
+
for (const ext of pathext) {
|
|
81
|
+
const candidate = `${basePath}${ext}`;
|
|
82
|
+
if (await fileExists(candidate)) {
|
|
83
|
+
return {
|
|
84
|
+
resolvedPath: candidate,
|
|
85
|
+
isBatchFile: isBatchExtension(ext),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Look up an environment variable key case-insensitively.
|
|
93
|
+
*
|
|
94
|
+
* On Windows, env variable names are case-insensitive (e.g. `PATH` vs `Path`).
|
|
95
|
+
* Node.js normalises keys for `process.env` on Windows, but when env objects
|
|
96
|
+
* are spread or merged (as in CliBackendExecutor), casing may vary.
|
|
97
|
+
*/
|
|
98
|
+
export function getEnvInsensitive(env, key) {
|
|
99
|
+
const upperKey = key.toUpperCase();
|
|
100
|
+
for (const [k, v] of Object.entries(env)) {
|
|
101
|
+
if (k.toUpperCase() === upperKey) {
|
|
102
|
+
return v;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
function getPathext(env) {
|
|
108
|
+
return (getEnvInsensitive(env, "PATHEXT") ?? WIN32_PATHEXT_DEFAULTS.join(";"))
|
|
109
|
+
.split(";")
|
|
110
|
+
.filter(Boolean);
|
|
111
|
+
}
|
|
112
|
+
function isBatchExtension(ext) {
|
|
113
|
+
const upper = ext.toUpperCase();
|
|
114
|
+
return upper === ".CMD" || upper === ".BAT";
|
|
115
|
+
}
|
|
116
|
+
async function fileExists(filePath) {
|
|
117
|
+
try {
|
|
118
|
+
await access(filePath);
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=resolve-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-command.js","sourceRoot":"","sources":["../../../src/infrastructure/process/resolve-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -763,7 +763,7 @@ const TOOL_DESCRIPTIONS = {
|
|
|
763
763
|
export function createRelayMcpServer(options) {
|
|
764
764
|
const server = new McpServer({
|
|
765
765
|
name: "agentic-relay",
|
|
766
|
-
version: "19.14.
|
|
766
|
+
version: "19.14.4",
|
|
767
767
|
});
|
|
768
768
|
if (options.allowSpawnAgents) {
|
|
769
769
|
server.registerTool("spawn_agents", {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rk0429/agentic-relay",
|
|
3
|
-
"version": "19.14.
|
|
3
|
+
"version": "19.14.4",
|
|
4
4
|
"displayName": "agentic-relay",
|
|
5
5
|
"description": "Unified MCP relay for Claude Code, Codex CLI, and Gemini CLI",
|
|
6
6
|
"type": "module",
|
|
@@ -110,12 +110,14 @@
|
|
|
110
110
|
},
|
|
111
111
|
"dependencies": {
|
|
112
112
|
"@modelcontextprotocol/sdk": "1.27.1",
|
|
113
|
+
"cross-spawn": "^7.0.6",
|
|
113
114
|
"ink": "6.3.1",
|
|
114
115
|
"react": "19.2.0",
|
|
115
116
|
"yaml": "^2.8.2",
|
|
116
117
|
"zod": "4.3.6"
|
|
117
118
|
},
|
|
118
119
|
"devDependencies": {
|
|
120
|
+
"@types/cross-spawn": "^6.0.6",
|
|
119
121
|
"@types/node": "24.7.2",
|
|
120
122
|
"@types/react": "19.2.2",
|
|
121
123
|
"@types/vscode": "^1.110.0",
|