flockbay 0.10.46 → 0.10.48
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-CNHBXWGe.mjs → index-BLsRYyPq.mjs} +104 -31
- package/dist/{index-BsespsLC.cjs → index-jd6DaTy_.cjs} +105 -32
- 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/{migratePlugin-CcRAl4zO.mjs → migratePlugin-BPUAeqI_.mjs} +1 -1
- package/dist/{migratePlugin-B2SM0IhP.cjs → migratePlugin-CyWWA8GW.cjs} +1 -1
- package/dist/{runCodex-b9J0CZko.mjs → runCodex-BkdEucuI.mjs} +81 -35
- package/dist/{runCodex-Rx9uhhBt.cjs → runCodex-D8On-xj7.cjs} +81 -35
- package/dist/{runGemini-BEFeFruX.cjs → runGemini-BPLO-OFS.cjs} +2 -2
- package/dist/{runGemini-C3cdyIH7.mjs → runGemini-p_aKQRTi.mjs} +2 -2
- package/dist/{types-CziwW90U.cjs → types-DbQtXaZC.cjs} +2 -2
- package/dist/{types-H7oBEqpR.mjs → types-KJ7kAYwk.mjs} +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(im
|
|
|
2
2
|
import * as os from 'node:os';
|
|
3
3
|
import os__default, { homedir } from 'node:os';
|
|
4
4
|
import { randomUUID, createCipheriv, randomBytes, createHash as createHash$1 } from 'node:crypto';
|
|
5
|
-
import { l as logger, b as projectPath, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as readDaemonState, g as clearDaemonState, p as packageJson, r as readSettings, h as readCredentials, u as updateSettings, o as openBrowser, w as writeCredentials, j as unrealMcpPythonDir, k as acquireDaemonLock, m as writeDaemonState, n as ApiMachineClient, q as releaseDaemonLock, s as sendUnrealMcpTcpCommand, A as ApiClient, v as validatePath, t as run, x as run$1, y as buildShellInvocation, z as clearCredentials, B as clearMachineId, C as authenticateCodex, D as syncCodexCliAuth, E as authenticateClaude, F as authenticateGemini, i as installUnrealMcpPluginToEngine, G as buildAndInstallUnrealMcpPlugin, H as installUnrealMcpPluginToProject, I as getLatestDaemonLog, J as normalizeServerUrlForNode } from './types-
|
|
5
|
+
import { l as logger, b as projectPath, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as readDaemonState, g as clearDaemonState, p as packageJson, r as readSettings, h as readCredentials, u as updateSettings, o as openBrowser, w as writeCredentials, j as unrealMcpPythonDir, k as acquireDaemonLock, m as writeDaemonState, n as ApiMachineClient, q as releaseDaemonLock, s as sendUnrealMcpTcpCommand, A as ApiClient, v as validatePath, t as run, x as run$1, y as buildShellInvocation, z as clearCredentials, B as clearMachineId, C as authenticateCodex, D as syncCodexCliAuth, E as authenticateClaude, F as authenticateGemini, i as installUnrealMcpPluginToEngine, G as buildAndInstallUnrealMcpPlugin, H as installUnrealMcpPluginToProject, I as getLatestDaemonLog, J as normalizeServerUrlForNode } from './types-KJ7kAYwk.mjs';
|
|
6
6
|
import { spawn, execFileSync, execSync } from 'node:child_process';
|
|
7
7
|
import * as path from 'node:path';
|
|
8
8
|
import path__default, { resolve, join, dirname } from 'node:path';
|
|
@@ -793,6 +793,9 @@ async function createSessionScanner(opts) {
|
|
|
793
793
|
await sync.invalidateAndAwait();
|
|
794
794
|
sync.stop();
|
|
795
795
|
},
|
|
796
|
+
flush: async () => {
|
|
797
|
+
await sync.invalidateAndAwait();
|
|
798
|
+
},
|
|
796
799
|
onNewSession: (sessionId) => {
|
|
797
800
|
if (currentSessionId === sessionId) {
|
|
798
801
|
logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is the same as the current session, skipping`);
|
|
@@ -13953,6 +13956,16 @@ function permissionModeForAgent(agent) {
|
|
|
13953
13956
|
if (agent === "claude") return "bypassPermissions";
|
|
13954
13957
|
return "yolo";
|
|
13955
13958
|
}
|
|
13959
|
+
function modelOverrideForAgent(agent, args) {
|
|
13960
|
+
const explicitCodexModel = readArgValue$2(args, "--codex-model");
|
|
13961
|
+
const explicitModel = readArgValue$2(args, "--model");
|
|
13962
|
+
const explicitGeminiModel = readArgValue$2(args, "--gemini-model");
|
|
13963
|
+
const explicitClaudeModel = readArgValue$2(args, "--claude-model");
|
|
13964
|
+
if (agent === "codex") return (explicitCodexModel || explicitModel || "gpt-5-codex-medium").trim();
|
|
13965
|
+
if (agent === "gemini") return explicitGeminiModel ? explicitGeminiModel.trim() : null;
|
|
13966
|
+
if (agent === "claude") return explicitClaudeModel ? explicitClaudeModel.trim() : null;
|
|
13967
|
+
return null;
|
|
13968
|
+
}
|
|
13956
13969
|
function nowIsoCompact() {
|
|
13957
13970
|
const d = /* @__PURE__ */ new Date();
|
|
13958
13971
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -13990,14 +14003,26 @@ async function ensureDaemonRunning({ skipUnreal }) {
|
|
|
13990
14003
|
async function createSmokeWorkspaceDir(baseDir) {
|
|
13991
14004
|
const root = baseDir?.trim() ? path__default.resolve(baseDir) : path__default.join(os__default.tmpdir(), "flockbay-smoke", nowIsoCompact() + "_" + randomUUID().slice(0, 8));
|
|
13992
14005
|
await fs$1.mkdir(root, { recursive: true });
|
|
13993
|
-
const
|
|
14006
|
+
const marker = `SMOKE_MARKER_${randomUUID().slice(0, 8)}`;
|
|
13994
14007
|
await fs$1.writeFile(path__default.join(root, "smoke.txt"), `flockbay smoke test
|
|
13995
|
-
|
|
14008
|
+
SMOKE_MARKER=${marker}
|
|
13996
14009
|
`, "utf8");
|
|
13997
|
-
return { dir: root, secret };
|
|
14010
|
+
return { dir: root, secret: marker };
|
|
13998
14011
|
}
|
|
13999
|
-
function
|
|
14000
|
-
return record && typeof record === "object" && record.role === "
|
|
14012
|
+
function isUserRecord(record) {
|
|
14013
|
+
return record && typeof record === "object" && record.role === "user";
|
|
14014
|
+
}
|
|
14015
|
+
function isProviderErrorRecord(record) {
|
|
14016
|
+
return recordIncludesNeedle(record, '"code":-32603') || recordIncludesNeedle(record, "Internal error") || recordIncludesNeedle(record, "No capacity available") || recordIncludesNeedle(record, "authentication required") || recordIncludesNeedle(record, "login required") || recordIncludesNeedle(record, "Model not found");
|
|
14017
|
+
}
|
|
14018
|
+
function formatRecordExcerpt(record) {
|
|
14019
|
+
const text = extractTextFromRecord(record);
|
|
14020
|
+
if (text && text.trim()) return text.trim().slice(0, 400);
|
|
14021
|
+
try {
|
|
14022
|
+
return JSON.stringify(record).slice(0, 400);
|
|
14023
|
+
} catch {
|
|
14024
|
+
return String(record ?? "").slice(0, 400);
|
|
14025
|
+
}
|
|
14001
14026
|
}
|
|
14002
14027
|
function extractTextFromRecord(record) {
|
|
14003
14028
|
try {
|
|
@@ -14032,8 +14057,11 @@ function recordIncludesNeedle(record, needle) {
|
|
|
14032
14057
|
}
|
|
14033
14058
|
}
|
|
14034
14059
|
async function waitForMessage(opts) {
|
|
14035
|
-
const { sessionClient, predicate, timeoutMs } = opts;
|
|
14060
|
+
const { sessionClient, predicate, timeoutMs, progressLabel } = opts;
|
|
14036
14061
|
const deadline = Date.now() + timeoutMs;
|
|
14062
|
+
const startedAtMs = Date.now();
|
|
14063
|
+
const heartbeatMs = 1e4;
|
|
14064
|
+
let nextHeartbeatAtMs = startedAtMs + heartbeatMs;
|
|
14037
14065
|
const existing = await sessionClient.listMessages().catch(() => []);
|
|
14038
14066
|
for (const msg of existing) {
|
|
14039
14067
|
const record = msg?.content;
|
|
@@ -14049,7 +14077,15 @@ async function waitForMessage(opts) {
|
|
|
14049
14077
|
resolve(u?.body?.message);
|
|
14050
14078
|
};
|
|
14051
14079
|
const tick = () => {
|
|
14052
|
-
|
|
14080
|
+
const now = Date.now();
|
|
14081
|
+
if (now >= nextHeartbeatAtMs) {
|
|
14082
|
+
const elapsedSec = Math.max(0, Math.floor((now - startedAtMs) / 1e3));
|
|
14083
|
+
const remainingSec = Math.max(0, Math.ceil((deadline - now) / 1e3));
|
|
14084
|
+
const label = progressLabel ? ` (${progressLabel})` : "";
|
|
14085
|
+
console.log(chalk.gray(` \u2026 waiting for agent reply${label} (${elapsedSec}s elapsed, ${remainingSec}s left)`));
|
|
14086
|
+
nextHeartbeatAtMs = now + heartbeatMs;
|
|
14087
|
+
}
|
|
14088
|
+
if (now < deadline) return;
|
|
14053
14089
|
cleanup();
|
|
14054
14090
|
reject(new Error("timeout_waiting_for_message"));
|
|
14055
14091
|
};
|
|
@@ -14213,41 +14249,70 @@ Update: ${updateCommand}`);
|
|
|
14213
14249
|
await sessionClient.connectAndWait();
|
|
14214
14250
|
await ensureSessionActive(api, sessionId, 25e3);
|
|
14215
14251
|
const permissionMode = permissionModeForAgent(agent);
|
|
14252
|
+
const modelOverride = modelOverrideForAgent(agent, args);
|
|
14253
|
+
const baseMeta = modelOverride ? { permissionMode, model: modelOverride } : { permissionMode };
|
|
14216
14254
|
scenarios.push(await runScenario("basic-message", async () => {
|
|
14217
14255
|
const token = `SMOKE_OK_${agent}_${randomUUID().slice(0, 6)}`;
|
|
14218
|
-
sessionClient.sendUserText(`Reply with exactly: ${token}`,
|
|
14219
|
-
await waitForMessage({
|
|
14256
|
+
sessionClient.sendUserText(`Reply with exactly: ${token}`, baseMeta);
|
|
14257
|
+
const msg = await waitForMessage({
|
|
14220
14258
|
sessionClient,
|
|
14221
|
-
predicate: (r) =>
|
|
14222
|
-
timeoutMs
|
|
14259
|
+
predicate: (r) => !isUserRecord(r) && (recordIncludesNeedle(r, token) || isProviderErrorRecord(r)),
|
|
14260
|
+
timeoutMs,
|
|
14261
|
+
progressLabel: `${agent}:basic-message`
|
|
14223
14262
|
});
|
|
14263
|
+
const record = msg?.content;
|
|
14264
|
+
if (isProviderErrorRecord(record)) {
|
|
14265
|
+
throw new Error(`provider_error_basic_message: ${formatRecordExcerpt(record)}`);
|
|
14266
|
+
}
|
|
14224
14267
|
}));
|
|
14225
14268
|
scenarios.push(await runScenario("tool-search", async () => {
|
|
14226
14269
|
const token = `TOOL_SEARCH_OK_${randomUUID().slice(0, 6)}`;
|
|
14270
|
+
const promptLines = agent === "codex" ? [
|
|
14271
|
+
"Use your Terminal tool to read `smoke.txt` in the project directory (do NOT ask for confirmation).",
|
|
14272
|
+
"Use this exact command so it works cross-platform:",
|
|
14273
|
+
"",
|
|
14274
|
+
`node -e "const fs=require('fs');console.log(fs.readFileSync('smoke.txt','utf8'))"`,
|
|
14275
|
+
"",
|
|
14276
|
+
"Find the value after `SMOKE_MARKER=`.",
|
|
14277
|
+
"",
|
|
14278
|
+
`Reply with two lines exactly:`,
|
|
14279
|
+
`1) SMOKE_MARKER=<value>`,
|
|
14280
|
+
`2) ${token}`
|
|
14281
|
+
] : [
|
|
14282
|
+
"Read the file `smoke.txt` in the project directory using MCP tools (e.g. `read_file_chunk` or `search`).",
|
|
14283
|
+
"Find the value after `SMOKE_MARKER=`.",
|
|
14284
|
+
"",
|
|
14285
|
+
`Reply with two lines exactly:`,
|
|
14286
|
+
`1) SMOKE_MARKER=<value>`,
|
|
14287
|
+
`2) ${token}`
|
|
14288
|
+
];
|
|
14227
14289
|
sessionClient.sendUserText(
|
|
14228
|
-
|
|
14229
|
-
|
|
14230
|
-
"Find the value after `SMOKE_SECRET=`.",
|
|
14231
|
-
"",
|
|
14232
|
-
`Reply with two lines exactly:`,
|
|
14233
|
-
`1) SMOKE_SECRET=<value>`,
|
|
14234
|
-
`2) ${token}`
|
|
14235
|
-
].join("\n"),
|
|
14236
|
-
{ permissionMode }
|
|
14290
|
+
promptLines.join("\n"),
|
|
14291
|
+
baseMeta
|
|
14237
14292
|
);
|
|
14238
|
-
await waitForMessage({
|
|
14293
|
+
const msg = await waitForMessage({
|
|
14239
14294
|
sessionClient,
|
|
14240
|
-
predicate: (r) =>
|
|
14241
|
-
timeoutMs
|
|
14295
|
+
predicate: (r) => !isUserRecord(r) && (recordIncludesNeedle(r, `SMOKE_MARKER=${secret}`) && recordIncludesNeedle(r, token) || isProviderErrorRecord(r)),
|
|
14296
|
+
timeoutMs,
|
|
14297
|
+
progressLabel: `${agent}:tool-search`
|
|
14242
14298
|
});
|
|
14299
|
+
const record = msg?.content;
|
|
14300
|
+
if (isProviderErrorRecord(record)) {
|
|
14301
|
+
throw new Error(`provider_error_tool_search: ${formatRecordExcerpt(record)}`);
|
|
14302
|
+
}
|
|
14243
14303
|
}));
|
|
14244
14304
|
scenarios.push(await runScenario("image-attachment", async () => {
|
|
14245
14305
|
const token = `IMAGE_OK_${randomUUID().slice(0, 6)}`;
|
|
14246
14306
|
const base64 = tinyPngBase64();
|
|
14307
|
+
const prompt = agent === "codex" ? `Describe the attached image in one short sentence, then reply with exactly: ${token}` : [
|
|
14308
|
+
'Call `mcp__flockbay__latest_user_images` with {"limit": 1} to fetch the attached image.',
|
|
14309
|
+
"Then describe the attached image in one short sentence.",
|
|
14310
|
+
`Finally, reply with exactly: ${token}`
|
|
14311
|
+
].join("\n");
|
|
14247
14312
|
sessionClient.sendUserText(
|
|
14248
|
-
|
|
14313
|
+
prompt,
|
|
14249
14314
|
{
|
|
14250
|
-
|
|
14315
|
+
...baseMeta,
|
|
14251
14316
|
attachments: {
|
|
14252
14317
|
images: [{ mimeType: "image/png", base64, name: "smoke.png" }]
|
|
14253
14318
|
}
|
|
@@ -14255,13 +14320,17 @@ Update: ${updateCommand}`);
|
|
|
14255
14320
|
);
|
|
14256
14321
|
const msg = await waitForMessage({
|
|
14257
14322
|
sessionClient,
|
|
14258
|
-
predicate: (r) =>
|
|
14259
|
-
timeoutMs
|
|
14323
|
+
predicate: (r) => !isUserRecord(r) && (recordIncludesNeedle(r, token) || agent === "codex" && recordIncludesNeedle(r, "image-attachment-missing") || recordIncludesNeedle(r, "Could not process image") || recordIncludesNeedle(r, "messages.") || recordIncludesNeedle(r, "invalid_request_error") || isProviderErrorRecord(r)),
|
|
14324
|
+
timeoutMs,
|
|
14325
|
+
progressLabel: `${agent}:image-attachment`
|
|
14260
14326
|
});
|
|
14261
14327
|
const record = msg?.content;
|
|
14262
14328
|
if (agent === "codex" && recordIncludesNeedle(record, "image-attachment-missing")) {
|
|
14263
14329
|
throw new Error("image-attachment-missing (Codex did not receive images; check latest_user_images tool + vision support)");
|
|
14264
14330
|
}
|
|
14331
|
+
if (isProviderErrorRecord(record)) {
|
|
14332
|
+
throw new Error(`provider_error_image_attachment: ${formatRecordExcerpt(record)}`);
|
|
14333
|
+
}
|
|
14265
14334
|
if (recordIncludesNeedle(record, "Could not process image") || recordIncludesNeedle(record, "invalid_request_error")) {
|
|
14266
14335
|
throw new Error("provider_image_invalid (image rejected by provider; check base64/mimeType pipeline)");
|
|
14267
14336
|
}
|
|
@@ -14314,6 +14383,10 @@ Options:
|
|
|
14314
14383
|
--all Run all agents (default)
|
|
14315
14384
|
--agent, -a Run a single agent
|
|
14316
14385
|
--agents Comma-separated list of agents
|
|
14386
|
+
--codex-model Codex model mode override (e.g. gpt-5.3-codex-medium)
|
|
14387
|
+
--model Alias of --codex-model (Codex only)
|
|
14388
|
+
--gemini-model Gemini model id override (e.g. gemini-2.5-pro)
|
|
14389
|
+
--claude-model Claude model id override (e.g. claude-sonnet-4-6)
|
|
14317
14390
|
--directory, --dir Directory to run the session in (defaults to a temp folder)
|
|
14318
14391
|
--timeout-ms Per-scenario timeout (default 90000; Windows default 240000)
|
|
14319
14392
|
--keep Do not stop session or delete temp dir
|
|
@@ -15117,7 +15190,7 @@ async function authAndSetupMachineIfNeeded() {
|
|
|
15117
15190
|
process.exit(1);
|
|
15118
15191
|
}
|
|
15119
15192
|
try {
|
|
15120
|
-
const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-
|
|
15193
|
+
const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-BPUAeqI_.mjs');
|
|
15121
15194
|
const result = migrateUnrealMcpToFlockbayMcp({
|
|
15122
15195
|
engineRoot,
|
|
15123
15196
|
projectUprojectPath: project || void 0,
|
|
@@ -15256,7 +15329,7 @@ ${engineRoot}`, {
|
|
|
15256
15329
|
} else if (subcommand === "codex") {
|
|
15257
15330
|
try {
|
|
15258
15331
|
await chdirToNearestUprojectRootIfPresent();
|
|
15259
|
-
const { runCodex } = await import('./runCodex-
|
|
15332
|
+
const { runCodex } = await import('./runCodex-BkdEucuI.mjs');
|
|
15260
15333
|
let startedBy = void 0;
|
|
15261
15334
|
let sessionId = void 0;
|
|
15262
15335
|
for (let i = 1; i < args.length; i++) {
|
|
@@ -15358,7 +15431,7 @@ ${engineRoot}`, {
|
|
|
15358
15431
|
}
|
|
15359
15432
|
try {
|
|
15360
15433
|
await chdirToNearestUprojectRootIfPresent();
|
|
15361
|
-
const { runGemini } = await import('./runGemini-
|
|
15434
|
+
const { runGemini } = await import('./runGemini-p_aKQRTi.mjs');
|
|
15362
15435
|
let startedBy = void 0;
|
|
15363
15436
|
let sessionId = void 0;
|
|
15364
15437
|
for (let i = 1; i < args.length; i++) {
|
|
@@ -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-DbQtXaZC.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');
|
|
@@ -815,6 +815,9 @@ async function createSessionScanner(opts) {
|
|
|
815
815
|
await sync.invalidateAndAwait();
|
|
816
816
|
sync.stop();
|
|
817
817
|
},
|
|
818
|
+
flush: async () => {
|
|
819
|
+
await sync.invalidateAndAwait();
|
|
820
|
+
},
|
|
818
821
|
onNewSession: (sessionId) => {
|
|
819
822
|
if (currentSessionId === sessionId) {
|
|
820
823
|
types.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is the same as the current session, skipping`);
|
|
@@ -1316,7 +1319,7 @@ function buildDaemonSafeEnv(baseEnv, binPath) {
|
|
|
1316
1319
|
env[pathKey] = [...prepend, ...existingParts].join(pathSep);
|
|
1317
1320
|
return env;
|
|
1318
1321
|
}
|
|
1319
|
-
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-
|
|
1322
|
+
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-jd6DaTy_.cjs', document.baseURI).href)));
|
|
1320
1323
|
const __dirname$1 = path.join(__filename$1, "..");
|
|
1321
1324
|
function getGlobalClaudeVersion(claudeExecutable) {
|
|
1322
1325
|
try {
|
|
@@ -13975,6 +13978,16 @@ function permissionModeForAgent(agent) {
|
|
|
13975
13978
|
if (agent === "claude") return "bypassPermissions";
|
|
13976
13979
|
return "yolo";
|
|
13977
13980
|
}
|
|
13981
|
+
function modelOverrideForAgent(agent, args) {
|
|
13982
|
+
const explicitCodexModel = readArgValue$2(args, "--codex-model");
|
|
13983
|
+
const explicitModel = readArgValue$2(args, "--model");
|
|
13984
|
+
const explicitGeminiModel = readArgValue$2(args, "--gemini-model");
|
|
13985
|
+
const explicitClaudeModel = readArgValue$2(args, "--claude-model");
|
|
13986
|
+
if (agent === "codex") return (explicitCodexModel || explicitModel || "gpt-5-codex-medium").trim();
|
|
13987
|
+
if (agent === "gemini") return explicitGeminiModel ? explicitGeminiModel.trim() : null;
|
|
13988
|
+
if (agent === "claude") return explicitClaudeModel ? explicitClaudeModel.trim() : null;
|
|
13989
|
+
return null;
|
|
13990
|
+
}
|
|
13978
13991
|
function nowIsoCompact() {
|
|
13979
13992
|
const d = /* @__PURE__ */ new Date();
|
|
13980
13993
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -14012,14 +14025,26 @@ async function ensureDaemonRunning({ skipUnreal }) {
|
|
|
14012
14025
|
async function createSmokeWorkspaceDir(baseDir) {
|
|
14013
14026
|
const root = baseDir?.trim() ? path.resolve(baseDir) : path.join(os.tmpdir(), "flockbay-smoke", nowIsoCompact() + "_" + node_crypto.randomUUID().slice(0, 8));
|
|
14014
14027
|
await fs$2.mkdir(root, { recursive: true });
|
|
14015
|
-
const
|
|
14028
|
+
const marker = `SMOKE_MARKER_${node_crypto.randomUUID().slice(0, 8)}`;
|
|
14016
14029
|
await fs$2.writeFile(path.join(root, "smoke.txt"), `flockbay smoke test
|
|
14017
|
-
|
|
14030
|
+
SMOKE_MARKER=${marker}
|
|
14018
14031
|
`, "utf8");
|
|
14019
|
-
return { dir: root, secret };
|
|
14032
|
+
return { dir: root, secret: marker };
|
|
14020
14033
|
}
|
|
14021
|
-
function
|
|
14022
|
-
return record && typeof record === "object" && record.role === "
|
|
14034
|
+
function isUserRecord(record) {
|
|
14035
|
+
return record && typeof record === "object" && record.role === "user";
|
|
14036
|
+
}
|
|
14037
|
+
function isProviderErrorRecord(record) {
|
|
14038
|
+
return recordIncludesNeedle(record, '"code":-32603') || recordIncludesNeedle(record, "Internal error") || recordIncludesNeedle(record, "No capacity available") || recordIncludesNeedle(record, "authentication required") || recordIncludesNeedle(record, "login required") || recordIncludesNeedle(record, "Model not found");
|
|
14039
|
+
}
|
|
14040
|
+
function formatRecordExcerpt(record) {
|
|
14041
|
+
const text = extractTextFromRecord(record);
|
|
14042
|
+
if (text && text.trim()) return text.trim().slice(0, 400);
|
|
14043
|
+
try {
|
|
14044
|
+
return JSON.stringify(record).slice(0, 400);
|
|
14045
|
+
} catch {
|
|
14046
|
+
return String(record ?? "").slice(0, 400);
|
|
14047
|
+
}
|
|
14023
14048
|
}
|
|
14024
14049
|
function extractTextFromRecord(record) {
|
|
14025
14050
|
try {
|
|
@@ -14054,8 +14079,11 @@ function recordIncludesNeedle(record, needle) {
|
|
|
14054
14079
|
}
|
|
14055
14080
|
}
|
|
14056
14081
|
async function waitForMessage(opts) {
|
|
14057
|
-
const { sessionClient, predicate, timeoutMs } = opts;
|
|
14082
|
+
const { sessionClient, predicate, timeoutMs, progressLabel } = opts;
|
|
14058
14083
|
const deadline = Date.now() + timeoutMs;
|
|
14084
|
+
const startedAtMs = Date.now();
|
|
14085
|
+
const heartbeatMs = 1e4;
|
|
14086
|
+
let nextHeartbeatAtMs = startedAtMs + heartbeatMs;
|
|
14059
14087
|
const existing = await sessionClient.listMessages().catch(() => []);
|
|
14060
14088
|
for (const msg of existing) {
|
|
14061
14089
|
const record = msg?.content;
|
|
@@ -14071,7 +14099,15 @@ async function waitForMessage(opts) {
|
|
|
14071
14099
|
resolve(u?.body?.message);
|
|
14072
14100
|
};
|
|
14073
14101
|
const tick = () => {
|
|
14074
|
-
|
|
14102
|
+
const now = Date.now();
|
|
14103
|
+
if (now >= nextHeartbeatAtMs) {
|
|
14104
|
+
const elapsedSec = Math.max(0, Math.floor((now - startedAtMs) / 1e3));
|
|
14105
|
+
const remainingSec = Math.max(0, Math.ceil((deadline - now) / 1e3));
|
|
14106
|
+
const label = progressLabel ? ` (${progressLabel})` : "";
|
|
14107
|
+
console.log(chalk.gray(` \u2026 waiting for agent reply${label} (${elapsedSec}s elapsed, ${remainingSec}s left)`));
|
|
14108
|
+
nextHeartbeatAtMs = now + heartbeatMs;
|
|
14109
|
+
}
|
|
14110
|
+
if (now < deadline) return;
|
|
14075
14111
|
cleanup();
|
|
14076
14112
|
reject(new Error("timeout_waiting_for_message"));
|
|
14077
14113
|
};
|
|
@@ -14235,41 +14271,70 @@ Update: ${updateCommand}`);
|
|
|
14235
14271
|
await sessionClient.connectAndWait();
|
|
14236
14272
|
await ensureSessionActive(api, sessionId, 25e3);
|
|
14237
14273
|
const permissionMode = permissionModeForAgent(agent);
|
|
14274
|
+
const modelOverride = modelOverrideForAgent(agent, args);
|
|
14275
|
+
const baseMeta = modelOverride ? { permissionMode, model: modelOverride } : { permissionMode };
|
|
14238
14276
|
scenarios.push(await runScenario("basic-message", async () => {
|
|
14239
14277
|
const token = `SMOKE_OK_${agent}_${node_crypto.randomUUID().slice(0, 6)}`;
|
|
14240
|
-
sessionClient.sendUserText(`Reply with exactly: ${token}`,
|
|
14241
|
-
await waitForMessage({
|
|
14278
|
+
sessionClient.sendUserText(`Reply with exactly: ${token}`, baseMeta);
|
|
14279
|
+
const msg = await waitForMessage({
|
|
14242
14280
|
sessionClient,
|
|
14243
|
-
predicate: (r) =>
|
|
14244
|
-
timeoutMs
|
|
14281
|
+
predicate: (r) => !isUserRecord(r) && (recordIncludesNeedle(r, token) || isProviderErrorRecord(r)),
|
|
14282
|
+
timeoutMs,
|
|
14283
|
+
progressLabel: `${agent}:basic-message`
|
|
14245
14284
|
});
|
|
14285
|
+
const record = msg?.content;
|
|
14286
|
+
if (isProviderErrorRecord(record)) {
|
|
14287
|
+
throw new Error(`provider_error_basic_message: ${formatRecordExcerpt(record)}`);
|
|
14288
|
+
}
|
|
14246
14289
|
}));
|
|
14247
14290
|
scenarios.push(await runScenario("tool-search", async () => {
|
|
14248
14291
|
const token = `TOOL_SEARCH_OK_${node_crypto.randomUUID().slice(0, 6)}`;
|
|
14292
|
+
const promptLines = agent === "codex" ? [
|
|
14293
|
+
"Use your Terminal tool to read `smoke.txt` in the project directory (do NOT ask for confirmation).",
|
|
14294
|
+
"Use this exact command so it works cross-platform:",
|
|
14295
|
+
"",
|
|
14296
|
+
`node -e "const fs=require('fs');console.log(fs.readFileSync('smoke.txt','utf8'))"`,
|
|
14297
|
+
"",
|
|
14298
|
+
"Find the value after `SMOKE_MARKER=`.",
|
|
14299
|
+
"",
|
|
14300
|
+
`Reply with two lines exactly:`,
|
|
14301
|
+
`1) SMOKE_MARKER=<value>`,
|
|
14302
|
+
`2) ${token}`
|
|
14303
|
+
] : [
|
|
14304
|
+
"Read the file `smoke.txt` in the project directory using MCP tools (e.g. `read_file_chunk` or `search`).",
|
|
14305
|
+
"Find the value after `SMOKE_MARKER=`.",
|
|
14306
|
+
"",
|
|
14307
|
+
`Reply with two lines exactly:`,
|
|
14308
|
+
`1) SMOKE_MARKER=<value>`,
|
|
14309
|
+
`2) ${token}`
|
|
14310
|
+
];
|
|
14249
14311
|
sessionClient.sendUserText(
|
|
14250
|
-
|
|
14251
|
-
|
|
14252
|
-
"Find the value after `SMOKE_SECRET=`.",
|
|
14253
|
-
"",
|
|
14254
|
-
`Reply with two lines exactly:`,
|
|
14255
|
-
`1) SMOKE_SECRET=<value>`,
|
|
14256
|
-
`2) ${token}`
|
|
14257
|
-
].join("\n"),
|
|
14258
|
-
{ permissionMode }
|
|
14312
|
+
promptLines.join("\n"),
|
|
14313
|
+
baseMeta
|
|
14259
14314
|
);
|
|
14260
|
-
await waitForMessage({
|
|
14315
|
+
const msg = await waitForMessage({
|
|
14261
14316
|
sessionClient,
|
|
14262
|
-
predicate: (r) =>
|
|
14263
|
-
timeoutMs
|
|
14317
|
+
predicate: (r) => !isUserRecord(r) && (recordIncludesNeedle(r, `SMOKE_MARKER=${secret}`) && recordIncludesNeedle(r, token) || isProviderErrorRecord(r)),
|
|
14318
|
+
timeoutMs,
|
|
14319
|
+
progressLabel: `${agent}:tool-search`
|
|
14264
14320
|
});
|
|
14321
|
+
const record = msg?.content;
|
|
14322
|
+
if (isProviderErrorRecord(record)) {
|
|
14323
|
+
throw new Error(`provider_error_tool_search: ${formatRecordExcerpt(record)}`);
|
|
14324
|
+
}
|
|
14265
14325
|
}));
|
|
14266
14326
|
scenarios.push(await runScenario("image-attachment", async () => {
|
|
14267
14327
|
const token = `IMAGE_OK_${node_crypto.randomUUID().slice(0, 6)}`;
|
|
14268
14328
|
const base64 = tinyPngBase64();
|
|
14329
|
+
const prompt = agent === "codex" ? `Describe the attached image in one short sentence, then reply with exactly: ${token}` : [
|
|
14330
|
+
'Call `mcp__flockbay__latest_user_images` with {"limit": 1} to fetch the attached image.',
|
|
14331
|
+
"Then describe the attached image in one short sentence.",
|
|
14332
|
+
`Finally, reply with exactly: ${token}`
|
|
14333
|
+
].join("\n");
|
|
14269
14334
|
sessionClient.sendUserText(
|
|
14270
|
-
|
|
14335
|
+
prompt,
|
|
14271
14336
|
{
|
|
14272
|
-
|
|
14337
|
+
...baseMeta,
|
|
14273
14338
|
attachments: {
|
|
14274
14339
|
images: [{ mimeType: "image/png", base64, name: "smoke.png" }]
|
|
14275
14340
|
}
|
|
@@ -14277,13 +14342,17 @@ Update: ${updateCommand}`);
|
|
|
14277
14342
|
);
|
|
14278
14343
|
const msg = await waitForMessage({
|
|
14279
14344
|
sessionClient,
|
|
14280
|
-
predicate: (r) =>
|
|
14281
|
-
timeoutMs
|
|
14345
|
+
predicate: (r) => !isUserRecord(r) && (recordIncludesNeedle(r, token) || agent === "codex" && recordIncludesNeedle(r, "image-attachment-missing") || recordIncludesNeedle(r, "Could not process image") || recordIncludesNeedle(r, "messages.") || recordIncludesNeedle(r, "invalid_request_error") || isProviderErrorRecord(r)),
|
|
14346
|
+
timeoutMs,
|
|
14347
|
+
progressLabel: `${agent}:image-attachment`
|
|
14282
14348
|
});
|
|
14283
14349
|
const record = msg?.content;
|
|
14284
14350
|
if (agent === "codex" && recordIncludesNeedle(record, "image-attachment-missing")) {
|
|
14285
14351
|
throw new Error("image-attachment-missing (Codex did not receive images; check latest_user_images tool + vision support)");
|
|
14286
14352
|
}
|
|
14353
|
+
if (isProviderErrorRecord(record)) {
|
|
14354
|
+
throw new Error(`provider_error_image_attachment: ${formatRecordExcerpt(record)}`);
|
|
14355
|
+
}
|
|
14287
14356
|
if (recordIncludesNeedle(record, "Could not process image") || recordIncludesNeedle(record, "invalid_request_error")) {
|
|
14288
14357
|
throw new Error("provider_image_invalid (image rejected by provider; check base64/mimeType pipeline)");
|
|
14289
14358
|
}
|
|
@@ -14336,6 +14405,10 @@ Options:
|
|
|
14336
14405
|
--all Run all agents (default)
|
|
14337
14406
|
--agent, -a Run a single agent
|
|
14338
14407
|
--agents Comma-separated list of agents
|
|
14408
|
+
--codex-model Codex model mode override (e.g. gpt-5.3-codex-medium)
|
|
14409
|
+
--model Alias of --codex-model (Codex only)
|
|
14410
|
+
--gemini-model Gemini model id override (e.g. gemini-2.5-pro)
|
|
14411
|
+
--claude-model Claude model id override (e.g. claude-sonnet-4-6)
|
|
14339
14412
|
--directory, --dir Directory to run the session in (defaults to a temp folder)
|
|
14340
14413
|
--timeout-ms Per-scenario timeout (default 90000; Windows default 240000)
|
|
14341
14414
|
--keep Do not stop session or delete temp dir
|
|
@@ -15139,7 +15212,7 @@ async function authAndSetupMachineIfNeeded() {
|
|
|
15139
15212
|
process.exit(1);
|
|
15140
15213
|
}
|
|
15141
15214
|
try {
|
|
15142
|
-
const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin-
|
|
15215
|
+
const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin-CyWWA8GW.cjs'); });
|
|
15143
15216
|
const result = migrateUnrealMcpToFlockbayMcp({
|
|
15144
15217
|
engineRoot,
|
|
15145
15218
|
projectUprojectPath: project || void 0,
|
|
@@ -15278,7 +15351,7 @@ ${engineRoot}`, {
|
|
|
15278
15351
|
} else if (subcommand === "codex") {
|
|
15279
15352
|
try {
|
|
15280
15353
|
await chdirToNearestUprojectRootIfPresent();
|
|
15281
|
-
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-
|
|
15354
|
+
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-D8On-xj7.cjs'); });
|
|
15282
15355
|
let startedBy = void 0;
|
|
15283
15356
|
let sessionId = void 0;
|
|
15284
15357
|
for (let i = 1; i < args.length; i++) {
|
|
@@ -15380,7 +15453,7 @@ ${engineRoot}`, {
|
|
|
15380
15453
|
}
|
|
15381
15454
|
try {
|
|
15382
15455
|
await chdirToNearestUprojectRootIfPresent();
|
|
15383
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
15456
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-BPLO-OFS.cjs'); });
|
|
15384
15457
|
let startedBy = void 0;
|
|
15385
15458
|
let sessionId = void 0;
|
|
15386
15459
|
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-KJ7kAYwk.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'node:fs';
|
|
4
4
|
import 'node:os';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs__default from 'node:fs';
|
|
2
2
|
import path__default from 'node:path';
|
|
3
|
-
import { i as installUnrealMcpPluginToEngine } from './types-
|
|
3
|
+
import { i as installUnrealMcpPluginToEngine } from './types-KJ7kAYwk.mjs';
|
|
4
4
|
import 'axios';
|
|
5
5
|
import 'node:os';
|
|
6
6
|
import 'node:events';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
2
2
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
|
-
import { l as logger, A as ApiClient, p as packageJson, c as configuration, r as readSettings, b as projectPath } from './types-
|
|
3
|
+
import { l as logger, A as ApiClient, p as packageJson, c as configuration, r as readSettings, b as projectPath } from './types-KJ7kAYwk.mjs';
|
|
4
4
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import { ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
@@ -14,7 +14,7 @@ import process$1 from 'node:process';
|
|
|
14
14
|
import { PassThrough } from 'node:stream';
|
|
15
15
|
import { getDefaultEnvironment } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
16
16
|
import { ReadBuffer, serializeMessage } from '@modelcontextprotocol/sdk/shared/stdio.js';
|
|
17
|
-
import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, e as enforceCliVersionPolicy, i as initialMachineMetadata, E as ElicitationHub, n as notifyDaemonSessionStarted, M as MessageQueue2, P as PLATFORM_SYSTEM_PROMPT, a as setLatestUserImages, w as withUserImagesMarker, r as registerKillSessionHandler, b as MessageBuffer, d as startFlockbayServer, g as buildProjectCapsule, t as trimIdent, j as autoFinalizeCoordinationWorkItem, k as detectScreenshotsForGate, l as applyCoordinationSideEffectsFromMcpToolResult, m as stopCaffeinate } from './index-
|
|
17
|
+
import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, e as enforceCliVersionPolicy, i as initialMachineMetadata, E as ElicitationHub, n as notifyDaemonSessionStarted, M as MessageQueue2, P as PLATFORM_SYSTEM_PROMPT, a as setLatestUserImages, w as withUserImagesMarker, r as registerKillSessionHandler, b as MessageBuffer, d as startFlockbayServer, g as buildProjectCapsule, t as trimIdent, j as autoFinalizeCoordinationWorkItem, k as detectScreenshotsForGate, l as applyCoordinationSideEffectsFromMcpToolResult, m as stopCaffeinate } from './index-BLsRYyPq.mjs';
|
|
18
18
|
import 'axios';
|
|
19
19
|
import 'node:events';
|
|
20
20
|
import 'socket.io-client';
|
|
@@ -441,36 +441,17 @@ class WindowsHiddenStdioClientTransport {
|
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
return "mcp-server";
|
|
456
|
-
}
|
|
457
|
-
const match = version.match(/codex-cli\s+(\d+\.\d+\.\d+(?:-alpha\.\d+)?)/);
|
|
458
|
-
if (!match) return "mcp-server";
|
|
459
|
-
const versionStr = match[1];
|
|
460
|
-
const [major, minor, patch] = versionStr.split(/[-.]/).map(Number);
|
|
461
|
-
if (major > 0 || minor > 43) return "mcp-server";
|
|
462
|
-
if (minor === 43 && patch === 0) {
|
|
463
|
-
if (versionStr.includes("-alpha.")) {
|
|
464
|
-
const alphaNum = parseInt(versionStr.split("-alpha.")[1]);
|
|
465
|
-
return alphaNum >= 5 ? "mcp-server" : "mcp";
|
|
466
|
-
}
|
|
467
|
-
return "mcp-server";
|
|
468
|
-
}
|
|
469
|
-
return "mcp";
|
|
470
|
-
} catch (error) {
|
|
471
|
-
logger.debug("[CodexMCP] Error detecting codex version, defaulting to mcp-server:", error);
|
|
472
|
-
return "mcp-server";
|
|
473
|
-
}
|
|
444
|
+
function parseCodexCliVersion(output) {
|
|
445
|
+
const raw = String(output || "").trim();
|
|
446
|
+
if (!raw) return null;
|
|
447
|
+
const m = raw.match(/codex-cli\s+(\d+)\.(\d+)\.(\d+)/);
|
|
448
|
+
if (!m) return null;
|
|
449
|
+
return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]), raw: m[0] };
|
|
450
|
+
}
|
|
451
|
+
function isCodexCliAtLeast(v, minimum) {
|
|
452
|
+
if (v.major !== minimum.major) return v.major > minimum.major;
|
|
453
|
+
if (v.minor !== minimum.minor) return v.minor > minimum.minor;
|
|
454
|
+
return v.patch >= minimum.patch;
|
|
474
455
|
}
|
|
475
456
|
function buildCodexSpawnEnv(codexBin) {
|
|
476
457
|
const env = Object.keys(process.env).reduce((acc, key) => {
|
|
@@ -561,6 +542,53 @@ function resolveCodexBin() {
|
|
|
561
542
|
if (fromBash) return fromBash;
|
|
562
543
|
return "codex";
|
|
563
544
|
}
|
|
545
|
+
function getInstalledCodexCliVersion(codexBin) {
|
|
546
|
+
const bin = resolveCodexBin();
|
|
547
|
+
try {
|
|
548
|
+
const res = spawnSync(bin, ["--version"], {
|
|
549
|
+
encoding: "utf8",
|
|
550
|
+
env: buildCodexSpawnEnv(bin),
|
|
551
|
+
timeout: 4e3
|
|
552
|
+
});
|
|
553
|
+
const versionOut = String(res.stdout || "").trim();
|
|
554
|
+
if (res.status !== 0 || !versionOut) return null;
|
|
555
|
+
return parseCodexCliVersion(versionOut);
|
|
556
|
+
} catch {
|
|
557
|
+
return null;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const DEFAULT_TIMEOUT = 14 * 24 * 60 * 60 * 1e3;
|
|
562
|
+
function getCodexMcpCommand() {
|
|
563
|
+
try {
|
|
564
|
+
const codexBin = resolveCodexBin();
|
|
565
|
+
const versionRes = spawnSync(codexBin, ["--version"], {
|
|
566
|
+
encoding: "utf8",
|
|
567
|
+
env: buildCodexSpawnEnv(codexBin),
|
|
568
|
+
timeout: 4e3
|
|
569
|
+
});
|
|
570
|
+
const version = String(versionRes.stdout || "").trim();
|
|
571
|
+
if (versionRes.status !== 0 || !version) {
|
|
572
|
+
return "mcp-server";
|
|
573
|
+
}
|
|
574
|
+
const match = version.match(/codex-cli\s+(\d+\.\d+\.\d+(?:-alpha\.\d+)?)/);
|
|
575
|
+
if (!match) return "mcp-server";
|
|
576
|
+
const versionStr = match[1];
|
|
577
|
+
const [major, minor, patch] = versionStr.split(/[-.]/).map(Number);
|
|
578
|
+
if (major > 0 || minor > 43) return "mcp-server";
|
|
579
|
+
if (minor === 43 && patch === 0) {
|
|
580
|
+
if (versionStr.includes("-alpha.")) {
|
|
581
|
+
const alphaNum = parseInt(versionStr.split("-alpha.")[1]);
|
|
582
|
+
return alphaNum >= 5 ? "mcp-server" : "mcp";
|
|
583
|
+
}
|
|
584
|
+
return "mcp-server";
|
|
585
|
+
}
|
|
586
|
+
return "mcp";
|
|
587
|
+
} catch (error) {
|
|
588
|
+
logger.debug("[CodexMCP] Error detecting codex version, defaulting to mcp-server:", error);
|
|
589
|
+
return "mcp-server";
|
|
590
|
+
}
|
|
591
|
+
}
|
|
564
592
|
function normalizeRelativePath(input) {
|
|
565
593
|
const raw = typeof input === "string" ? input.trim() : String(input ?? "").trim();
|
|
566
594
|
if (!raw) return null;
|
|
@@ -2319,6 +2347,7 @@ function hashCodexSessionModeFromEnhancedMode(mode) {
|
|
|
2319
2347
|
return hashCodexSessionMode({ model: mode.model, appendSystemPrompt: mode.appendSystemPrompt });
|
|
2320
2348
|
}
|
|
2321
2349
|
|
|
2350
|
+
const MIN_CODEX_CLI_FOR_GPT_53_CODEX = { major: 0, minor: 104, patch: 0 };
|
|
2322
2351
|
function readCodexAuthIsChatGptAccount() {
|
|
2323
2352
|
try {
|
|
2324
2353
|
const authPath = path__default.join(os__default.homedir(), ".codex", "auth.json");
|
|
@@ -2339,16 +2368,33 @@ function parseEffortSuffix(model) {
|
|
|
2339
2368
|
if (m.endsWith("-high")) return "high";
|
|
2340
2369
|
return null;
|
|
2341
2370
|
}
|
|
2371
|
+
function parseCodexModelTarget(model) {
|
|
2372
|
+
const trimmed = String(model || "").trim();
|
|
2373
|
+
if (!trimmed) return null;
|
|
2374
|
+
if (trimmed === "gpt-5-minimal" || trimmed === "gpt-5-low" || trimmed === "gpt-5-medium" || trimmed === "gpt-5-high" || trimmed === "gpt-5-codex" || trimmed.startsWith("gpt-5-codex-") || trimmed === "gpt-5.3-codex" || trimmed.startsWith("gpt-5.3-codex-")) {
|
|
2375
|
+
if (trimmed === "gpt-5-codex" || trimmed.startsWith("gpt-5-codex-")) return "gpt-5.2-codex";
|
|
2376
|
+
if (trimmed === "gpt-5.3-codex" || trimmed.startsWith("gpt-5.3-codex-")) return "gpt-5.3-codex";
|
|
2377
|
+
return "gpt-5.2";
|
|
2378
|
+
}
|
|
2379
|
+
return null;
|
|
2380
|
+
}
|
|
2342
2381
|
function resolveCodexModelOverride(rawModel) {
|
|
2343
2382
|
const model = typeof rawModel === "string" ? rawModel.trim() : "";
|
|
2344
2383
|
if (!model) return {};
|
|
2345
2384
|
const effort = parseEffortSuffix(model);
|
|
2346
|
-
const
|
|
2347
|
-
if (
|
|
2385
|
+
const codexModelTarget = parseCodexModelTarget(model);
|
|
2386
|
+
if (codexModelTarget) {
|
|
2387
|
+
if (codexModelTarget === "gpt-5.3-codex") {
|
|
2388
|
+
const installed = getInstalledCodexCliVersion();
|
|
2389
|
+
if (!installed || !isCodexCliAtLeast(installed, MIN_CODEX_CLI_FOR_GPT_53_CODEX)) {
|
|
2390
|
+
const installedText = installed ? `${installed.major}.${installed.minor}.${installed.patch}` : "unknown";
|
|
2391
|
+
throw new Error(`Codex CLI >= 0.104.0 is required for gpt-5.3-codex (installed: ${installedText}).`);
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2348
2394
|
const nextEffort = effort ?? "medium";
|
|
2349
2395
|
return {
|
|
2350
2396
|
config: {
|
|
2351
|
-
model:
|
|
2397
|
+
model: codexModelTarget,
|
|
2352
2398
|
model_reasoning_effort: nextEffort
|
|
2353
2399
|
}
|
|
2354
2400
|
};
|
|
@@ -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-DbQtXaZC.cjs');
|
|
6
6
|
var index_js = require('@modelcontextprotocol/sdk/client/index.js');
|
|
7
7
|
var z = require('zod');
|
|
8
8
|
var types_js = require('@modelcontextprotocol/sdk/types.js');
|
|
@@ -16,7 +16,7 @@ var process$1 = require('node:process');
|
|
|
16
16
|
var node_stream = require('node:stream');
|
|
17
17
|
var stdio_js$1 = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
18
18
|
var stdio_js = require('@modelcontextprotocol/sdk/shared/stdio.js');
|
|
19
|
-
var index = require('./index-
|
|
19
|
+
var index = require('./index-jd6DaTy_.cjs');
|
|
20
20
|
require('axios');
|
|
21
21
|
require('node:events');
|
|
22
22
|
require('socket.io-client');
|
|
@@ -443,36 +443,17 @@ class WindowsHiddenStdioClientTransport {
|
|
|
443
443
|
}
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
return "mcp-server";
|
|
458
|
-
}
|
|
459
|
-
const match = version.match(/codex-cli\s+(\d+\.\d+\.\d+(?:-alpha\.\d+)?)/);
|
|
460
|
-
if (!match) return "mcp-server";
|
|
461
|
-
const versionStr = match[1];
|
|
462
|
-
const [major, minor, patch] = versionStr.split(/[-.]/).map(Number);
|
|
463
|
-
if (major > 0 || minor > 43) return "mcp-server";
|
|
464
|
-
if (minor === 43 && patch === 0) {
|
|
465
|
-
if (versionStr.includes("-alpha.")) {
|
|
466
|
-
const alphaNum = parseInt(versionStr.split("-alpha.")[1]);
|
|
467
|
-
return alphaNum >= 5 ? "mcp-server" : "mcp";
|
|
468
|
-
}
|
|
469
|
-
return "mcp-server";
|
|
470
|
-
}
|
|
471
|
-
return "mcp";
|
|
472
|
-
} catch (error) {
|
|
473
|
-
types.logger.debug("[CodexMCP] Error detecting codex version, defaulting to mcp-server:", error);
|
|
474
|
-
return "mcp-server";
|
|
475
|
-
}
|
|
446
|
+
function parseCodexCliVersion(output) {
|
|
447
|
+
const raw = String(output || "").trim();
|
|
448
|
+
if (!raw) return null;
|
|
449
|
+
const m = raw.match(/codex-cli\s+(\d+)\.(\d+)\.(\d+)/);
|
|
450
|
+
if (!m) return null;
|
|
451
|
+
return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]), raw: m[0] };
|
|
452
|
+
}
|
|
453
|
+
function isCodexCliAtLeast(v, minimum) {
|
|
454
|
+
if (v.major !== minimum.major) return v.major > minimum.major;
|
|
455
|
+
if (v.minor !== minimum.minor) return v.minor > minimum.minor;
|
|
456
|
+
return v.patch >= minimum.patch;
|
|
476
457
|
}
|
|
477
458
|
function buildCodexSpawnEnv(codexBin) {
|
|
478
459
|
const env = Object.keys(process.env).reduce((acc, key) => {
|
|
@@ -563,6 +544,53 @@ function resolveCodexBin() {
|
|
|
563
544
|
if (fromBash) return fromBash;
|
|
564
545
|
return "codex";
|
|
565
546
|
}
|
|
547
|
+
function getInstalledCodexCliVersion(codexBin) {
|
|
548
|
+
const bin = resolveCodexBin();
|
|
549
|
+
try {
|
|
550
|
+
const res = node_child_process.spawnSync(bin, ["--version"], {
|
|
551
|
+
encoding: "utf8",
|
|
552
|
+
env: buildCodexSpawnEnv(bin),
|
|
553
|
+
timeout: 4e3
|
|
554
|
+
});
|
|
555
|
+
const versionOut = String(res.stdout || "").trim();
|
|
556
|
+
if (res.status !== 0 || !versionOut) return null;
|
|
557
|
+
return parseCodexCliVersion(versionOut);
|
|
558
|
+
} catch {
|
|
559
|
+
return null;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const DEFAULT_TIMEOUT = 14 * 24 * 60 * 60 * 1e3;
|
|
564
|
+
function getCodexMcpCommand() {
|
|
565
|
+
try {
|
|
566
|
+
const codexBin = resolveCodexBin();
|
|
567
|
+
const versionRes = node_child_process.spawnSync(codexBin, ["--version"], {
|
|
568
|
+
encoding: "utf8",
|
|
569
|
+
env: buildCodexSpawnEnv(codexBin),
|
|
570
|
+
timeout: 4e3
|
|
571
|
+
});
|
|
572
|
+
const version = String(versionRes.stdout || "").trim();
|
|
573
|
+
if (versionRes.status !== 0 || !version) {
|
|
574
|
+
return "mcp-server";
|
|
575
|
+
}
|
|
576
|
+
const match = version.match(/codex-cli\s+(\d+\.\d+\.\d+(?:-alpha\.\d+)?)/);
|
|
577
|
+
if (!match) return "mcp-server";
|
|
578
|
+
const versionStr = match[1];
|
|
579
|
+
const [major, minor, patch] = versionStr.split(/[-.]/).map(Number);
|
|
580
|
+
if (major > 0 || minor > 43) return "mcp-server";
|
|
581
|
+
if (minor === 43 && patch === 0) {
|
|
582
|
+
if (versionStr.includes("-alpha.")) {
|
|
583
|
+
const alphaNum = parseInt(versionStr.split("-alpha.")[1]);
|
|
584
|
+
return alphaNum >= 5 ? "mcp-server" : "mcp";
|
|
585
|
+
}
|
|
586
|
+
return "mcp-server";
|
|
587
|
+
}
|
|
588
|
+
return "mcp";
|
|
589
|
+
} catch (error) {
|
|
590
|
+
types.logger.debug("[CodexMCP] Error detecting codex version, defaulting to mcp-server:", error);
|
|
591
|
+
return "mcp-server";
|
|
592
|
+
}
|
|
593
|
+
}
|
|
566
594
|
function normalizeRelativePath(input) {
|
|
567
595
|
const raw = typeof input === "string" ? input.trim() : String(input ?? "").trim();
|
|
568
596
|
if (!raw) return null;
|
|
@@ -2321,6 +2349,7 @@ function hashCodexSessionModeFromEnhancedMode(mode) {
|
|
|
2321
2349
|
return hashCodexSessionMode({ model: mode.model, appendSystemPrompt: mode.appendSystemPrompt });
|
|
2322
2350
|
}
|
|
2323
2351
|
|
|
2352
|
+
const MIN_CODEX_CLI_FOR_GPT_53_CODEX = { major: 0, minor: 104, patch: 0 };
|
|
2324
2353
|
function readCodexAuthIsChatGptAccount() {
|
|
2325
2354
|
try {
|
|
2326
2355
|
const authPath = path.join(os.homedir(), ".codex", "auth.json");
|
|
@@ -2341,16 +2370,33 @@ function parseEffortSuffix(model) {
|
|
|
2341
2370
|
if (m.endsWith("-high")) return "high";
|
|
2342
2371
|
return null;
|
|
2343
2372
|
}
|
|
2373
|
+
function parseCodexModelTarget(model) {
|
|
2374
|
+
const trimmed = String(model || "").trim();
|
|
2375
|
+
if (!trimmed) return null;
|
|
2376
|
+
if (trimmed === "gpt-5-minimal" || trimmed === "gpt-5-low" || trimmed === "gpt-5-medium" || trimmed === "gpt-5-high" || trimmed === "gpt-5-codex" || trimmed.startsWith("gpt-5-codex-") || trimmed === "gpt-5.3-codex" || trimmed.startsWith("gpt-5.3-codex-")) {
|
|
2377
|
+
if (trimmed === "gpt-5-codex" || trimmed.startsWith("gpt-5-codex-")) return "gpt-5.2-codex";
|
|
2378
|
+
if (trimmed === "gpt-5.3-codex" || trimmed.startsWith("gpt-5.3-codex-")) return "gpt-5.3-codex";
|
|
2379
|
+
return "gpt-5.2";
|
|
2380
|
+
}
|
|
2381
|
+
return null;
|
|
2382
|
+
}
|
|
2344
2383
|
function resolveCodexModelOverride(rawModel) {
|
|
2345
2384
|
const model = typeof rawModel === "string" ? rawModel.trim() : "";
|
|
2346
2385
|
if (!model) return {};
|
|
2347
2386
|
const effort = parseEffortSuffix(model);
|
|
2348
|
-
const
|
|
2349
|
-
if (
|
|
2387
|
+
const codexModelTarget = parseCodexModelTarget(model);
|
|
2388
|
+
if (codexModelTarget) {
|
|
2389
|
+
if (codexModelTarget === "gpt-5.3-codex") {
|
|
2390
|
+
const installed = getInstalledCodexCliVersion();
|
|
2391
|
+
if (!installed || !isCodexCliAtLeast(installed, MIN_CODEX_CLI_FOR_GPT_53_CODEX)) {
|
|
2392
|
+
const installedText = installed ? `${installed.major}.${installed.minor}.${installed.patch}` : "unknown";
|
|
2393
|
+
throw new Error(`Codex CLI >= 0.104.0 is required for gpt-5.3-codex (installed: ${installedText}).`);
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2350
2396
|
const nextEffort = effort ?? "medium";
|
|
2351
2397
|
return {
|
|
2352
2398
|
config: {
|
|
2353
|
-
model:
|
|
2399
|
+
model: codexModelTarget,
|
|
2354
2400
|
model_reasoning_effort: nextEffort
|
|
2355
2401
|
}
|
|
2356
2402
|
};
|
|
@@ -6,8 +6,8 @@ var node_crypto = require('node:crypto');
|
|
|
6
6
|
var os = require('node:os');
|
|
7
7
|
var path = require('node:path');
|
|
8
8
|
var fs$2 = require('node:fs/promises');
|
|
9
|
-
var types = require('./types-
|
|
10
|
-
var index = require('./index-
|
|
9
|
+
var types = require('./types-DbQtXaZC.cjs');
|
|
10
|
+
var index = require('./index-jd6DaTy_.cjs');
|
|
11
11
|
var node_child_process = require('node:child_process');
|
|
12
12
|
var sdk = require('@agentclientprotocol/sdk');
|
|
13
13
|
var fs = require('fs');
|
|
@@ -4,8 +4,8 @@ import { randomUUID, createHash } from 'node:crypto';
|
|
|
4
4
|
import os__default from 'node:os';
|
|
5
5
|
import path__default, { resolve, join as join$1, basename } from 'node:path';
|
|
6
6
|
import { mkdir, writeFile, readFile } from 'node:fs/promises';
|
|
7
|
-
import { l as logger, p as packageJson, A as ApiClient, c as configuration, r as readSettings, b as projectPath } from './types-
|
|
8
|
-
import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, e as enforceCliVersionPolicy, i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, g as buildProjectCapsule, a as setLatestUserImages, b as MessageBuffer, w as withUserImagesMarker, r as registerKillSessionHandler, d as startFlockbayServer, o as extractUserImagesMarker, p as getLatestUserImages, P as PLATFORM_SYSTEM_PROMPT, j as autoFinalizeCoordinationWorkItem, E as ElicitationHub, k as detectScreenshotsForGate, m as stopCaffeinate } from './index-
|
|
7
|
+
import { l as logger, p as packageJson, A as ApiClient, c as configuration, r as readSettings, b as projectPath } from './types-KJ7kAYwk.mjs';
|
|
8
|
+
import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, e as enforceCliVersionPolicy, i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, g as buildProjectCapsule, a as setLatestUserImages, b as MessageBuffer, w as withUserImagesMarker, r as registerKillSessionHandler, d as startFlockbayServer, o as extractUserImagesMarker, p as getLatestUserImages, P as PLATFORM_SYSTEM_PROMPT, j as autoFinalizeCoordinationWorkItem, E as ElicitationHub, k as detectScreenshotsForGate, m as stopCaffeinate } from './index-BLsRYyPq.mjs';
|
|
9
9
|
import { spawn, spawnSync } from 'node:child_process';
|
|
10
10
|
import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
|
|
11
11
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
@@ -44,7 +44,7 @@ function _interopNamespaceDefault(e) {
|
|
|
44
44
|
var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
45
45
|
|
|
46
46
|
var name = "flockbay";
|
|
47
|
-
var version = "0.10.
|
|
47
|
+
var version = "0.10.48";
|
|
48
48
|
var description = "Flockbay CLI (local agent + daemon)";
|
|
49
49
|
var author = "Eduardo Orellana";
|
|
50
50
|
var license = "UNLICENSED";
|
|
@@ -832,7 +832,7 @@ class RpcHandlerManager {
|
|
|
832
832
|
}
|
|
833
833
|
}
|
|
834
834
|
|
|
835
|
-
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-
|
|
835
|
+
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-DbQtXaZC.cjs', document.baseURI).href))));
|
|
836
836
|
function projectPath() {
|
|
837
837
|
const path = path$1.resolve(__dirname$1, "..");
|
|
838
838
|
return path;
|
|
@@ -23,7 +23,7 @@ import { createServer } from 'http';
|
|
|
23
23
|
import open$2 from 'open';
|
|
24
24
|
|
|
25
25
|
var name = "flockbay";
|
|
26
|
-
var version = "0.10.
|
|
26
|
+
var version = "0.10.48";
|
|
27
27
|
var description = "Flockbay CLI (local agent + daemon)";
|
|
28
28
|
var author = "Eduardo Orellana";
|
|
29
29
|
var license = "UNLICENSED";
|