@runeya/runeya 2.0.65 → 2.0.66
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/agent/index.js +135 -26
- package/agent/index.js.map +1 -1
- package/index.js +1 -1
- package/mcp-server/launch.d.ts +45 -0
- package/mcp-server/launch.js +65 -0
- package/mcp-server/launch.js.map +1 -0
- package/package.json +1 -1
- package/{src-YPQEXOFN.js → src-ETRPQHFP.js} +96 -20
- package/src-ETRPQHFP.js.map +1 -0
- package/src-YPQEXOFN.js.map +0 -1
package/agent/index.js
CHANGED
|
@@ -5172,11 +5172,14 @@ import { TRPCError as TRPCError5 } from "@trpc/server";
|
|
|
5172
5172
|
import { spawn as spawn4, execFileSync } from "child_process";
|
|
5173
5173
|
import { EventEmitter as EventEmitter9 } from "events";
|
|
5174
5174
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
5175
|
-
import {
|
|
5176
|
-
import { createRequire } from "module";
|
|
5177
|
-
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
5175
|
+
import { existsSync as existsSync3, readFileSync } from "fs";
|
|
5178
5176
|
import { dirname, resolve as resolvePath2 } from "path";
|
|
5179
5177
|
import * as pty2 from "@lydell/node-pty";
|
|
5178
|
+
|
|
5179
|
+
// ../../packages/mcp-server/src/launch.ts
|
|
5180
|
+
import { fileURLToPath } from "url";
|
|
5181
|
+
import { createRequire } from "module";
|
|
5182
|
+
import { existsSync as existsSync2 } from "fs";
|
|
5180
5183
|
function resolveMcpServerPath() {
|
|
5181
5184
|
try {
|
|
5182
5185
|
const req = createRequire(import.meta.url);
|
|
@@ -5184,9 +5187,13 @@ function resolveMcpServerPath() {
|
|
|
5184
5187
|
} catch {
|
|
5185
5188
|
}
|
|
5186
5189
|
const candidates = [
|
|
5190
|
+
// Build packagé du CLI : dist/agent/index.js et dist/index.js côtoient
|
|
5191
|
+
// dist/mcp-server/, copié là par le post-build.
|
|
5192
|
+
new URL("../mcp-server/index.js", import.meta.url),
|
|
5193
|
+
new URL("./mcp-server/index.js", import.meta.url),
|
|
5194
|
+
// Monorepo, depuis un dist d'app.
|
|
5187
5195
|
new URL("../../../packages/mcp-server/dist/index.js", import.meta.url),
|
|
5188
|
-
new URL("../../../../packages/mcp-server/dist/index.js", import.meta.url)
|
|
5189
|
-
new URL("../mcp-server/index.js", import.meta.url)
|
|
5196
|
+
new URL("../../../../packages/mcp-server/dist/index.js", import.meta.url)
|
|
5190
5197
|
];
|
|
5191
5198
|
for (const c of candidates) {
|
|
5192
5199
|
const p = fileURLToPath(c);
|
|
@@ -5194,6 +5201,42 @@ function resolveMcpServerPath() {
|
|
|
5194
5201
|
}
|
|
5195
5202
|
throw new Error("Could not locate @runeya/packages-mcp-server (built dist not found)");
|
|
5196
5203
|
}
|
|
5204
|
+
function pickEnv(env2) {
|
|
5205
|
+
return {
|
|
5206
|
+
...env2.RUNEYA_BASE_URL ? { RUNEYA_BASE_URL: env2.RUNEYA_BASE_URL } : {},
|
|
5207
|
+
...env2.RUNEYA_API_TOKEN ? { RUNEYA_API_TOKEN: env2.RUNEYA_API_TOKEN } : {}
|
|
5208
|
+
};
|
|
5209
|
+
}
|
|
5210
|
+
function claudeMcpArgs(env2) {
|
|
5211
|
+
const config = JSON.stringify({
|
|
5212
|
+
mcpServers: {
|
|
5213
|
+
runeya: {
|
|
5214
|
+
command: "node",
|
|
5215
|
+
args: [resolveMcpServerPath()],
|
|
5216
|
+
env: pickEnv(env2)
|
|
5217
|
+
}
|
|
5218
|
+
}
|
|
5219
|
+
});
|
|
5220
|
+
return ["--mcp-config", config];
|
|
5221
|
+
}
|
|
5222
|
+
function codexMcpArgs(env2) {
|
|
5223
|
+
const fields = [
|
|
5224
|
+
`command=${tomlString("node")}`,
|
|
5225
|
+
`args=[${tomlString(resolveMcpServerPath())}]`
|
|
5226
|
+
];
|
|
5227
|
+
const entries = Object.entries(pickEnv(env2));
|
|
5228
|
+
if (entries.length > 0) {
|
|
5229
|
+
const inline = entries.map(([k, v]) => `${k}=${tomlString(v)}`).join(",");
|
|
5230
|
+
fields.push(`env={${inline}}`);
|
|
5231
|
+
}
|
|
5232
|
+
return ["-c", `mcp_servers.runeya={${fields.join(",")}}`];
|
|
5233
|
+
}
|
|
5234
|
+
function tomlString(value) {
|
|
5235
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/[\u0000-\u001f\u007f]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
5236
|
+
return `"${escaped}"`;
|
|
5237
|
+
}
|
|
5238
|
+
|
|
5239
|
+
// src/services/ai-spawn-manager.ts
|
|
5197
5240
|
function resolveCliInvocation(cli, args) {
|
|
5198
5241
|
if (process.platform !== "win32") return { command: cli, args };
|
|
5199
5242
|
if (/\.exe$/i.test(cli)) return { command: cli, args };
|
|
@@ -5209,13 +5252,13 @@ function resolveCliInvocation(cli, args) {
|
|
|
5209
5252
|
shim = found.find((f) => /\.cmd$/i.test(f)) ?? found[0] ?? cli;
|
|
5210
5253
|
}
|
|
5211
5254
|
if (/\.exe$/i.test(shim)) return { command: shim, args };
|
|
5212
|
-
if (/\.cmd$/i.test(shim) &&
|
|
5255
|
+
if (/\.cmd$/i.test(shim) && existsSync3(shim)) {
|
|
5213
5256
|
try {
|
|
5214
5257
|
const content = readFileSync(shim, "utf-8");
|
|
5215
5258
|
const m = content.match(/%~?dp0%\\?([^"\s]+\.js)/i);
|
|
5216
5259
|
if (m?.[1]) {
|
|
5217
5260
|
const entry = resolvePath2(dirname(shim), m[1].replace(/^\\+/, ""));
|
|
5218
|
-
if (
|
|
5261
|
+
if (existsSync3(entry)) return { command: process.execPath, args: [entry, ...args] };
|
|
5219
5262
|
}
|
|
5220
5263
|
} catch {
|
|
5221
5264
|
}
|
|
@@ -5238,20 +5281,10 @@ function resolveSpawnEnvAndArgs(opts) {
|
|
|
5238
5281
|
const args = [...opts.args];
|
|
5239
5282
|
if (opts.enableMcp && opts.cli === "claude") {
|
|
5240
5283
|
try {
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
command: "node",
|
|
5246
|
-
args: [mcpServerPath],
|
|
5247
|
-
env: {
|
|
5248
|
-
...env2.RUNEYA_BASE_URL ? { RUNEYA_BASE_URL: env2.RUNEYA_BASE_URL } : {},
|
|
5249
|
-
...env2.RUNEYA_API_TOKEN ? { RUNEYA_API_TOKEN: env2.RUNEYA_API_TOKEN } : {}
|
|
5250
|
-
}
|
|
5251
|
-
}
|
|
5252
|
-
}
|
|
5253
|
-
});
|
|
5254
|
-
args.push("--mcp-config", mcpConfig);
|
|
5284
|
+
args.push(...claudeMcpArgs({
|
|
5285
|
+
RUNEYA_BASE_URL: env2.RUNEYA_BASE_URL,
|
|
5286
|
+
RUNEYA_API_TOKEN: env2.RUNEYA_API_TOKEN
|
|
5287
|
+
}));
|
|
5255
5288
|
} catch (err) {
|
|
5256
5289
|
console.warn("[ai-spawn-manager] Failed to resolve MCP server path:", err.message);
|
|
5257
5290
|
}
|
|
@@ -5556,6 +5589,18 @@ import { spawn as spawn6 } from "child_process";
|
|
|
5556
5589
|
import { createInterface as createInterface2 } from "readline";
|
|
5557
5590
|
import { EventEmitter as EventEmitter10 } from "events";
|
|
5558
5591
|
var REQUEST_TIMEOUT_MS = 3e5;
|
|
5592
|
+
function resolveMcpArgs(env2) {
|
|
5593
|
+
if (!env2["RUNEYA_API_TOKEN"]) return [];
|
|
5594
|
+
try {
|
|
5595
|
+
return codexMcpArgs({
|
|
5596
|
+
RUNEYA_BASE_URL: env2["RUNEYA_BASE_URL"],
|
|
5597
|
+
RUNEYA_API_TOKEN: env2["RUNEYA_API_TOKEN"]
|
|
5598
|
+
});
|
|
5599
|
+
} catch (err) {
|
|
5600
|
+
console.warn("[codex-app-server-mgr] Failed to resolve MCP server path:", err.message);
|
|
5601
|
+
return [];
|
|
5602
|
+
}
|
|
5603
|
+
}
|
|
5559
5604
|
var CodexAppServerManager = class extends EventEmitter10 {
|
|
5560
5605
|
proc = null;
|
|
5561
5606
|
rl = null;
|
|
@@ -5580,9 +5625,10 @@ var CodexAppServerManager = class extends EventEmitter10 {
|
|
|
5580
5625
|
}
|
|
5581
5626
|
}
|
|
5582
5627
|
async doConnect() {
|
|
5583
|
-
|
|
5628
|
+
const env2 = { ...process.env, ...this.extraEnv };
|
|
5629
|
+
this.proc = spawn6("codex", [...resolveMcpArgs(env2), "app-server"], {
|
|
5584
5630
|
stdio: ["pipe", "pipe", "pipe"],
|
|
5585
|
-
env:
|
|
5631
|
+
env: env2
|
|
5586
5632
|
});
|
|
5587
5633
|
this.rl = createInterface2({ input: this.proc.stdout });
|
|
5588
5634
|
this.rl.on("line", (line) => this.handleLine(line));
|
|
@@ -6304,11 +6350,73 @@ function createAgent(opts) {
|
|
|
6304
6350
|
// src/config/node-path.ts
|
|
6305
6351
|
import { dirname as dirname3, delimiter } from "path";
|
|
6306
6352
|
function ensureNodeBinOnPath(environment = process.env) {
|
|
6307
|
-
|
|
6353
|
+
appendToPath(dirname3(process.execPath), environment);
|
|
6354
|
+
}
|
|
6355
|
+
function appendToPath(dir, environment = process.env) {
|
|
6356
|
+
if (!dir) return;
|
|
6308
6357
|
const current = environment["PATH"] ?? "";
|
|
6309
6358
|
const entries = current.split(delimiter).filter(Boolean);
|
|
6310
|
-
if (entries.includes(
|
|
6311
|
-
environment["PATH"] = entries.length > 0 ? `${current}${delimiter}${
|
|
6359
|
+
if (entries.includes(dir)) return;
|
|
6360
|
+
environment["PATH"] = entries.length > 0 ? `${current}${delimiter}${dir}` : dir;
|
|
6361
|
+
}
|
|
6362
|
+
|
|
6363
|
+
// src/config/user-path.ts
|
|
6364
|
+
import { execFile as execFile5 } from "child_process";
|
|
6365
|
+
import { promisify as promisify3 } from "util";
|
|
6366
|
+
import { homedir as homedir5 } from "os";
|
|
6367
|
+
import { existsSync as existsSync4, statSync } from "fs";
|
|
6368
|
+
import { join as join6, delimiter as delimiter2 } from "path";
|
|
6369
|
+
var execFileAsync3 = promisify3(execFile5);
|
|
6370
|
+
var MARKER = "__RUNEYA_PATH__";
|
|
6371
|
+
var SHELL_TIMEOUT_MS = 3e3;
|
|
6372
|
+
function commonUserBins(home) {
|
|
6373
|
+
return [
|
|
6374
|
+
join6(home, ".local", "bin"),
|
|
6375
|
+
join6(home, "bin"),
|
|
6376
|
+
join6(home, ".npm-global", "bin"),
|
|
6377
|
+
join6(home, ".bun", "bin"),
|
|
6378
|
+
join6(home, ".cargo", "bin"),
|
|
6379
|
+
"/opt/homebrew/bin",
|
|
6380
|
+
"/usr/local/bin"
|
|
6381
|
+
];
|
|
6382
|
+
}
|
|
6383
|
+
async function readLoginShellPath() {
|
|
6384
|
+
if (process.platform === "win32") return null;
|
|
6385
|
+
const shell = process.env["SHELL"];
|
|
6386
|
+
if (!shell || !existsSync4(shell)) return null;
|
|
6387
|
+
try {
|
|
6388
|
+
const { stdout } = await execFileAsync3(shell, ["-l", "-i", "-c", `echo "${MARKER}$PATH"`], {
|
|
6389
|
+
timeout: SHELL_TIMEOUT_MS,
|
|
6390
|
+
shell: false,
|
|
6391
|
+
encoding: "utf8",
|
|
6392
|
+
maxBuffer: 1024 * 1024,
|
|
6393
|
+
env: { ...process.env, TERM: "dumb" }
|
|
6394
|
+
});
|
|
6395
|
+
const line = stdout.split("\n").find((l) => l.includes(MARKER));
|
|
6396
|
+
if (!line) return null;
|
|
6397
|
+
const value = line.slice(line.indexOf(MARKER) + MARKER.length).trim();
|
|
6398
|
+
return value.length > 0 ? value : null;
|
|
6399
|
+
} catch {
|
|
6400
|
+
return null;
|
|
6401
|
+
}
|
|
6402
|
+
}
|
|
6403
|
+
async function ensureUserBinsOnPath(environment = process.env, home = homedir5()) {
|
|
6404
|
+
const shellPath = await readLoginShellPath();
|
|
6405
|
+
if (shellPath) {
|
|
6406
|
+
for (const entry of shellPath.split(delimiter2).filter(Boolean)) {
|
|
6407
|
+
appendToPath(entry, environment);
|
|
6408
|
+
}
|
|
6409
|
+
}
|
|
6410
|
+
for (const dir of commonUserBins(home)) {
|
|
6411
|
+
if (isDirectory(dir)) appendToPath(dir, environment);
|
|
6412
|
+
}
|
|
6413
|
+
}
|
|
6414
|
+
function isDirectory(path3) {
|
|
6415
|
+
try {
|
|
6416
|
+
return statSync(path3).isDirectory();
|
|
6417
|
+
} catch {
|
|
6418
|
+
return false;
|
|
6419
|
+
}
|
|
6312
6420
|
}
|
|
6313
6421
|
|
|
6314
6422
|
// src/index.ts
|
|
@@ -6345,6 +6453,7 @@ process.on("uncaughtException", (err) => {
|
|
|
6345
6453
|
});
|
|
6346
6454
|
async function main() {
|
|
6347
6455
|
ensureNodeBinOnPath();
|
|
6456
|
+
await ensureUserBinsOnPath();
|
|
6348
6457
|
const { server, shutdown, passphraseHex } = createAgent({
|
|
6349
6458
|
passphraseHex: env.PASSPHRASE_OVERRIDE
|
|
6350
6459
|
});
|