flockbay 0.10.20 → 0.10.21
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/{index-D_mglYG0.cjs → index-Bhkn02hu.cjs} +125 -22
- package/dist/{index-CX0Z8pmz.mjs → index-By332wvJ.mjs} +124 -21
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{runCodex-CXJW0tzo.cjs → runCodex-CH4lz1QX.cjs} +2 -4
- package/dist/{runCodex-Biis9GFw.mjs → runCodex-d2KQX2mn.mjs} +2 -4
- package/dist/{runGemini-BSH4b0wu.mjs → runGemini-Cn0C7MS1.mjs} +101 -31
- package/dist/{runGemini-FOBXtEU6.cjs → runGemini-DNSymY04.cjs} +101 -31
- package/dist/{types-BYHCKlu_.cjs → types-DeH24uWs.cjs} +2 -2
- package/dist/{types-C4QeUggl.mjs → types-mXJc7o0P.mjs} +1 -1
- package/package.json +1 -1
- package/scripts/claude_version_utils.cjs +66 -12
- package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPEditorCommands.cpp +32 -11
- package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/UnrealMCP.Build.cs +1 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var os = require('node:os');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var types = require('./types-
|
|
6
|
+
var types = require('./types-DeH24uWs.cjs');
|
|
7
7
|
var node_child_process = require('node:child_process');
|
|
8
8
|
var path = require('node:path');
|
|
9
9
|
var node_readline = require('node:readline');
|
|
@@ -1258,7 +1258,8 @@ function buildDaemonSafeEnv(baseEnv, binPath) {
|
|
|
1258
1258
|
if (!p) return;
|
|
1259
1259
|
if (!prepend.includes(p) && !existingParts.includes(p)) prepend.push(p);
|
|
1260
1260
|
};
|
|
1261
|
-
|
|
1261
|
+
const isPathLike = typeof binPath === "string" && binPath.length > 0 && (binPath.includes("/") || binPath.includes("\\")) && !binPath.startsWith("\\\\");
|
|
1262
|
+
if (isPathLike) {
|
|
1262
1263
|
add(path.dirname(binPath));
|
|
1263
1264
|
}
|
|
1264
1265
|
add(path.dirname(process$1.execPath));
|
|
@@ -1272,12 +1273,12 @@ function buildDaemonSafeEnv(baseEnv, binPath) {
|
|
|
1272
1273
|
env[pathKey] = [...prepend, ...existingParts].join(pathSep);
|
|
1273
1274
|
return env;
|
|
1274
1275
|
}
|
|
1275
|
-
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
1276
|
+
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-Bhkn02hu.cjs', document.baseURI).href)));
|
|
1276
1277
|
const __dirname$1 = path.join(__filename$1, "..");
|
|
1277
1278
|
function getGlobalClaudeVersion(claudeExecutable) {
|
|
1278
1279
|
try {
|
|
1279
1280
|
const cleanEnv = buildDaemonSafeEnv(getCleanEnv(), claudeExecutable);
|
|
1280
|
-
const output = claudeExecutable.includes("/") && !claudeExecutable.startsWith("\\\\") ? node_child_process.execFileSync(claudeExecutable, ["--version"], {
|
|
1281
|
+
const output = (claudeExecutable.includes("/") || claudeExecutable.includes("\\")) && !claudeExecutable.startsWith("\\\\") ? node_child_process.execFileSync(claudeExecutable, ["--version"], {
|
|
1281
1282
|
encoding: "utf8",
|
|
1282
1283
|
stdio: ["pipe", "pipe", "pipe"],
|
|
1283
1284
|
cwd: os.homedir(),
|
|
@@ -1295,6 +1296,35 @@ function getGlobalClaudeVersion(claudeExecutable) {
|
|
|
1295
1296
|
return null;
|
|
1296
1297
|
}
|
|
1297
1298
|
}
|
|
1299
|
+
function tryReadBundledClaudeVersion(nodeModulesCliPath) {
|
|
1300
|
+
try {
|
|
1301
|
+
const pkgPath = path.join(path.dirname(path.dirname(nodeModulesCliPath)), "package.json");
|
|
1302
|
+
if (!fs.existsSync(pkgPath)) return null;
|
|
1303
|
+
const raw = fs.readFileSync(pkgPath, "utf8");
|
|
1304
|
+
const parsed = JSON.parse(raw);
|
|
1305
|
+
const v = typeof parsed?.version === "string" ? parsed.version.trim() : "";
|
|
1306
|
+
return v || null;
|
|
1307
|
+
} catch {
|
|
1308
|
+
return null;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
function parseSemver3(v) {
|
|
1312
|
+
const m = String(v || "").trim().match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
1313
|
+
if (!m) return null;
|
|
1314
|
+
const a = Number(m[1]);
|
|
1315
|
+
const b = Number(m[2]);
|
|
1316
|
+
const c = Number(m[3]);
|
|
1317
|
+
if (!Number.isFinite(a) || !Number.isFinite(b) || !Number.isFinite(c)) return null;
|
|
1318
|
+
return [a, b, c];
|
|
1319
|
+
}
|
|
1320
|
+
function compareSemver(a, b) {
|
|
1321
|
+
const pa = parseSemver3(a);
|
|
1322
|
+
const pb = parseSemver3(b);
|
|
1323
|
+
if (!pa || !pb) return null;
|
|
1324
|
+
if (pa[0] !== pb[0]) return pa[0] - pb[0];
|
|
1325
|
+
if (pa[1] !== pb[1]) return pa[1] - pb[1];
|
|
1326
|
+
return pa[2] - pb[2];
|
|
1327
|
+
}
|
|
1298
1328
|
function getCleanEnv() {
|
|
1299
1329
|
const env = { ...process$1.env };
|
|
1300
1330
|
const cwd = process$1.cwd();
|
|
@@ -1414,11 +1444,22 @@ function getDefaultClaudeCodePath() {
|
|
|
1414
1444
|
return nodeModulesPath;
|
|
1415
1445
|
}
|
|
1416
1446
|
const globalVersion = getGlobalClaudeVersion(globalPath);
|
|
1447
|
+
const bundledVersion = tryReadBundledClaudeVersion(nodeModulesPath);
|
|
1417
1448
|
types.logger.debug(`[Claude SDK] Global version: ${globalVersion || "unknown"}`);
|
|
1418
|
-
|
|
1449
|
+
types.logger.debug(`[Claude SDK] Bundled version: ${bundledVersion || "unknown"}`);
|
|
1450
|
+
if (!globalVersion || !bundledVersion) {
|
|
1419
1451
|
types.logger.debug(`[Claude SDK] Cannot compare versions, using global: ${globalPath}`);
|
|
1420
1452
|
return globalPath;
|
|
1421
1453
|
}
|
|
1454
|
+
const cmp = compareSemver(bundledVersion, globalVersion);
|
|
1455
|
+
if (cmp === null) {
|
|
1456
|
+
types.logger.debug(`[Claude SDK] Cannot parse versions, using global: ${globalPath}`);
|
|
1457
|
+
return globalPath;
|
|
1458
|
+
}
|
|
1459
|
+
if (cmp > 0) {
|
|
1460
|
+
types.logger.debug(`[Claude SDK] Bundled Claude is newer (${bundledVersion} > ${globalVersion}), using bundled: ${nodeModulesPath}`);
|
|
1461
|
+
return nodeModulesPath;
|
|
1462
|
+
}
|
|
1422
1463
|
return globalPath;
|
|
1423
1464
|
}
|
|
1424
1465
|
function logDebug(message) {
|
|
@@ -1693,8 +1734,9 @@ function query(config) {
|
|
|
1693
1734
|
stdio: ["pipe", "pipe", "pipe"],
|
|
1694
1735
|
signal: config.options?.abort,
|
|
1695
1736
|
env: spawnEnv,
|
|
1696
|
-
//
|
|
1697
|
-
|
|
1737
|
+
// Only use a shell on Windows when spawning a bare command (e.g. "claude").
|
|
1738
|
+
// Passing large `--allowedTools` lists through cmd.exe can hit the ~8k command line limit.
|
|
1739
|
+
shell: isCommandOnly && process$1.platform === "win32"
|
|
1698
1740
|
});
|
|
1699
1741
|
let childStdin = null;
|
|
1700
1742
|
if (typeof prompt === "string") {
|
|
@@ -2470,6 +2512,21 @@ async function consumeToolQuota(args) {
|
|
|
2470
2512
|
return { ok: true, allowed: true, unlimited: true };
|
|
2471
2513
|
}
|
|
2472
2514
|
|
|
2515
|
+
function canonicalizeToolNameForMatching(name) {
|
|
2516
|
+
if (name === "ExitPlanMode") return "exit_plan_mode";
|
|
2517
|
+
return name;
|
|
2518
|
+
}
|
|
2519
|
+
function stripUndefinedDeep(value) {
|
|
2520
|
+
if (value === null || value === void 0) return value;
|
|
2521
|
+
if (Array.isArray(value)) return value.map(stripUndefinedDeep);
|
|
2522
|
+
if (typeof value !== "object") return value;
|
|
2523
|
+
const out = {};
|
|
2524
|
+
for (const [key, child] of Object.entries(value)) {
|
|
2525
|
+
if (child === void 0) continue;
|
|
2526
|
+
out[key] = stripUndefinedDeep(child);
|
|
2527
|
+
}
|
|
2528
|
+
return out;
|
|
2529
|
+
}
|
|
2473
2530
|
class PermissionHandler {
|
|
2474
2531
|
toolCalls = [];
|
|
2475
2532
|
responses = /* @__PURE__ */ new Map();
|
|
@@ -2753,8 +2810,13 @@ ${next}`
|
|
|
2753
2810
|
}
|
|
2754
2811
|
let toolCallId = this.resolveToolCallId(toolName, input);
|
|
2755
2812
|
if (!toolCallId) {
|
|
2756
|
-
|
|
2757
|
-
|
|
2813
|
+
const isPlanMode = toolName === "exit_plan_mode" || toolName === "ExitPlanMode";
|
|
2814
|
+
const timeoutMs = isPlanMode ? 3e3 : 1e3;
|
|
2815
|
+
const deadline = Date.now() + timeoutMs;
|
|
2816
|
+
while (!toolCallId && Date.now() < deadline) {
|
|
2817
|
+
await types.delay(100);
|
|
2818
|
+
toolCallId = this.resolveToolCallId(toolName, input);
|
|
2819
|
+
}
|
|
2758
2820
|
if (!toolCallId) {
|
|
2759
2821
|
throw new Error(`Could not resolve tool call ID for ${toolName}`);
|
|
2760
2822
|
}
|
|
@@ -2835,9 +2897,12 @@ ${next}`
|
|
|
2835
2897
|
* Resolves tool call ID based on tool name and input
|
|
2836
2898
|
*/
|
|
2837
2899
|
resolveToolCallId(name, args) {
|
|
2900
|
+
const normalizedName = canonicalizeToolNameForMatching(name);
|
|
2901
|
+
const normalizedArgs = stripUndefinedDeep(args);
|
|
2838
2902
|
for (let i = this.toolCalls.length - 1; i >= 0; i--) {
|
|
2839
2903
|
const call = this.toolCalls[i];
|
|
2840
|
-
|
|
2904
|
+
const callName = canonicalizeToolNameForMatching(call.name);
|
|
2905
|
+
if (callName === normalizedName && deepEqual(stripUndefinedDeep(call.input), normalizedArgs)) {
|
|
2841
2906
|
if (call.used) {
|
|
2842
2907
|
return null;
|
|
2843
2908
|
}
|
|
@@ -2845,6 +2910,18 @@ ${next}`
|
|
|
2845
2910
|
return call.id;
|
|
2846
2911
|
}
|
|
2847
2912
|
}
|
|
2913
|
+
const candidates = [];
|
|
2914
|
+
for (let i = this.toolCalls.length - 1; i >= 0; i--) {
|
|
2915
|
+
const call = this.toolCalls[i];
|
|
2916
|
+
if (call.used) continue;
|
|
2917
|
+
const callName = canonicalizeToolNameForMatching(call.name);
|
|
2918
|
+
if (callName === normalizedName) candidates.push(call);
|
|
2919
|
+
if (candidates.length > 1) break;
|
|
2920
|
+
}
|
|
2921
|
+
if (candidates.length === 1) {
|
|
2922
|
+
candidates[0].used = true;
|
|
2923
|
+
return candidates[0].id;
|
|
2924
|
+
}
|
|
2848
2925
|
return null;
|
|
2849
2926
|
}
|
|
2850
2927
|
/**
|
|
@@ -7117,7 +7194,11 @@ async function uploadScreenshotViewsForSession(args) {
|
|
|
7117
7194
|
for (const v of args.views) {
|
|
7118
7195
|
const buf = await fs$2.readFile(v.path);
|
|
7119
7196
|
const filename = path.basename(v.path);
|
|
7120
|
-
const contentType =
|
|
7197
|
+
const contentType = (() => {
|
|
7198
|
+
const mime = detectImageMimeTypeFromBuffer(buf);
|
|
7199
|
+
if (mime) return mime;
|
|
7200
|
+
throw new Error(`Unsupported screenshot format (expected PNG/JPEG): ${v.path}`);
|
|
7201
|
+
})();
|
|
7121
7202
|
const blob = new Blob([buf], { type: contentType });
|
|
7122
7203
|
form.append(`file:${v.id}`, blob, filename);
|
|
7123
7204
|
}
|
|
@@ -7158,6 +7239,22 @@ async function uploadScreenshotViewsForSession(args) {
|
|
|
7158
7239
|
}
|
|
7159
7240
|
return out;
|
|
7160
7241
|
}
|
|
7242
|
+
function detectImageMimeTypeFromBuffer(buf) {
|
|
7243
|
+
if (!buf || buf.length < 12) return null;
|
|
7244
|
+
if (buf[0] === 137 && buf[1] === 80 && buf[2] === 78 && buf[3] === 71 && buf[4] === 13 && buf[5] === 10 && buf[6] === 26 && buf[7] === 10) {
|
|
7245
|
+
return "image/png";
|
|
7246
|
+
}
|
|
7247
|
+
if (buf[0] === 255 && buf[1] === 216 && buf[2] === 255) {
|
|
7248
|
+
return "image/jpeg";
|
|
7249
|
+
}
|
|
7250
|
+
if (buf[0] === 71 && buf[1] === 73 && buf[2] === 70 && buf[3] === 56 && (buf[4] === 55 || buf[4] === 57) && buf[5] === 97) {
|
|
7251
|
+
return "image/gif";
|
|
7252
|
+
}
|
|
7253
|
+
if (buf[0] === 82 && buf[1] === 73 && buf[2] === 70 && buf[3] === 70 && buf[8] === 87 && buf[9] === 69 && buf[10] === 66 && buf[11] === 80) {
|
|
7254
|
+
return "image/webp";
|
|
7255
|
+
}
|
|
7256
|
+
return null;
|
|
7257
|
+
}
|
|
7161
7258
|
async function startFlockbayServer(client, options) {
|
|
7162
7259
|
const handler = async (title) => {
|
|
7163
7260
|
types.logger.debug("[flockbayMCP] Changing title to:", title);
|
|
@@ -8687,13 +8784,13 @@ ${String(st.stdout || "").trim()}`
|
|
|
8687
8784
|
"read_images",
|
|
8688
8785
|
{
|
|
8689
8786
|
title: "Read Images",
|
|
8690
|
-
description: "Read one or more local
|
|
8787
|
+
description: "Read one or more local images by path (PNG/JPEG) and return a `{ views: [...] }` payload so the app can render them as a gallery.",
|
|
8691
8788
|
inputSchema: {
|
|
8692
|
-
paths: z.z.array(z.z.string()).describe("Image paths (absolute or relative to the session directory). PNG only."),
|
|
8789
|
+
paths: z.z.array(z.z.string()).describe("Image paths (absolute or relative to the session directory). PNG/JPG only."),
|
|
8693
8790
|
limit: z.z.number().int().positive().optional().describe("Max number of images to include (default 10)."),
|
|
8694
8791
|
upload: z.z.boolean().optional().describe("Upload images to the session screenshots store and return HTTPS URLs (default true)."),
|
|
8695
8792
|
includeBase64: z.z.boolean().optional().describe("Include base64 data in the payload (default false)."),
|
|
8696
|
-
includeToolImages: z.z.boolean().optional().describe("Include MCP image blocks so vision models can see the
|
|
8793
|
+
includeToolImages: z.z.boolean().optional().describe("Include MCP image blocks so vision models can see the images (default false)."),
|
|
8697
8794
|
maxBytesPerImage: z.z.number().int().positive().optional().describe("Max bytes per image when includeBase64=true (default 2500000).")
|
|
8698
8795
|
}
|
|
8699
8796
|
},
|
|
@@ -8725,14 +8822,16 @@ ${String(st.stdout || "").trim()}`
|
|
|
8725
8822
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
8726
8823
|
if (home) return path.join(home, p.slice(2));
|
|
8727
8824
|
}
|
|
8728
|
-
|
|
8825
|
+
const baseDir = readSessionWorkingDirectory();
|
|
8826
|
+
return path.isAbsolute(p) ? p : path.resolve(baseDir, p);
|
|
8729
8827
|
};
|
|
8730
8828
|
const idsSeen = /* @__PURE__ */ new Set();
|
|
8731
8829
|
const viewsLocal = [];
|
|
8732
8830
|
for (const inputPath of paths) {
|
|
8733
8831
|
const abs = resolvePath(inputPath);
|
|
8734
|
-
|
|
8735
|
-
|
|
8832
|
+
const lower = abs.toLowerCase();
|
|
8833
|
+
if (!lower.endsWith(".png") && !lower.endsWith(".jpg") && !lower.endsWith(".jpeg")) {
|
|
8834
|
+
throw new Error(`Only PNG/JPG images are supported: ${abs}`);
|
|
8736
8835
|
}
|
|
8737
8836
|
if (!fs.existsSync(abs)) {
|
|
8738
8837
|
throw new Error(`Image not found: ${abs}`);
|
|
@@ -8752,7 +8851,11 @@ ${String(st.stdout || "").trim()}`
|
|
|
8752
8851
|
throw new Error(`Image too large (${st.size} bytes) to embed: ${abs}`);
|
|
8753
8852
|
}
|
|
8754
8853
|
const buf = await fs$2.readFile(abs);
|
|
8755
|
-
|
|
8854
|
+
const mime = detectImageMimeTypeFromBuffer(buf);
|
|
8855
|
+
if (!mime) {
|
|
8856
|
+
throw new Error(`Unsupported image format (expected PNG/JPEG): ${abs}`);
|
|
8857
|
+
}
|
|
8858
|
+
viewsLocal.push({ id: unique, path: abs, base64: buf.toString("base64"), mimeType: mime });
|
|
8756
8859
|
} else {
|
|
8757
8860
|
viewsLocal.push({ id: unique, path: abs });
|
|
8758
8861
|
}
|
|
@@ -8777,7 +8880,7 @@ ${String(st.stdout || "").trim()}`
|
|
|
8777
8880
|
viewsLocal.forEach((v, idx) => {
|
|
8778
8881
|
if (!v.base64) return;
|
|
8779
8882
|
content.push({ type: "text", text: `Image ${idx + 1}: ${v.id}` });
|
|
8780
|
-
content.push({ type: "image", data: v.base64, mimeType: "image/png" });
|
|
8883
|
+
content.push({ type: "image", data: v.base64, mimeType: v.mimeType || "image/png" });
|
|
8781
8884
|
});
|
|
8782
8885
|
}
|
|
8783
8886
|
return {
|
|
@@ -8789,7 +8892,7 @@ ${String(st.stdout || "").trim()}`
|
|
|
8789
8892
|
return {
|
|
8790
8893
|
content: [
|
|
8791
8894
|
{ type: "text", text: `Failed to read images: ${error instanceof Error ? error.message : String(error)}` },
|
|
8792
|
-
{ type: "text", text: `Tip: pass absolute PNG paths, or relative paths from the session folder.` }
|
|
8895
|
+
{ type: "text", text: `Tip: pass absolute PNG/JPG paths, or relative paths from the session folder.` }
|
|
8793
8896
|
],
|
|
8794
8897
|
isError: true
|
|
8795
8898
|
};
|
|
@@ -12224,7 +12327,7 @@ ${engineRoot}`, {
|
|
|
12224
12327
|
} else if (subcommand === "codex") {
|
|
12225
12328
|
try {
|
|
12226
12329
|
await chdirToNearestUprojectRootIfPresent();
|
|
12227
|
-
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-
|
|
12330
|
+
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-CH4lz1QX.cjs'); });
|
|
12228
12331
|
let startedBy = void 0;
|
|
12229
12332
|
let sessionId = void 0;
|
|
12230
12333
|
for (let i = 1; i < args.length; i++) {
|
|
@@ -12319,7 +12422,7 @@ ${engineRoot}`, {
|
|
|
12319
12422
|
}
|
|
12320
12423
|
try {
|
|
12321
12424
|
await chdirToNearestUprojectRootIfPresent();
|
|
12322
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
12425
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-DNSymY04.cjs'); });
|
|
12323
12426
|
let startedBy = void 0;
|
|
12324
12427
|
let sessionId = void 0;
|
|
12325
12428
|
for (let i = 1; i < args.length; i++) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
|
|
2
2
|
import os, { homedir } from 'node:os';
|
|
3
3
|
import { randomUUID, createCipheriv, randomBytes } from 'node:crypto';
|
|
4
|
-
import { l as logger, p as projectPath, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as readDaemonState, g as clearDaemonState, b as packageJson, r as readSettings, h as readCredentials, u as updateSettings, w as writeCredentials, i as unrealMcpPythonDir, j as acquireDaemonLock, k as writeDaemonState, m as ApiMachineClient, n as releaseDaemonLock, s as sendUnrealMcpTcpCommand, A as ApiClient, o as clearCredentials, q as clearMachineId, t as installUnrealMcpPluginToEngine, v as getLatestDaemonLog, x as normalizeServerUrlForNode } from './types-
|
|
4
|
+
import { l as logger, p as projectPath, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as readDaemonState, g as clearDaemonState, b as packageJson, r as readSettings, h as readCredentials, u as updateSettings, w as writeCredentials, i as unrealMcpPythonDir, j as acquireDaemonLock, k as writeDaemonState, m as ApiMachineClient, n as releaseDaemonLock, s as sendUnrealMcpTcpCommand, A as ApiClient, o as clearCredentials, q as clearMachineId, t as installUnrealMcpPluginToEngine, v as getLatestDaemonLog, x as normalizeServerUrlForNode } from './types-mXJc7o0P.mjs';
|
|
5
5
|
import { spawn, execFileSync, execSync } from 'node:child_process';
|
|
6
6
|
import path, { resolve, join, dirname } from 'node:path';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
@@ -1236,7 +1236,8 @@ function buildDaemonSafeEnv(baseEnv, binPath) {
|
|
|
1236
1236
|
if (!p) return;
|
|
1237
1237
|
if (!prepend.includes(p) && !existingParts.includes(p)) prepend.push(p);
|
|
1238
1238
|
};
|
|
1239
|
-
|
|
1239
|
+
const isPathLike = typeof binPath === "string" && binPath.length > 0 && (binPath.includes("/") || binPath.includes("\\")) && !binPath.startsWith("\\\\");
|
|
1240
|
+
if (isPathLike) {
|
|
1240
1241
|
add(dirname(binPath));
|
|
1241
1242
|
}
|
|
1242
1243
|
add(dirname(process$1.execPath));
|
|
@@ -1255,7 +1256,7 @@ const __dirname$1 = join(__filename$1, "..");
|
|
|
1255
1256
|
function getGlobalClaudeVersion(claudeExecutable) {
|
|
1256
1257
|
try {
|
|
1257
1258
|
const cleanEnv = buildDaemonSafeEnv(getCleanEnv(), claudeExecutable);
|
|
1258
|
-
const output = claudeExecutable.includes("/") && !claudeExecutable.startsWith("\\\\") ? execFileSync(claudeExecutable, ["--version"], {
|
|
1259
|
+
const output = (claudeExecutable.includes("/") || claudeExecutable.includes("\\")) && !claudeExecutable.startsWith("\\\\") ? execFileSync(claudeExecutable, ["--version"], {
|
|
1259
1260
|
encoding: "utf8",
|
|
1260
1261
|
stdio: ["pipe", "pipe", "pipe"],
|
|
1261
1262
|
cwd: homedir(),
|
|
@@ -1273,6 +1274,35 @@ function getGlobalClaudeVersion(claudeExecutable) {
|
|
|
1273
1274
|
return null;
|
|
1274
1275
|
}
|
|
1275
1276
|
}
|
|
1277
|
+
function tryReadBundledClaudeVersion(nodeModulesCliPath) {
|
|
1278
|
+
try {
|
|
1279
|
+
const pkgPath = join(dirname(dirname(nodeModulesCliPath)), "package.json");
|
|
1280
|
+
if (!existsSync(pkgPath)) return null;
|
|
1281
|
+
const raw = readFileSync(pkgPath, "utf8");
|
|
1282
|
+
const parsed = JSON.parse(raw);
|
|
1283
|
+
const v = typeof parsed?.version === "string" ? parsed.version.trim() : "";
|
|
1284
|
+
return v || null;
|
|
1285
|
+
} catch {
|
|
1286
|
+
return null;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
function parseSemver3(v) {
|
|
1290
|
+
const m = String(v || "").trim().match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
1291
|
+
if (!m) return null;
|
|
1292
|
+
const a = Number(m[1]);
|
|
1293
|
+
const b = Number(m[2]);
|
|
1294
|
+
const c = Number(m[3]);
|
|
1295
|
+
if (!Number.isFinite(a) || !Number.isFinite(b) || !Number.isFinite(c)) return null;
|
|
1296
|
+
return [a, b, c];
|
|
1297
|
+
}
|
|
1298
|
+
function compareSemver(a, b) {
|
|
1299
|
+
const pa = parseSemver3(a);
|
|
1300
|
+
const pb = parseSemver3(b);
|
|
1301
|
+
if (!pa || !pb) return null;
|
|
1302
|
+
if (pa[0] !== pb[0]) return pa[0] - pb[0];
|
|
1303
|
+
if (pa[1] !== pb[1]) return pa[1] - pb[1];
|
|
1304
|
+
return pa[2] - pb[2];
|
|
1305
|
+
}
|
|
1276
1306
|
function getCleanEnv() {
|
|
1277
1307
|
const env = { ...process$1.env };
|
|
1278
1308
|
const cwd = process$1.cwd();
|
|
@@ -1392,11 +1422,22 @@ function getDefaultClaudeCodePath() {
|
|
|
1392
1422
|
return nodeModulesPath;
|
|
1393
1423
|
}
|
|
1394
1424
|
const globalVersion = getGlobalClaudeVersion(globalPath);
|
|
1425
|
+
const bundledVersion = tryReadBundledClaudeVersion(nodeModulesPath);
|
|
1395
1426
|
logger.debug(`[Claude SDK] Global version: ${globalVersion || "unknown"}`);
|
|
1396
|
-
|
|
1427
|
+
logger.debug(`[Claude SDK] Bundled version: ${bundledVersion || "unknown"}`);
|
|
1428
|
+
if (!globalVersion || !bundledVersion) {
|
|
1397
1429
|
logger.debug(`[Claude SDK] Cannot compare versions, using global: ${globalPath}`);
|
|
1398
1430
|
return globalPath;
|
|
1399
1431
|
}
|
|
1432
|
+
const cmp = compareSemver(bundledVersion, globalVersion);
|
|
1433
|
+
if (cmp === null) {
|
|
1434
|
+
logger.debug(`[Claude SDK] Cannot parse versions, using global: ${globalPath}`);
|
|
1435
|
+
return globalPath;
|
|
1436
|
+
}
|
|
1437
|
+
if (cmp > 0) {
|
|
1438
|
+
logger.debug(`[Claude SDK] Bundled Claude is newer (${bundledVersion} > ${globalVersion}), using bundled: ${nodeModulesPath}`);
|
|
1439
|
+
return nodeModulesPath;
|
|
1440
|
+
}
|
|
1400
1441
|
return globalPath;
|
|
1401
1442
|
}
|
|
1402
1443
|
function logDebug(message) {
|
|
@@ -1671,8 +1712,9 @@ function query(config) {
|
|
|
1671
1712
|
stdio: ["pipe", "pipe", "pipe"],
|
|
1672
1713
|
signal: config.options?.abort,
|
|
1673
1714
|
env: spawnEnv,
|
|
1674
|
-
//
|
|
1675
|
-
|
|
1715
|
+
// Only use a shell on Windows when spawning a bare command (e.g. "claude").
|
|
1716
|
+
// Passing large `--allowedTools` lists through cmd.exe can hit the ~8k command line limit.
|
|
1717
|
+
shell: isCommandOnly && process$1.platform === "win32"
|
|
1676
1718
|
});
|
|
1677
1719
|
let childStdin = null;
|
|
1678
1720
|
if (typeof prompt === "string") {
|
|
@@ -2448,6 +2490,21 @@ async function consumeToolQuota(args) {
|
|
|
2448
2490
|
return { ok: true, allowed: true, unlimited: true };
|
|
2449
2491
|
}
|
|
2450
2492
|
|
|
2493
|
+
function canonicalizeToolNameForMatching(name) {
|
|
2494
|
+
if (name === "ExitPlanMode") return "exit_plan_mode";
|
|
2495
|
+
return name;
|
|
2496
|
+
}
|
|
2497
|
+
function stripUndefinedDeep(value) {
|
|
2498
|
+
if (value === null || value === void 0) return value;
|
|
2499
|
+
if (Array.isArray(value)) return value.map(stripUndefinedDeep);
|
|
2500
|
+
if (typeof value !== "object") return value;
|
|
2501
|
+
const out = {};
|
|
2502
|
+
for (const [key, child] of Object.entries(value)) {
|
|
2503
|
+
if (child === void 0) continue;
|
|
2504
|
+
out[key] = stripUndefinedDeep(child);
|
|
2505
|
+
}
|
|
2506
|
+
return out;
|
|
2507
|
+
}
|
|
2451
2508
|
class PermissionHandler {
|
|
2452
2509
|
toolCalls = [];
|
|
2453
2510
|
responses = /* @__PURE__ */ new Map();
|
|
@@ -2731,8 +2788,13 @@ ${next}`
|
|
|
2731
2788
|
}
|
|
2732
2789
|
let toolCallId = this.resolveToolCallId(toolName, input);
|
|
2733
2790
|
if (!toolCallId) {
|
|
2734
|
-
|
|
2735
|
-
|
|
2791
|
+
const isPlanMode = toolName === "exit_plan_mode" || toolName === "ExitPlanMode";
|
|
2792
|
+
const timeoutMs = isPlanMode ? 3e3 : 1e3;
|
|
2793
|
+
const deadline = Date.now() + timeoutMs;
|
|
2794
|
+
while (!toolCallId && Date.now() < deadline) {
|
|
2795
|
+
await delay(100);
|
|
2796
|
+
toolCallId = this.resolveToolCallId(toolName, input);
|
|
2797
|
+
}
|
|
2736
2798
|
if (!toolCallId) {
|
|
2737
2799
|
throw new Error(`Could not resolve tool call ID for ${toolName}`);
|
|
2738
2800
|
}
|
|
@@ -2813,9 +2875,12 @@ ${next}`
|
|
|
2813
2875
|
* Resolves tool call ID based on tool name and input
|
|
2814
2876
|
*/
|
|
2815
2877
|
resolveToolCallId(name, args) {
|
|
2878
|
+
const normalizedName = canonicalizeToolNameForMatching(name);
|
|
2879
|
+
const normalizedArgs = stripUndefinedDeep(args);
|
|
2816
2880
|
for (let i = this.toolCalls.length - 1; i >= 0; i--) {
|
|
2817
2881
|
const call = this.toolCalls[i];
|
|
2818
|
-
|
|
2882
|
+
const callName = canonicalizeToolNameForMatching(call.name);
|
|
2883
|
+
if (callName === normalizedName && deepEqual(stripUndefinedDeep(call.input), normalizedArgs)) {
|
|
2819
2884
|
if (call.used) {
|
|
2820
2885
|
return null;
|
|
2821
2886
|
}
|
|
@@ -2823,6 +2888,18 @@ ${next}`
|
|
|
2823
2888
|
return call.id;
|
|
2824
2889
|
}
|
|
2825
2890
|
}
|
|
2891
|
+
const candidates = [];
|
|
2892
|
+
for (let i = this.toolCalls.length - 1; i >= 0; i--) {
|
|
2893
|
+
const call = this.toolCalls[i];
|
|
2894
|
+
if (call.used) continue;
|
|
2895
|
+
const callName = canonicalizeToolNameForMatching(call.name);
|
|
2896
|
+
if (callName === normalizedName) candidates.push(call);
|
|
2897
|
+
if (candidates.length > 1) break;
|
|
2898
|
+
}
|
|
2899
|
+
if (candidates.length === 1) {
|
|
2900
|
+
candidates[0].used = true;
|
|
2901
|
+
return candidates[0].id;
|
|
2902
|
+
}
|
|
2826
2903
|
return null;
|
|
2827
2904
|
}
|
|
2828
2905
|
/**
|
|
@@ -7095,7 +7172,11 @@ async function uploadScreenshotViewsForSession(args) {
|
|
|
7095
7172
|
for (const v of args.views) {
|
|
7096
7173
|
const buf = await readFile(v.path);
|
|
7097
7174
|
const filename = path.basename(v.path);
|
|
7098
|
-
const contentType =
|
|
7175
|
+
const contentType = (() => {
|
|
7176
|
+
const mime = detectImageMimeTypeFromBuffer(buf);
|
|
7177
|
+
if (mime) return mime;
|
|
7178
|
+
throw new Error(`Unsupported screenshot format (expected PNG/JPEG): ${v.path}`);
|
|
7179
|
+
})();
|
|
7099
7180
|
const blob = new Blob([buf], { type: contentType });
|
|
7100
7181
|
form.append(`file:${v.id}`, blob, filename);
|
|
7101
7182
|
}
|
|
@@ -7136,6 +7217,22 @@ async function uploadScreenshotViewsForSession(args) {
|
|
|
7136
7217
|
}
|
|
7137
7218
|
return out;
|
|
7138
7219
|
}
|
|
7220
|
+
function detectImageMimeTypeFromBuffer(buf) {
|
|
7221
|
+
if (!buf || buf.length < 12) return null;
|
|
7222
|
+
if (buf[0] === 137 && buf[1] === 80 && buf[2] === 78 && buf[3] === 71 && buf[4] === 13 && buf[5] === 10 && buf[6] === 26 && buf[7] === 10) {
|
|
7223
|
+
return "image/png";
|
|
7224
|
+
}
|
|
7225
|
+
if (buf[0] === 255 && buf[1] === 216 && buf[2] === 255) {
|
|
7226
|
+
return "image/jpeg";
|
|
7227
|
+
}
|
|
7228
|
+
if (buf[0] === 71 && buf[1] === 73 && buf[2] === 70 && buf[3] === 56 && (buf[4] === 55 || buf[4] === 57) && buf[5] === 97) {
|
|
7229
|
+
return "image/gif";
|
|
7230
|
+
}
|
|
7231
|
+
if (buf[0] === 82 && buf[1] === 73 && buf[2] === 70 && buf[3] === 70 && buf[8] === 87 && buf[9] === 69 && buf[10] === 66 && buf[11] === 80) {
|
|
7232
|
+
return "image/webp";
|
|
7233
|
+
}
|
|
7234
|
+
return null;
|
|
7235
|
+
}
|
|
7139
7236
|
async function startFlockbayServer(client, options) {
|
|
7140
7237
|
const handler = async (title) => {
|
|
7141
7238
|
logger.debug("[flockbayMCP] Changing title to:", title);
|
|
@@ -8665,13 +8762,13 @@ ${String(st.stdout || "").trim()}`
|
|
|
8665
8762
|
"read_images",
|
|
8666
8763
|
{
|
|
8667
8764
|
title: "Read Images",
|
|
8668
|
-
description: "Read one or more local
|
|
8765
|
+
description: "Read one or more local images by path (PNG/JPEG) and return a `{ views: [...] }` payload so the app can render them as a gallery.",
|
|
8669
8766
|
inputSchema: {
|
|
8670
|
-
paths: z.array(z.string()).describe("Image paths (absolute or relative to the session directory). PNG only."),
|
|
8767
|
+
paths: z.array(z.string()).describe("Image paths (absolute or relative to the session directory). PNG/JPG only."),
|
|
8671
8768
|
limit: z.number().int().positive().optional().describe("Max number of images to include (default 10)."),
|
|
8672
8769
|
upload: z.boolean().optional().describe("Upload images to the session screenshots store and return HTTPS URLs (default true)."),
|
|
8673
8770
|
includeBase64: z.boolean().optional().describe("Include base64 data in the payload (default false)."),
|
|
8674
|
-
includeToolImages: z.boolean().optional().describe("Include MCP image blocks so vision models can see the
|
|
8771
|
+
includeToolImages: z.boolean().optional().describe("Include MCP image blocks so vision models can see the images (default false)."),
|
|
8675
8772
|
maxBytesPerImage: z.number().int().positive().optional().describe("Max bytes per image when includeBase64=true (default 2500000).")
|
|
8676
8773
|
}
|
|
8677
8774
|
},
|
|
@@ -8703,14 +8800,16 @@ ${String(st.stdout || "").trim()}`
|
|
|
8703
8800
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
8704
8801
|
if (home) return path.join(home, p.slice(2));
|
|
8705
8802
|
}
|
|
8706
|
-
|
|
8803
|
+
const baseDir = readSessionWorkingDirectory();
|
|
8804
|
+
return path.isAbsolute(p) ? p : path.resolve(baseDir, p);
|
|
8707
8805
|
};
|
|
8708
8806
|
const idsSeen = /* @__PURE__ */ new Set();
|
|
8709
8807
|
const viewsLocal = [];
|
|
8710
8808
|
for (const inputPath of paths) {
|
|
8711
8809
|
const abs = resolvePath(inputPath);
|
|
8712
|
-
|
|
8713
|
-
|
|
8810
|
+
const lower = abs.toLowerCase();
|
|
8811
|
+
if (!lower.endsWith(".png") && !lower.endsWith(".jpg") && !lower.endsWith(".jpeg")) {
|
|
8812
|
+
throw new Error(`Only PNG/JPG images are supported: ${abs}`);
|
|
8714
8813
|
}
|
|
8715
8814
|
if (!existsSync(abs)) {
|
|
8716
8815
|
throw new Error(`Image not found: ${abs}`);
|
|
@@ -8730,7 +8829,11 @@ ${String(st.stdout || "").trim()}`
|
|
|
8730
8829
|
throw new Error(`Image too large (${st.size} bytes) to embed: ${abs}`);
|
|
8731
8830
|
}
|
|
8732
8831
|
const buf = await readFile(abs);
|
|
8733
|
-
|
|
8832
|
+
const mime = detectImageMimeTypeFromBuffer(buf);
|
|
8833
|
+
if (!mime) {
|
|
8834
|
+
throw new Error(`Unsupported image format (expected PNG/JPEG): ${abs}`);
|
|
8835
|
+
}
|
|
8836
|
+
viewsLocal.push({ id: unique, path: abs, base64: buf.toString("base64"), mimeType: mime });
|
|
8734
8837
|
} else {
|
|
8735
8838
|
viewsLocal.push({ id: unique, path: abs });
|
|
8736
8839
|
}
|
|
@@ -8755,7 +8858,7 @@ ${String(st.stdout || "").trim()}`
|
|
|
8755
8858
|
viewsLocal.forEach((v, idx) => {
|
|
8756
8859
|
if (!v.base64) return;
|
|
8757
8860
|
content.push({ type: "text", text: `Image ${idx + 1}: ${v.id}` });
|
|
8758
|
-
content.push({ type: "image", data: v.base64, mimeType: "image/png" });
|
|
8861
|
+
content.push({ type: "image", data: v.base64, mimeType: v.mimeType || "image/png" });
|
|
8759
8862
|
});
|
|
8760
8863
|
}
|
|
8761
8864
|
return {
|
|
@@ -8767,7 +8870,7 @@ ${String(st.stdout || "").trim()}`
|
|
|
8767
8870
|
return {
|
|
8768
8871
|
content: [
|
|
8769
8872
|
{ type: "text", text: `Failed to read images: ${error instanceof Error ? error.message : String(error)}` },
|
|
8770
|
-
{ type: "text", text: `Tip: pass absolute PNG paths, or relative paths from the session folder.` }
|
|
8873
|
+
{ type: "text", text: `Tip: pass absolute PNG/JPG paths, or relative paths from the session folder.` }
|
|
8771
8874
|
],
|
|
8772
8875
|
isError: true
|
|
8773
8876
|
};
|
|
@@ -12202,7 +12305,7 @@ ${engineRoot}`, {
|
|
|
12202
12305
|
} else if (subcommand === "codex") {
|
|
12203
12306
|
try {
|
|
12204
12307
|
await chdirToNearestUprojectRootIfPresent();
|
|
12205
|
-
const { runCodex } = await import('./runCodex-
|
|
12308
|
+
const { runCodex } = await import('./runCodex-d2KQX2mn.mjs');
|
|
12206
12309
|
let startedBy = void 0;
|
|
12207
12310
|
let sessionId = void 0;
|
|
12208
12311
|
for (let i = 1; i < args.length; i++) {
|
|
@@ -12297,7 +12400,7 @@ ${engineRoot}`, {
|
|
|
12297
12400
|
}
|
|
12298
12401
|
try {
|
|
12299
12402
|
await chdirToNearestUprojectRootIfPresent();
|
|
12300
|
-
const { runGemini } = await import('./runGemini-
|
|
12403
|
+
const { runGemini } = await import('./runGemini-Cn0C7MS1.mjs');
|
|
12301
12404
|
let startedBy = void 0;
|
|
12302
12405
|
let sessionId = void 0;
|
|
12303
12406
|
for (let i = 1; i < args.length; i++) {
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
package/dist/lib.cjs
CHANGED
package/dist/lib.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-mXJc7o0P.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'node:fs';
|
|
4
4
|
import 'node:os';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var ink = require('ink');
|
|
4
4
|
var React = require('react');
|
|
5
|
-
var types = require('./types-
|
|
5
|
+
var types = require('./types-DeH24uWs.cjs');
|
|
6
6
|
var index_js = require('@modelcontextprotocol/sdk/client/index.js');
|
|
7
7
|
var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
8
8
|
var z = require('zod');
|
|
@@ -12,7 +12,7 @@ var fs = require('node:fs');
|
|
|
12
12
|
var os = require('node:os');
|
|
13
13
|
var path = require('node:path');
|
|
14
14
|
var node_child_process = require('node:child_process');
|
|
15
|
-
var index = require('./index-
|
|
15
|
+
var index = require('./index-Bhkn02hu.cjs');
|
|
16
16
|
require('axios');
|
|
17
17
|
require('node:events');
|
|
18
18
|
require('socket.io-client');
|
|
@@ -3179,11 +3179,9 @@ async function runCodex(opts) {
|
|
|
3179
3179
|
} else if (msg.type === "task_complete") {
|
|
3180
3180
|
messageBuffer.addMessage("Task completed", "status");
|
|
3181
3181
|
flushInflightExecCalls({ isError: false, reason: "task_complete" });
|
|
3182
|
-
sendReady();
|
|
3183
3182
|
} else if (msg.type === "turn_aborted") {
|
|
3184
3183
|
messageBuffer.addMessage("Turn aborted", "status");
|
|
3185
3184
|
flushInflightExecCalls({ isError: true, reason: "turn_aborted" });
|
|
3186
|
-
sendReady();
|
|
3187
3185
|
}
|
|
3188
3186
|
if (msg.type === "task_started") {
|
|
3189
3187
|
if (!thinking) {
|