@phidiassj/aiyoperps-mcp-installer 0.5.5 → 0.5.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/bin/aiyoperps-mcp-installer.js +131 -42
- package/package.json +1 -1
|
@@ -9,6 +9,17 @@ import { parse as parseToml } from 'smol-toml';
|
|
|
9
9
|
|
|
10
10
|
const SERVER_NAME = 'aiyoperps';
|
|
11
11
|
const DEFAULT_URL = 'http://127.0.0.1:5078/mcp';
|
|
12
|
+
const BRIDGE_PACKAGE_NAME = '@phidiassj/aiyoperps-mcp-bridge';
|
|
13
|
+
const BRIDGE_SCRIPT_RELATIVE_PATH = path.join(
|
|
14
|
+
'node_modules',
|
|
15
|
+
'@phidiassj',
|
|
16
|
+
'aiyoperps-mcp-bridge',
|
|
17
|
+
'bin',
|
|
18
|
+
'aiyoperps-mcp-bridge.js');
|
|
19
|
+
const EXECUTABLE_CACHE = new Map();
|
|
20
|
+
let bridgeRuntimePrepared = false;
|
|
21
|
+
let bridgeRuntimeAttempted = false;
|
|
22
|
+
let bridgeRuntimeWarning = '';
|
|
12
23
|
|
|
13
24
|
const cli = parseCliArgs(argv.slice(2));
|
|
14
25
|
const targetUrl = cli.url;
|
|
@@ -541,20 +552,18 @@ function buildJsonServerConfig(url) {
|
|
|
541
552
|
}
|
|
542
553
|
|
|
543
554
|
async function prewarmBridgePackage(url) {
|
|
544
|
-
stdout.write('\
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
});
|
|
548
|
-
const result = runCommand(commandLine.command, commandLine.args);
|
|
549
|
-
if (!result.ok) {
|
|
550
|
-
stdout.write(` warning: prewarm failed: ${result.stderr || result.error?.message || 'unknown error'}\n`);
|
|
555
|
+
stdout.write('\nPreparing bridge runtime...\n');
|
|
556
|
+
await ensureBridgeRuntimePrepared();
|
|
557
|
+
if (bridgeRuntimePrepared) {
|
|
558
|
+
stdout.write(` ready: ${resolveInstalledBridgeScriptPath()}\n`);
|
|
551
559
|
return;
|
|
552
560
|
}
|
|
553
561
|
|
|
554
|
-
stdout.write(
|
|
562
|
+
stdout.write(` warning: ${bridgeRuntimeWarning || 'falling back to npx'}\n`);
|
|
555
563
|
}
|
|
556
564
|
|
|
557
565
|
async function resolveInstallUrl(defaultUrl, urlExplicit) {
|
|
566
|
+
await ensureBridgeRuntimePrepared();
|
|
558
567
|
const candidates = urlExplicit
|
|
559
568
|
? [defaultUrl]
|
|
560
569
|
: buildCandidateUrls(defaultUrl);
|
|
@@ -605,35 +614,11 @@ function detectWslGatewayUrl() {
|
|
|
605
614
|
}
|
|
606
615
|
|
|
607
616
|
async function canReachMcpEndpoint(url) {
|
|
608
|
-
const
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
method: 'POST',
|
|
614
|
-
headers: {
|
|
615
|
-
'Content-Type': 'application/json'
|
|
616
|
-
},
|
|
617
|
-
body: JSON.stringify({
|
|
618
|
-
jsonrpc: '2.0',
|
|
619
|
-
id: 'installer-probe',
|
|
620
|
-
method: 'ping',
|
|
621
|
-
params: {}
|
|
622
|
-
}),
|
|
623
|
-
signal: controller.signal
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
if (!response.ok) {
|
|
627
|
-
return false;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
const payload = await response.json();
|
|
631
|
-
return !payload?.error;
|
|
632
|
-
} catch {
|
|
633
|
-
return false;
|
|
634
|
-
} finally {
|
|
635
|
-
clearTimeout(timeout);
|
|
636
|
-
}
|
|
617
|
+
const commandLine = resolveCommandLineSpec(process.platform, url, {
|
|
618
|
+
healthCheck: true
|
|
619
|
+
});
|
|
620
|
+
const result = runCommand(commandLine.command, commandLine.args);
|
|
621
|
+
return result.ok;
|
|
637
622
|
}
|
|
638
623
|
|
|
639
624
|
function hasCodexBlock(content) {
|
|
@@ -784,26 +769,101 @@ function splitCsvArg(value) {
|
|
|
784
769
|
}
|
|
785
770
|
|
|
786
771
|
function resolveCommandLineSpec(platform, url, options = {}) {
|
|
787
|
-
const
|
|
772
|
+
const bridgeArgs = [];
|
|
788
773
|
if (options.prewarm) {
|
|
789
|
-
|
|
774
|
+
bridgeArgs.push('--help');
|
|
775
|
+
} else if (options.healthCheck) {
|
|
776
|
+
bridgeArgs.push('--health-check', '--quiet', '--url', url);
|
|
790
777
|
} else {
|
|
791
|
-
|
|
778
|
+
bridgeArgs.push('--quiet', '--url', url);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
const installedScriptPath = resolveInstalledBridgeScriptPath();
|
|
782
|
+
if (installedScriptPath) {
|
|
783
|
+
return {
|
|
784
|
+
command: process.execPath,
|
|
785
|
+
args: [installedScriptPath, ...bridgeArgs]
|
|
786
|
+
};
|
|
792
787
|
}
|
|
793
788
|
|
|
789
|
+
const packageArgs = ['-y', BRIDGE_PACKAGE_NAME, ...bridgeArgs];
|
|
790
|
+
const resolvedNpx = resolveExecutablePath(platform === 'win32' ? 'npx.cmd' : 'npx');
|
|
794
791
|
if (platform === 'win32') {
|
|
795
792
|
return {
|
|
796
|
-
command: 'npx.cmd',
|
|
793
|
+
command: resolvedNpx || 'npx.cmd',
|
|
797
794
|
args: packageArgs
|
|
798
795
|
};
|
|
799
796
|
}
|
|
800
797
|
|
|
801
798
|
return {
|
|
802
|
-
command: 'npx',
|
|
799
|
+
command: resolvedNpx || 'npx',
|
|
803
800
|
args: packageArgs
|
|
804
801
|
};
|
|
805
802
|
}
|
|
806
803
|
|
|
804
|
+
async function ensureBridgeRuntimePrepared() {
|
|
805
|
+
if (bridgeRuntimeAttempted) {
|
|
806
|
+
return bridgeRuntimePrepared;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
bridgeRuntimeAttempted = true;
|
|
810
|
+
|
|
811
|
+
if (resolveInstalledBridgeScriptPath()) {
|
|
812
|
+
bridgeRuntimePrepared = true;
|
|
813
|
+
return true;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
const npmCommand = resolveExecutablePath(process.platform === 'win32' ? 'npm.cmd' : 'npm');
|
|
817
|
+
if (!npmCommand) {
|
|
818
|
+
bridgeRuntimeWarning = 'npm was not found in PATH, falling back to npx.';
|
|
819
|
+
return false;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
const installRoot = resolveBridgeInstallRoot();
|
|
823
|
+
ensureParentDir(path.join(installRoot, 'placeholder'));
|
|
824
|
+
|
|
825
|
+
const result = runCommand(npmCommand, [
|
|
826
|
+
'install',
|
|
827
|
+
'--silent',
|
|
828
|
+
'--no-audit',
|
|
829
|
+
'--no-fund',
|
|
830
|
+
'--prefix',
|
|
831
|
+
installRoot,
|
|
832
|
+
BRIDGE_PACKAGE_NAME
|
|
833
|
+
]);
|
|
834
|
+
|
|
835
|
+
if (!result.ok) {
|
|
836
|
+
bridgeRuntimeWarning = result.stderr || result.error?.message || 'npm install failed, falling back to npx.';
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if (!resolveInstalledBridgeScriptPath()) {
|
|
841
|
+
bridgeRuntimeWarning = 'bridge package installed, but launcher script was not found; falling back to npx.';
|
|
842
|
+
return false;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
bridgeRuntimePrepared = true;
|
|
846
|
+
return true;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
function resolveBridgeInstallRoot() {
|
|
850
|
+
if (env.AIYOPERPS_MCP_BRIDGE_DIR) {
|
|
851
|
+
return env.AIYOPERPS_MCP_BRIDGE_DIR;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
if (process.platform === 'win32') {
|
|
855
|
+
const appData = env.LOCALAPPDATA || path.join(env.USERPROFILE || os.homedir(), 'AppData', 'Local');
|
|
856
|
+
return path.join(appData, 'AiyoPerps', 'mcp-bridge');
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
return path.join(os.homedir(), '.aiyoperps', 'mcp-bridge');
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
function resolveInstalledBridgeScriptPath() {
|
|
863
|
+
const scriptPath = path.join(resolveBridgeInstallRoot(), BRIDGE_SCRIPT_RELATIVE_PATH);
|
|
864
|
+
return fileExists(scriptPath) ? scriptPath : null;
|
|
865
|
+
}
|
|
866
|
+
|
|
807
867
|
function resolveCodexConfigPath() {
|
|
808
868
|
if (env.CODEX_CONFIG_PATH) {
|
|
809
869
|
return env.CODEX_CONFIG_PATH;
|
|
@@ -868,6 +928,35 @@ function runCommand(command, args) {
|
|
|
868
928
|
};
|
|
869
929
|
}
|
|
870
930
|
|
|
931
|
+
function resolveExecutablePath(name) {
|
|
932
|
+
if (EXECUTABLE_CACHE.has(name)) {
|
|
933
|
+
return EXECUTABLE_CACHE.get(name);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
const pathValue = env.PATH || '';
|
|
937
|
+
const separator = process.platform === 'win32' ? ';' : ':';
|
|
938
|
+
const extensions = process.platform === 'win32'
|
|
939
|
+
? ['', '.cmd', '.exe', '.bat']
|
|
940
|
+
: [''];
|
|
941
|
+
|
|
942
|
+
for (const directory of pathValue.split(separator)) {
|
|
943
|
+
if (!directory) {
|
|
944
|
+
continue;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
for (const extension of extensions) {
|
|
948
|
+
const candidate = path.join(directory, name.endsWith(extension) ? name : `${name}${extension}`);
|
|
949
|
+
if (fileExists(candidate)) {
|
|
950
|
+
EXECUTABLE_CACHE.set(name, candidate);
|
|
951
|
+
return candidate;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
EXECUTABLE_CACHE.set(name, null);
|
|
957
|
+
return null;
|
|
958
|
+
}
|
|
959
|
+
|
|
871
960
|
function ensureParentDir(filePath) {
|
|
872
961
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
873
962
|
}
|