vibe-gate-mcp 0.1.7 → 0.1.8
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/CHANGELOG.md +11 -0
- package/dist/index.mjs +29 -28
- package/docs/CLI_PROVIDERS.md +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.8] - 2026-09-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Resolve explicitly selected CLI names through Windows `PATH` and `PATHEXT` before spawning, including Cursor's `agent.cmd` and legacy `cursor-agent.cmd` shims.
|
|
15
|
+
- Launch Windows `.cmd` and `.bat` shims through `cmd.exe` while keeping native executables on the direct spawn path.
|
|
16
|
+
|
|
17
|
+
### Tests
|
|
18
|
+
|
|
19
|
+
- Cover Windows `PATHEXT` resolution for explicit `agent` and `cursor-agent` commands and safely quoted batch-shim invocation.
|
|
20
|
+
|
|
10
21
|
## [0.1.7] - 2026-09-24
|
|
11
22
|
|
|
12
23
|
### Fixed
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { basename, dirname, extname, isAbsolute, join, normalize, relative, resolve } from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
5
|
import { config } from "dotenv";
|
|
5
6
|
import { accessSync, constants, existsSync, readFileSync } from "node:fs";
|
|
@@ -2487,9 +2488,32 @@ const WINDOWS_EXECUTABLE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
2487
2488
|
]);
|
|
2488
2489
|
const WINDOWS_BATCH_EXTENSIONS = /* @__PURE__ */ new Set([".BAT", ".CMD"]);
|
|
2489
2490
|
function executableExtensions(command, isWindows, pathExt = process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD") {
|
|
2490
|
-
|
|
2491
|
+
const commandExtension = isWindows ? path.win32.extname(command) : extname(command);
|
|
2492
|
+
if (!isWindows || commandExtension) return [""];
|
|
2491
2493
|
return pathExt.split(";").filter((extension) => WINDOWS_EXECUTABLE_EXTENSIONS.has(extension.toUpperCase()));
|
|
2492
2494
|
}
|
|
2495
|
+
function executableCandidates(command, options = {}) {
|
|
2496
|
+
const isWindows = (options.platform ?? process.platform) === "win32";
|
|
2497
|
+
const pathApi = isWindows ? path.win32 : path;
|
|
2498
|
+
const hasDirectory = pathApi.isAbsolute(command) || command.includes("/") || command.includes("\\");
|
|
2499
|
+
const pathValue = options.pathValue ?? process.env.PATH ?? process.env.Path ?? "";
|
|
2500
|
+
const pathDelimiter = isWindows ? ";" : path.delimiter;
|
|
2501
|
+
const bases = hasDirectory ? [pathApi.resolve(command)] : pathValue.split(pathDelimiter).filter(Boolean).map((directory) => pathApi.join(directory, command));
|
|
2502
|
+
const extensions = executableExtensions(command, isWindows, options.pathExt);
|
|
2503
|
+
return bases.flatMap((base) => extensions.map((extension) => extension ? `${base}${extension}` : base));
|
|
2504
|
+
}
|
|
2505
|
+
function findExecutable(command, options = {}) {
|
|
2506
|
+
const isWindows = (options.platform ?? process.platform) === "win32";
|
|
2507
|
+
const canAccess = options.canAccess ?? ((candidate, windows) => {
|
|
2508
|
+
try {
|
|
2509
|
+
accessSync(candidate, windows ? constants.F_OK : constants.X_OK);
|
|
2510
|
+
return true;
|
|
2511
|
+
} catch {
|
|
2512
|
+
return false;
|
|
2513
|
+
}
|
|
2514
|
+
});
|
|
2515
|
+
for (const candidate of executableCandidates(command, options)) if (canAccess(candidate, isWindows)) return candidate;
|
|
2516
|
+
}
|
|
2493
2517
|
function quoteCmdToken(value) {
|
|
2494
2518
|
if (/[%"\0\r\n]/.test(value)) throw new Error("Windows CLI arguments cannot contain percent signs, quotes, or line breaks.");
|
|
2495
2519
|
return `"${value}"`;
|
|
@@ -2556,10 +2580,11 @@ function sanitizeStderr(stderr) {
|
|
|
2556
2580
|
}
|
|
2557
2581
|
function runCli({ command, args, cwd, input, timeoutMs, label, env, keepCredentialEnvKeys }) {
|
|
2558
2582
|
return new Promise((resolve, reject) => {
|
|
2559
|
-
const
|
|
2583
|
+
const childEnv = createChildEnv(env, keepCredentialEnvKeys);
|
|
2584
|
+
const target = buildCliSpawnTarget(findExecutable(command, { pathValue: childEnv.PATH ?? childEnv.Path }) ?? command, args);
|
|
2560
2585
|
const child = spawn(target.command, target.args, {
|
|
2561
2586
|
cwd,
|
|
2562
|
-
env:
|
|
2587
|
+
env: childEnv,
|
|
2563
2588
|
shell: false,
|
|
2564
2589
|
windowsHide: true,
|
|
2565
2590
|
...target.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {},
|
|
@@ -3041,9 +3066,6 @@ function createOpenCodeCliProvider(command, model, timeoutMs) {
|
|
|
3041
3066
|
}
|
|
3042
3067
|
//#endregion
|
|
3043
3068
|
//#region src/llm/index.ts
|
|
3044
|
-
/**
|
|
3045
|
-
* LLM provider factory and local CLI auto-detection.
|
|
3046
|
-
*/
|
|
3047
3069
|
const AUTO_DETECT_CLI_ORDER = [
|
|
3048
3070
|
PROVIDERS.CODEX_CLI,
|
|
3049
3071
|
PROVIDERS.CLAUDE_CODE,
|
|
@@ -3064,27 +3086,6 @@ function commandCandidates(id, config) {
|
|
|
3064
3086
|
if (id === PROVIDERS.CURSOR_AGENT) return [CLI_DEFAULT_COMMANDS[id], CURSOR_AGENT_LEGACY_COMMAND];
|
|
3065
3087
|
return [CLI_DEFAULT_COMMANDS[id]];
|
|
3066
3088
|
}
|
|
3067
|
-
function commandSearchBases(command) {
|
|
3068
|
-
if (isAbsolute(command) || command.includes("/") || command.includes("\\")) return [resolve(command)];
|
|
3069
|
-
return (process.env.PATH ?? process.env.Path ?? "").split(delimiter).filter(Boolean).map((dir) => join(dir, command));
|
|
3070
|
-
}
|
|
3071
|
-
function canExecute(path, isWindows) {
|
|
3072
|
-
try {
|
|
3073
|
-
accessSync(path, isWindows ? constants.F_OK : constants.X_OK);
|
|
3074
|
-
return true;
|
|
3075
|
-
} catch {
|
|
3076
|
-
return false;
|
|
3077
|
-
}
|
|
3078
|
-
}
|
|
3079
|
-
function findExecutable(command) {
|
|
3080
|
-
const isWindows = process.platform === "win32";
|
|
3081
|
-
const bases = commandSearchBases(command);
|
|
3082
|
-
const extensions = executableExtensions(command, isWindows);
|
|
3083
|
-
for (const base of bases) for (const extension of extensions) {
|
|
3084
|
-
const candidate = extension ? `${base}${extension}` : base;
|
|
3085
|
-
if (canExecute(candidate, isWindows)) return candidate;
|
|
3086
|
-
}
|
|
3087
|
-
}
|
|
3088
3089
|
function hasOpenCodeModel(config) {
|
|
3089
3090
|
const model = config.criticModel;
|
|
3090
3091
|
const separator = model?.indexOf("/") ?? -1;
|
package/docs/CLI_PROVIDERS.md
CHANGED
|
@@ -8,7 +8,7 @@ The CLI is installed locally, but its model request still goes to the provider.
|
|
|
8
8
|
|
|
9
9
|
When `CRITIC_PROVIDER` is empty or unset, Vibe-Gate checks local CLI executables in this order: Codex (`codex`), Claude Code (`claude`), Cursor Agent (`agent`, then legacy `cursor-agent`), and OpenCode CLI (`opencode`). OpenCode CLI is considered only with a `provider/model` `CRITIC_MODEL`, and that model format moves it to the front of the default order. Configured `*_CLI_PATH` values are checked before default PATH names, using the same provider order. The first tool response reports the selected CLI in `providerNotice`. Detection checks whether the executable is available; it does not verify that the CLI is signed in. If the selected CLI needs login, Vibe-Gate returns its error and does not switch to another account or service. If no local CLI is found, Vibe-Gate retains its OpenAI default and requires `OPENAI_API_KEY`. Set `CRITIC_PROVIDER` to select a provider explicitly.
|
|
10
10
|
|
|
11
|
-
On Windows,
|
|
11
|
+
On Windows, command names are resolved through `PATH` and `PATHEXT` for `.COM`, `.EXE`, `.BAT`, and `.CMD` files whether `CRITIC_PROVIDER` is automatic or explicitly set. Batch shims (`.bat` and `.cmd`) run through `cmd.exe`; native executables run directly.
|
|
12
12
|
|
|
13
13
|
| `CRITIC_PROVIDER` | Command | Sign in | Model selection |
|
|
14
14
|
| ----------------- | ----------------------------------------- | ---------------------------------------------- | -------------------------------------------------- |
|