Repository navigation
Expand file tree
/
Copy pathai-cli-capabilities.js
More file actions
70 lines (65 loc) · 3.22 KB
/
Copy pathai-cli-capabilities.js
File metadata and controls
70 lines (65 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
* Copyright (c) 2021 - present core.ai
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/** Read-only compatibility checks before adding per-launch CLI configuration. */
const path = require("path");
const fs = require("fs");
const CliLocator = require("./cli-locator");
/**
* Resolve an npm Windows shim to the native binary shipped by that same installation.
* Never silently switches a user-selected CLI to a different installed version.
* @param {string} cli Provider id.
* @param {Object} located A CliLocator.locateCli result.
* @return {string} Executable suitable for argument-array spawning.
*/
function nativeExecutable(cli, located) {
// Set unless the path is a shim the locator could not follow, as it can for Claude Code.
if (located.execPath) { return located.execPath; }
const base = path.dirname(located.path);
const candidates = cli !== "codex" ? [] : [
path.join(base, "node_modules", "@openai", "codex", "vendor", "x86_64-pc-windows-msvc", "codex", "codex.exe"),
path.join(base, "node_modules", "@openai", "codex-win32-x64", "vendor",
"x86_64-pc-windows-msvc", "codex", "codex.exe")
];
for (const candidate of candidates) { if (fs.existsSync(candidate)) { return candidate; } }
throw new Error("Phoenix connection requires a native " + cli + " executable for this Windows installation.");
}
/**
* Avoid overriding an existing server with the reserved name; do not edit CLI settings.
* @param {string} cli CLI id.
* @param {string} projectRoot Native working directory.
* @return {Promise<string>} Resolved executable.
*/
async function checkLaunch(cli, projectRoot) {
const located = await CliLocator.locateCli(cli);
if (!located.path) { throw new Error("CLI is no longer available."); }
const executable = nativeExecutable(cli, located);
const help = await CliLocator.spawnCli(executable, ["--help"],
{cwd: projectRoot, timeout: 5000, windowsHide: true});
const required = cli === "codex" ? ["--no-daemon"] :
["--mcp-config", "--settings", "--session-id"];
if (help.status !== 0 || required.some(flag => !help.stdout.includes(flag))) {
throw new Error("Update " + cli + " to use the Phoenix connection.");
}
if (cli === "codex") {
const listed = await CliLocator.spawnCli(executable, ["mcp", "list", "--json"],
{cwd: projectRoot, timeout: 5000, windowsHide: true});
if (listed.status !== 0) { throw new Error("Could not read Codex MCP configuration."); }
checkCodexServers(listed.stdout);
}
return executable;
}
/** Validate Codex's server list without exposing its configuration in diagnostics. */
function checkCodexServers(stdout) {
let entries;
try { entries = JSON.parse(stdout); }
catch (error) { throw new Error("Codex MCP configuration could not be read."); }
if (!Array.isArray(entries)) { throw new Error("Unsupported Codex MCP configuration format."); }
if (entries.some(entry => entry.name === "phoenix-editor")) {
throw new Error("An MCP server named phoenix-editor is already configured in Codex. Rename it to connect.");
}
}
exports.checkLaunch = checkLaunch;
exports.nativeExecutable = nativeExecutable;
exports.checkCodexServers = checkCodexServers;