@mkterswingman/5mghost-yonder 0.0.40 → 0.0.41
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/setup.js +5 -5
- package/dist/telemetry.js +1 -1
- package/dist/utils/launcher.d.ts +11 -4
- package/dist/utils/launcher.js +109 -11
- package/package.json +1 -1
package/dist/cli/setup.js
CHANGED
|
@@ -443,8 +443,8 @@ export async function runSetup() {
|
|
|
443
443
|
{
|
|
444
444
|
"mcpServers": {
|
|
445
445
|
"yt-mcp": {
|
|
446
|
-
"command":
|
|
447
|
-
"args":
|
|
446
|
+
"command": ${JSON.stringify(launcherCommand.command)},
|
|
447
|
+
"args": ${JSON.stringify(launcherCommand.args)}
|
|
448
448
|
}
|
|
449
449
|
}
|
|
450
450
|
}
|
|
@@ -456,14 +456,14 @@ export async function runSetup() {
|
|
|
456
456
|
"servers": {
|
|
457
457
|
"yt-mcp": {
|
|
458
458
|
"transport": "stdio",
|
|
459
|
-
"command":
|
|
460
|
-
"args":
|
|
459
|
+
"command": ${JSON.stringify(launcherCommand.command)},
|
|
460
|
+
"args": ${JSON.stringify(launcherCommand.args)}
|
|
461
461
|
}
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
464
|
`);
|
|
465
465
|
console.log(" OpenClaw stdio CLI (recommended):");
|
|
466
|
-
console.log(` mcporter config add yt-mcp --command
|
|
466
|
+
console.log(` mcporter config add yt-mcp --command ${JSON.stringify(launcherCommand.command)} ${launcherCommand.args.map((arg) => `--arg ${JSON.stringify(arg)}`).join(" ")}`);
|
|
467
467
|
console.log(` OpenClaw uses ${PATHS.sharedAuthJson} for PAT/JWT, so env.YT_MCP_TOKEN is optional after setup.`);
|
|
468
468
|
console.log(` WorkBuddy MCP config: ${getWorkBuddyConfigPath()}`);
|
|
469
469
|
console.log(` CodeBuddy MCP config: ${getCodeBuddyConfigPath()}`);
|
package/dist/telemetry.js
CHANGED
|
@@ -3,7 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { PATHS } from "./utils/config.js";
|
|
5
5
|
const PRODUCT = "5mghost-yonder";
|
|
6
|
-
const PRODUCT_VERSION = "0.0.
|
|
6
|
+
const PRODUCT_VERSION = "0.0.41";
|
|
7
7
|
const MAX_ERROR_CODE_CHARS = 64;
|
|
8
8
|
export class ToolTelemetryClient {
|
|
9
9
|
config;
|
package/dist/utils/launcher.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export interface LauncherSourceOptions {
|
|
2
|
+
packageSpec: string;
|
|
3
|
+
npmCacheDir: string;
|
|
4
|
+
npxCommand?: string | null;
|
|
5
|
+
}
|
|
6
|
+
export interface LauncherCommand {
|
|
7
|
+
command: string;
|
|
8
|
+
args: string[];
|
|
9
|
+
}
|
|
5
10
|
export declare function buildLauncherCommand(launcherPath?: string): LauncherCommand;
|
|
11
|
+
export declare function isRepairableNpxFailure(stderr: string): boolean;
|
|
12
|
+
export declare function resolveNpxCommand(): string | null;
|
|
6
13
|
export declare function buildLauncherSource(options?: Partial<LauncherSourceOptions>): string;
|
|
7
14
|
export declare function writeLauncherFile(options?: Partial<LauncherSourceOptions>): string;
|
package/dist/utils/launcher.js
CHANGED
|
@@ -1,19 +1,117 @@
|
|
|
1
1
|
import { PATHS } from "./config.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { dirname } from "node:path";
|
|
4
5
|
const DEFAULT_PACKAGE_SPEC = "@mkterswingman/5mghost-yonder@latest";
|
|
5
6
|
export function buildLauncherCommand(launcherPath = PATHS.launcherJs) {
|
|
6
|
-
return
|
|
7
|
+
return {
|
|
8
|
+
command: process.execPath,
|
|
9
|
+
args: [launcherPath, "serve"],
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function isRepairableNpxFailure(stderr) {
|
|
13
|
+
const lower = stderr.toLowerCase();
|
|
14
|
+
const referencesNpxDir = lower.includes("_npx/") || lower.includes("_npx\\");
|
|
15
|
+
return referencesNpxDir && (lower.includes("enotempty") || lower.includes("rename"));
|
|
16
|
+
}
|
|
17
|
+
export function resolveNpxCommand() {
|
|
18
|
+
try {
|
|
19
|
+
const lookup = process.platform === "win32" ? "where" : "which";
|
|
20
|
+
const target = process.platform === "win32" ? "npx.cmd" : "npx";
|
|
21
|
+
const output = execFileSync(lookup, [target], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
22
|
+
return output.split(/\r?\n/).map((line) => line.trim()).find(Boolean) ?? null;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
7
27
|
}
|
|
8
28
|
export function buildLauncherSource(options = {}) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
29
|
+
const packageSpec = options.packageSpec ?? DEFAULT_PACKAGE_SPEC;
|
|
30
|
+
const npmCacheDir = options.npmCacheDir ?? PATHS.npmCacheDir;
|
|
31
|
+
const npxCommand = "npxCommand" in options ? options.npxCommand : resolveNpxCommand();
|
|
32
|
+
return `#!/usr/bin/env node
|
|
33
|
+
import { existsSync, mkdirSync, renameSync } from "node:fs";
|
|
34
|
+
import { join } from "node:path";
|
|
35
|
+
import { spawnSync } from "node:child_process";
|
|
36
|
+
|
|
37
|
+
const packageSpec = ${JSON.stringify(packageSpec)};
|
|
38
|
+
const npmCacheDir = ${JSON.stringify(npmCacheDir)};
|
|
39
|
+
const configuredNpxCommand = ${JSON.stringify(npxCommand)};
|
|
40
|
+
const args = process.argv.slice(2);
|
|
41
|
+
const targetArgs = args.length > 0 ? args : ["serve"];
|
|
42
|
+
|
|
43
|
+
function isSkillInstallerMode(subArgs) {
|
|
44
|
+
return subArgs[0] === "install-skills";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isRepairableNpxFailure(stderr) {
|
|
48
|
+
const lower = stderr.toLowerCase();
|
|
49
|
+
return (lower.includes("_npx/") || lower.includes("_npx\\\\"))
|
|
50
|
+
&& (lower.includes("enotempty") || lower.includes("rename"));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getNpxCommand() {
|
|
54
|
+
return configuredNpxCommand || (process.platform === "win32" ? "npx.cmd" : "npx");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function writeSpawnError(result, npxBin) {
|
|
58
|
+
if (!result.error) return;
|
|
59
|
+
const message = result.error instanceof Error ? result.error.message : String(result.error);
|
|
60
|
+
process.stderr.write(\`[launcher] failed to start npx command "\${npxBin}": \${message}\\n\`);
|
|
61
|
+
process.stderr.write("[launcher] rerun setup from a terminal where Node.js/npm are available: yt-mcp setup\\n");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function runNpx(subArgs, captureStdErrOnly = false) {
|
|
65
|
+
mkdirSync(npmCacheDir, { recursive: true });
|
|
66
|
+
const npxBin = getNpxCommand();
|
|
67
|
+
const result = spawnSync(npxBin, ["--yes", packageSpec, ...subArgs], {
|
|
68
|
+
env: { ...process.env, npm_config_cache: npmCacheDir },
|
|
69
|
+
// Why: probe runs before MCP starts; stdout must stay silent or it will corrupt stdio transport.
|
|
70
|
+
// The skill installer is an explicit one-shot CLI path, so it can inherit stdio safely.
|
|
71
|
+
stdio: captureStdErrOnly ? ["ignore", "ignore", "pipe"] : "inherit",
|
|
72
|
+
});
|
|
73
|
+
writeSpawnError(result, npxBin);
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function rotateNpxDir() {
|
|
78
|
+
const npxDir = join(npmCacheDir, "_npx");
|
|
79
|
+
if (!existsSync(npxDir)) return false;
|
|
80
|
+
const backup = \`\${npxDir}.bad.\${new Date().toISOString().replace(/[^0-9]/g, "").slice(0, 14)}\`;
|
|
81
|
+
renameSync(npxDir, backup);
|
|
82
|
+
process.stderr.write(\`[launcher] repaired corrupted npx cache: \${backup}\\n\`);
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function ensurePackageReady() {
|
|
87
|
+
const first = runNpx(["version"], true);
|
|
88
|
+
if ((first.status ?? 1) === 0) return;
|
|
89
|
+
|
|
90
|
+
const stderr = first.stderr ? String(first.stderr) : "";
|
|
91
|
+
if (!isRepairableNpxFailure(stderr) || !rotateNpxDir()) {
|
|
92
|
+
if (stderr) process.stderr.write(stderr);
|
|
93
|
+
process.exit(first.status ?? 1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const second = runNpx(["version"], true);
|
|
97
|
+
const secondStderr = second.stderr ? String(second.stderr) : "";
|
|
98
|
+
if ((second.status ?? 1) !== 0) {
|
|
99
|
+
if (secondStderr) process.stderr.write(secondStderr);
|
|
100
|
+
process.exit(second.status ?? 1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
ensurePackageReady();
|
|
105
|
+
if (isSkillInstallerMode(targetArgs)) {
|
|
106
|
+
process.env.SHARED_CLIENT_INSTALL_SKILLS = "1";
|
|
107
|
+
}
|
|
108
|
+
const finalRun = runNpx(targetArgs, false);
|
|
109
|
+
process.exit(finalRun.status ?? (finalRun.error ? 1 : 0));
|
|
110
|
+
`;
|
|
13
111
|
}
|
|
14
112
|
export function writeLauncherFile(options = {}) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
113
|
+
mkdirSync(dirname(PATHS.launcherJs), { recursive: true });
|
|
114
|
+
const source = buildLauncherSource(options);
|
|
115
|
+
writeFileSync(PATHS.launcherJs, source, { encoding: "utf8", mode: 0o755 });
|
|
116
|
+
return PATHS.launcherJs;
|
|
19
117
|
}
|