flockbay 0.10.51 → 0.10.52

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.
@@ -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-CN-EDgzo.cjs');
6
+ var types = require('./types-5z8UADAi.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');
@@ -982,7 +982,11 @@ async function claudeLocalLauncher(session) {
982
982
  } catch (e) {
983
983
  types.logger.debug("[local]: launch error", e);
984
984
  if (!exitReason) {
985
- session.client.sendSessionEvent({ type: "message", message: "Process exited unexpectedly" });
985
+ const details = e instanceof Error ? e.message : String(e);
986
+ session.client.sendSessionEvent({
987
+ type: "message",
988
+ message: `Process exited unexpectedly${details ? `: ${details}` : ""}`
989
+ });
986
990
  continue;
987
991
  } else {
988
992
  break;
@@ -1319,7 +1323,7 @@ function buildDaemonSafeEnv(baseEnv, binPath) {
1319
1323
  env[pathKey] = [...prepend, ...existingParts].join(pathSep);
1320
1324
  return env;
1321
1325
  }
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-wU3LFfZh.cjs', document.baseURI).href)));
1326
+ 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-IntvnrmZ.cjs', document.baseURI).href)));
1323
1327
  const __dirname$1 = path.join(__filename$1, "..");
1324
1328
  function getGlobalClaudeVersion(claudeExecutable) {
1325
1329
  try {
@@ -1522,6 +1526,40 @@ async function streamToStdin(stream, stdin, abort) {
1522
1526
  stdin.end();
1523
1527
  }
1524
1528
 
1529
+ function trimProcessDiagnostic(text) {
1530
+ const lines = String(text || "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
1531
+ if (lines.length === 0) return "";
1532
+ return lines.slice(-8).join("\n");
1533
+ }
1534
+ function buildClaudeProcessExitMessage(args) {
1535
+ const stderrText = String(args.stderrText || "");
1536
+ const stderr = trimProcessDiagnostic(stderrText);
1537
+ const combined = [stderrText, args.spawnError?.message || ""].filter(Boolean).join("\n");
1538
+ if (/claude code is not installed/i.test(combined)) {
1539
+ return [
1540
+ "Claude Code is not installed on this machine.",
1541
+ "Install it, then restart Flockbay:",
1542
+ process$1.platform === "win32" ? " npm install -g @anthropic-ai/claude-code" : " npm install -g @anthropic-ai/claude-code"
1543
+ ].join("\n");
1544
+ }
1545
+ if (/not recognized as an internal or external command|command not found|spawn .*enoent|enoent/i.test(combined)) {
1546
+ return [
1547
+ "Claude Code could not be found on PATH.",
1548
+ "Install it, then restart Flockbay:",
1549
+ " npm install -g @anthropic-ai/claude-code"
1550
+ ].join("\n");
1551
+ }
1552
+ if (/git bash|bash\.exe|claude_code_git_bash_path/i.test(combined)) {
1553
+ return [
1554
+ "Claude Code could not start because Git Bash is missing or not configured.",
1555
+ "Install Git for Windows, then set CLAUDE_CODE_GIT_BASH_PATH to your bash.exe path and restart Flockbay."
1556
+ ].join("\n");
1557
+ }
1558
+ if (stderr) {
1559
+ return `Claude Code process exited with code ${args.code}. Details: ${stderr}`;
1560
+ }
1561
+ return `Claude Code process exited with code ${args.code}`;
1562
+ }
1525
1563
  class Query {
1526
1564
  constructor(childStdin, childStdout, processExitPromise, canCallTool) {
1527
1565
  this.childStdin = childStdin;
@@ -1791,11 +1829,17 @@ function query(config) {
1791
1829
  streamToStdin(prompt, child.stdin, config.options?.abort);
1792
1830
  childStdin = child.stdin;
1793
1831
  }
1794
- if (process$1.env.DEBUG) {
1795
- child.stderr.on("data", (data) => {
1832
+ let stderrTail = "";
1833
+ const appendStderr = (chunk) => {
1834
+ stderrTail += chunk.toString();
1835
+ if (stderrTail.length > 32e3) stderrTail = stderrTail.slice(-16e3);
1836
+ };
1837
+ child.stderr.on("data", (data) => {
1838
+ appendStderr(data);
1839
+ if (process$1.env.DEBUG) {
1796
1840
  console.error("Claude Code stderr:", data.toString());
1797
- });
1798
- }
1841
+ }
1842
+ });
1799
1843
  const cleanup = () => {
1800
1844
  if (!child.killed) {
1801
1845
  child.kill("SIGTERM");
@@ -1809,7 +1853,7 @@ function query(config) {
1809
1853
  query2.setError(new AbortError("Claude Code process aborted by user"));
1810
1854
  }
1811
1855
  if (code !== 0) {
1812
- query2.setError(new Error(`Claude Code process exited with code ${code}`));
1856
+ query2.setError(new Error(buildClaudeProcessExitMessage({ code, stderrText: stderrTail })));
1813
1857
  } else {
1814
1858
  resolve();
1815
1859
  }
@@ -1820,7 +1864,7 @@ function query(config) {
1820
1864
  if (config.options?.abort?.aborted) {
1821
1865
  query2.setError(new AbortError("Claude Code process aborted by user"));
1822
1866
  } else {
1823
- query2.setError(new Error(`Failed to spawn Claude Code process: ${error.message}`));
1867
+ query2.setError(new Error(buildClaudeProcessExitMessage({ code: null, stderrText: stderrTail, spawnError: error })));
1824
1868
  }
1825
1869
  });
1826
1870
  processExitPromise.finally(() => {
@@ -15225,7 +15269,7 @@ async function authAndSetupMachineIfNeeded() {
15225
15269
  process.exit(1);
15226
15270
  }
15227
15271
  try {
15228
- const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin-CyXgJ-se.cjs'); });
15272
+ const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin-D1XjjWFq.cjs'); });
15229
15273
  const result = migrateUnrealMcpToFlockbayMcp({
15230
15274
  engineRoot,
15231
15275
  projectUprojectPath: project || void 0,
@@ -15381,7 +15425,7 @@ ${engineRoot}`;
15381
15425
  } else if (subcommand === "codex") {
15382
15426
  try {
15383
15427
  await chdirToNearestUprojectRootIfPresent();
15384
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-jDfLDJJW.cjs'); });
15428
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-B7i_ICoQ.cjs'); });
15385
15429
  let startedBy = void 0;
15386
15430
  let sessionId = void 0;
15387
15431
  for (let i = 1; i < args.length; i++) {
@@ -15483,7 +15527,7 @@ ${engineRoot}`;
15483
15527
  }
15484
15528
  try {
15485
15529
  await chdirToNearestUprojectRootIfPresent();
15486
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-DN189-WI.cjs'); });
15530
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-gBKR3rdL.cjs'); });
15487
15531
  let startedBy = void 0;
15488
15532
  let sessionId = void 0;
15489
15533
  for (let i = 1; i < args.length; i++) {
@@ -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, e as projectPath, f as backoff, g as delay, R as RawJSONLinesSchema, c as configuration, h as readDaemonState, j as clearDaemonState, p as packageJson, r as readSettings, k as readCredentials, u as updateSettings, o as openBrowser, w as writeCredentials, m as unrealMcpPythonDir, n as acquireDaemonLock, s as writeDaemonState, t as ApiMachineClient, v as releaseDaemonLock, x as sendUnrealMcpTcpCommand, A as ApiClient, y as validatePath, z as run, B as run$1, C as buildShellInvocation, D as clearCredentials, E as clearMachineId, F as authenticateCodex, G as syncCodexCliAuth, H as authenticateClaude, I as authenticateGemini, d as installUnrealMcpPluginToEngine, J as buildAndInstallUnrealMcpPlugin, i as installUnrealMcpPluginToProject, b as isInstalledEngineRoot, K as getLatestDaemonLog, L as normalizeServerUrlForNode } from './types-DRXvc8Nt.mjs';
5
+ import { l as logger, e as projectPath, f as backoff, g as delay, R as RawJSONLinesSchema, c as configuration, h as readDaemonState, j as clearDaemonState, p as packageJson, r as readSettings, k as readCredentials, u as updateSettings, o as openBrowser, w as writeCredentials, m as unrealMcpPythonDir, n as acquireDaemonLock, s as writeDaemonState, t as ApiMachineClient, v as releaseDaemonLock, x as sendUnrealMcpTcpCommand, A as ApiClient, y as validatePath, z as run, B as run$1, C as buildShellInvocation, D as clearCredentials, E as clearMachineId, F as authenticateCodex, G as syncCodexCliAuth, H as authenticateClaude, I as authenticateGemini, d as installUnrealMcpPluginToEngine, J as buildAndInstallUnrealMcpPlugin, i as installUnrealMcpPluginToProject, b as isInstalledEngineRoot, K as getLatestDaemonLog, L as normalizeServerUrlForNode } from './types-Bgzap7qR.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';
@@ -960,7 +960,11 @@ async function claudeLocalLauncher(session) {
960
960
  } catch (e) {
961
961
  logger.debug("[local]: launch error", e);
962
962
  if (!exitReason) {
963
- session.client.sendSessionEvent({ type: "message", message: "Process exited unexpectedly" });
963
+ const details = e instanceof Error ? e.message : String(e);
964
+ session.client.sendSessionEvent({
965
+ type: "message",
966
+ message: `Process exited unexpectedly${details ? `: ${details}` : ""}`
967
+ });
964
968
  continue;
965
969
  } else {
966
970
  break;
@@ -1500,6 +1504,40 @@ async function streamToStdin(stream, stdin, abort) {
1500
1504
  stdin.end();
1501
1505
  }
1502
1506
 
1507
+ function trimProcessDiagnostic(text) {
1508
+ const lines = String(text || "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
1509
+ if (lines.length === 0) return "";
1510
+ return lines.slice(-8).join("\n");
1511
+ }
1512
+ function buildClaudeProcessExitMessage(args) {
1513
+ const stderrText = String(args.stderrText || "");
1514
+ const stderr = trimProcessDiagnostic(stderrText);
1515
+ const combined = [stderrText, args.spawnError?.message || ""].filter(Boolean).join("\n");
1516
+ if (/claude code is not installed/i.test(combined)) {
1517
+ return [
1518
+ "Claude Code is not installed on this machine.",
1519
+ "Install it, then restart Flockbay:",
1520
+ process$1.platform === "win32" ? " npm install -g @anthropic-ai/claude-code" : " npm install -g @anthropic-ai/claude-code"
1521
+ ].join("\n");
1522
+ }
1523
+ if (/not recognized as an internal or external command|command not found|spawn .*enoent|enoent/i.test(combined)) {
1524
+ return [
1525
+ "Claude Code could not be found on PATH.",
1526
+ "Install it, then restart Flockbay:",
1527
+ " npm install -g @anthropic-ai/claude-code"
1528
+ ].join("\n");
1529
+ }
1530
+ if (/git bash|bash\.exe|claude_code_git_bash_path/i.test(combined)) {
1531
+ return [
1532
+ "Claude Code could not start because Git Bash is missing or not configured.",
1533
+ "Install Git for Windows, then set CLAUDE_CODE_GIT_BASH_PATH to your bash.exe path and restart Flockbay."
1534
+ ].join("\n");
1535
+ }
1536
+ if (stderr) {
1537
+ return `Claude Code process exited with code ${args.code}. Details: ${stderr}`;
1538
+ }
1539
+ return `Claude Code process exited with code ${args.code}`;
1540
+ }
1503
1541
  class Query {
1504
1542
  constructor(childStdin, childStdout, processExitPromise, canCallTool) {
1505
1543
  this.childStdin = childStdin;
@@ -1769,11 +1807,17 @@ function query(config) {
1769
1807
  streamToStdin(prompt, child.stdin, config.options?.abort);
1770
1808
  childStdin = child.stdin;
1771
1809
  }
1772
- if (process$1.env.DEBUG) {
1773
- child.stderr.on("data", (data) => {
1810
+ let stderrTail = "";
1811
+ const appendStderr = (chunk) => {
1812
+ stderrTail += chunk.toString();
1813
+ if (stderrTail.length > 32e3) stderrTail = stderrTail.slice(-16e3);
1814
+ };
1815
+ child.stderr.on("data", (data) => {
1816
+ appendStderr(data);
1817
+ if (process$1.env.DEBUG) {
1774
1818
  console.error("Claude Code stderr:", data.toString());
1775
- });
1776
- }
1819
+ }
1820
+ });
1777
1821
  const cleanup = () => {
1778
1822
  if (!child.killed) {
1779
1823
  child.kill("SIGTERM");
@@ -1787,7 +1831,7 @@ function query(config) {
1787
1831
  query2.setError(new AbortError("Claude Code process aborted by user"));
1788
1832
  }
1789
1833
  if (code !== 0) {
1790
- query2.setError(new Error(`Claude Code process exited with code ${code}`));
1834
+ query2.setError(new Error(buildClaudeProcessExitMessage({ code, stderrText: stderrTail })));
1791
1835
  } else {
1792
1836
  resolve();
1793
1837
  }
@@ -1798,7 +1842,7 @@ function query(config) {
1798
1842
  if (config.options?.abort?.aborted) {
1799
1843
  query2.setError(new AbortError("Claude Code process aborted by user"));
1800
1844
  } else {
1801
- query2.setError(new Error(`Failed to spawn Claude Code process: ${error.message}`));
1845
+ query2.setError(new Error(buildClaudeProcessExitMessage({ code: null, stderrText: stderrTail, spawnError: error })));
1802
1846
  }
1803
1847
  });
1804
1848
  processExitPromise.finally(() => {
@@ -15203,7 +15247,7 @@ async function authAndSetupMachineIfNeeded() {
15203
15247
  process.exit(1);
15204
15248
  }
15205
15249
  try {
15206
- const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-CnpWYW1E.mjs');
15250
+ const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-C71hAoc5.mjs');
15207
15251
  const result = migrateUnrealMcpToFlockbayMcp({
15208
15252
  engineRoot,
15209
15253
  projectUprojectPath: project || void 0,
@@ -15359,7 +15403,7 @@ ${engineRoot}`;
15359
15403
  } else if (subcommand === "codex") {
15360
15404
  try {
15361
15405
  await chdirToNearestUprojectRootIfPresent();
15362
- const { runCodex } = await import('./runCodex-Dhkynhhh.mjs');
15406
+ const { runCodex } = await import('./runCodex-BSx-hCu6.mjs');
15363
15407
  let startedBy = void 0;
15364
15408
  let sessionId = void 0;
15365
15409
  for (let i = 1; i < args.length; i++) {
@@ -15461,7 +15505,7 @@ ${engineRoot}`;
15461
15505
  }
15462
15506
  try {
15463
15507
  await chdirToNearestUprojectRootIfPresent();
15464
- const { runGemini } = await import('./runGemini-Dq5_59Us.mjs');
15508
+ const { runGemini } = await import('./runGemini-Dwyh7_WI.mjs');
15465
15509
  let startedBy = void 0;
15466
15510
  let sessionId = void 0;
15467
15511
  for (let i = 1; i < args.length; i++) {
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./index-wU3LFfZh.cjs');
5
- require('./types-CN-EDgzo.cjs');
4
+ require('./index-IntvnrmZ.cjs');
5
+ require('./types-5z8UADAi.cjs');
6
6
  require('zod');
7
7
  require('node:child_process');
8
8
  require('node:fs');
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import 'chalk';
2
- import './index-DZjyS6UX.mjs';
3
- import './types-DRXvc8Nt.mjs';
2
+ import './index-wkeSi0iC.mjs';
3
+ import './types-Bgzap7qR.mjs';
4
4
  import 'zod';
5
5
  import 'node:child_process';
6
6
  import 'node:fs';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-CN-EDgzo.cjs');
3
+ var types = require('./types-5z8UADAi.cjs');
4
4
  require('axios');
5
5
  require('node:fs');
6
6
  require('node:os');
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-DRXvc8Nt.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-Bgzap7qR.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 installUnrealMcpPluginToProject, b as isInstalledEngineRoot, q as quarantineLegacyEnginePlugins, d as installUnrealMcpPluginToEngine } from './types-DRXvc8Nt.mjs';
3
+ import { i as installUnrealMcpPluginToProject, b as isInstalledEngineRoot, q as quarantineLegacyEnginePlugins, d as installUnrealMcpPluginToEngine } from './types-Bgzap7qR.mjs';
4
4
  import 'axios';
5
5
  import 'node:os';
6
6
  import 'node:events';
@@ -2,7 +2,7 @@
2
2
 
3
3
  var fs = require('node:fs');
4
4
  var path = require('node:path');
5
- var types = require('./types-CN-EDgzo.cjs');
5
+ var types = require('./types-5z8UADAi.cjs');
6
6
  require('axios');
7
7
  require('node:os');
8
8
  require('node:events');
@@ -2,7 +2,7 @@
2
2
 
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
- var types = require('./types-CN-EDgzo.cjs');
5
+ var types = require('./types-5z8UADAi.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-wU3LFfZh.cjs');
19
+ var index = require('./index-IntvnrmZ.cjs');
20
20
  require('axios');
21
21
  require('node:events');
22
22
  require('socket.io-client');
@@ -2350,38 +2350,50 @@ function hashCodexSessionModeFromEnhancedMode(mode) {
2350
2350
  }
2351
2351
 
2352
2352
  const MIN_CODEX_CLI_FOR_GPT_53_CODEX = { major: 0, minor: 104, patch: 0 };
2353
- function readCodexAuthIsChatGptAccount() {
2354
- try {
2355
- const authPath = path.join(os.homedir(), ".codex", "auth.json");
2356
- const raw = fs.readFileSync(authPath, "utf8");
2357
- const parsed = JSON.parse(raw);
2358
- const accessToken = parsed?.tokens?.access_token;
2359
- if (typeof accessToken !== "string" || !accessToken) return false;
2360
- return Boolean(parsed?.tokens?.account_id) && parsed?.OPENAI_API_KEY === null;
2361
- } catch {
2362
- return false;
2353
+ function normalizeLegacyModelAlias(model) {
2354
+ const trimmed = String(model || "").trim();
2355
+ if (!trimmed) return "";
2356
+ switch (trimmed) {
2357
+ case "gpt-5":
2358
+ case "gpt-5-minimal":
2359
+ case "gpt-5-low":
2360
+ return "gpt-5.4-low";
2361
+ case "gpt-5-medium":
2362
+ return "gpt-5.4-medium";
2363
+ case "gpt-5-high":
2364
+ return "gpt-5.4-high";
2365
+ case "gpt-5-codex":
2366
+ case "gpt-5-codex-low":
2367
+ return "gpt-5.3-codex-low";
2368
+ case "gpt-5-codex-medium":
2369
+ return "gpt-5.3-codex-medium";
2370
+ case "gpt-5-codex-high":
2371
+ return "gpt-5.3-codex-high";
2372
+ default:
2373
+ return trimmed;
2363
2374
  }
2364
2375
  }
2365
2376
  function parseEffortSuffix(model) {
2366
2377
  const m = String(model || "").trim();
2367
2378
  if (!m) return null;
2379
+ if (m.endsWith("-xhigh")) return "xhigh";
2368
2380
  if (m.endsWith("-low")) return "low";
2369
2381
  if (m.endsWith("-medium")) return "medium";
2370
2382
  if (m.endsWith("-high")) return "high";
2371
2383
  return null;
2372
2384
  }
2373
2385
  function parseCodexModelTarget(model) {
2374
- const trimmed = String(model || "").trim();
2386
+ const trimmed = normalizeLegacyModelAlias(model);
2375
2387
  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";
2388
+ const isGpt54ReasoningToken = trimmed === "gpt-5.4" || trimmed === "gpt-5.4-low" || trimmed === "gpt-5.4-medium" || trimmed === "gpt-5.4-high" || trimmed === "gpt-5.4-xhigh";
2389
+ if (isGpt54ReasoningToken || trimmed === "gpt-5.3-codex" || trimmed.startsWith("gpt-5.3-codex-")) {
2378
2390
  if (trimmed === "gpt-5.3-codex" || trimmed.startsWith("gpt-5.3-codex-")) return "gpt-5.3-codex";
2379
- return "gpt-5.2";
2391
+ return "gpt-5.4";
2380
2392
  }
2381
2393
  return null;
2382
2394
  }
2383
2395
  function resolveCodexModelOverride(rawModel) {
2384
- const model = typeof rawModel === "string" ? rawModel.trim() : "";
2396
+ const model = normalizeLegacyModelAlias(typeof rawModel === "string" ? rawModel.trim() : "");
2385
2397
  if (!model) return {};
2386
2398
  const effort = parseEffortSuffix(model);
2387
2399
  const codexModelTarget = parseCodexModelTarget(model);
@@ -2401,12 +2413,6 @@ function resolveCodexModelOverride(rawModel) {
2401
2413
  }
2402
2414
  };
2403
2415
  }
2404
- const isChatGptAuth = readCodexAuthIsChatGptAccount();
2405
- if (!isChatGptAuth) return { config: { model } };
2406
- if (model.startsWith("gpt-5-")) {
2407
- const nextEffort = effort ?? "medium";
2408
- return { config: { model: "gpt-5.2", model_reasoning_effort: nextEffort } };
2409
- }
2410
2416
  return { config: { model } };
2411
2417
  }
2412
2418
 
@@ -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, e as projectPath } from './types-DRXvc8Nt.mjs';
3
+ import { l as logger, A as ApiClient, p as packageJson, c as configuration, r as readSettings, e as projectPath } from './types-Bgzap7qR.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-DZjyS6UX.mjs';
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-wkeSi0iC.mjs';
18
18
  import 'axios';
19
19
  import 'node:events';
20
20
  import 'socket.io-client';
@@ -2348,38 +2348,50 @@ function hashCodexSessionModeFromEnhancedMode(mode) {
2348
2348
  }
2349
2349
 
2350
2350
  const MIN_CODEX_CLI_FOR_GPT_53_CODEX = { major: 0, minor: 104, patch: 0 };
2351
- function readCodexAuthIsChatGptAccount() {
2352
- try {
2353
- const authPath = path__default.join(os__default.homedir(), ".codex", "auth.json");
2354
- const raw = fs__default.readFileSync(authPath, "utf8");
2355
- const parsed = JSON.parse(raw);
2356
- const accessToken = parsed?.tokens?.access_token;
2357
- if (typeof accessToken !== "string" || !accessToken) return false;
2358
- return Boolean(parsed?.tokens?.account_id) && parsed?.OPENAI_API_KEY === null;
2359
- } catch {
2360
- return false;
2351
+ function normalizeLegacyModelAlias(model) {
2352
+ const trimmed = String(model || "").trim();
2353
+ if (!trimmed) return "";
2354
+ switch (trimmed) {
2355
+ case "gpt-5":
2356
+ case "gpt-5-minimal":
2357
+ case "gpt-5-low":
2358
+ return "gpt-5.4-low";
2359
+ case "gpt-5-medium":
2360
+ return "gpt-5.4-medium";
2361
+ case "gpt-5-high":
2362
+ return "gpt-5.4-high";
2363
+ case "gpt-5-codex":
2364
+ case "gpt-5-codex-low":
2365
+ return "gpt-5.3-codex-low";
2366
+ case "gpt-5-codex-medium":
2367
+ return "gpt-5.3-codex-medium";
2368
+ case "gpt-5-codex-high":
2369
+ return "gpt-5.3-codex-high";
2370
+ default:
2371
+ return trimmed;
2361
2372
  }
2362
2373
  }
2363
2374
  function parseEffortSuffix(model) {
2364
2375
  const m = String(model || "").trim();
2365
2376
  if (!m) return null;
2377
+ if (m.endsWith("-xhigh")) return "xhigh";
2366
2378
  if (m.endsWith("-low")) return "low";
2367
2379
  if (m.endsWith("-medium")) return "medium";
2368
2380
  if (m.endsWith("-high")) return "high";
2369
2381
  return null;
2370
2382
  }
2371
2383
  function parseCodexModelTarget(model) {
2372
- const trimmed = String(model || "").trim();
2384
+ const trimmed = normalizeLegacyModelAlias(model);
2373
2385
  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";
2386
+ const isGpt54ReasoningToken = trimmed === "gpt-5.4" || trimmed === "gpt-5.4-low" || trimmed === "gpt-5.4-medium" || trimmed === "gpt-5.4-high" || trimmed === "gpt-5.4-xhigh";
2387
+ if (isGpt54ReasoningToken || trimmed === "gpt-5.3-codex" || trimmed.startsWith("gpt-5.3-codex-")) {
2376
2388
  if (trimmed === "gpt-5.3-codex" || trimmed.startsWith("gpt-5.3-codex-")) return "gpt-5.3-codex";
2377
- return "gpt-5.2";
2389
+ return "gpt-5.4";
2378
2390
  }
2379
2391
  return null;
2380
2392
  }
2381
2393
  function resolveCodexModelOverride(rawModel) {
2382
- const model = typeof rawModel === "string" ? rawModel.trim() : "";
2394
+ const model = normalizeLegacyModelAlias(typeof rawModel === "string" ? rawModel.trim() : "");
2383
2395
  if (!model) return {};
2384
2396
  const effort = parseEffortSuffix(model);
2385
2397
  const codexModelTarget = parseCodexModelTarget(model);
@@ -2399,12 +2411,6 @@ function resolveCodexModelOverride(rawModel) {
2399
2411
  }
2400
2412
  };
2401
2413
  }
2402
- const isChatGptAuth = readCodexAuthIsChatGptAccount();
2403
- if (!isChatGptAuth) return { config: { model } };
2404
- if (model.startsWith("gpt-5-")) {
2405
- const nextEffort = effort ?? "medium";
2406
- return { config: { model: "gpt-5.2", model_reasoning_effort: nextEffort } };
2407
- }
2408
2414
  return { config: { model } };
2409
2415
  }
2410
2416
 
@@ -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, e as projectPath } from './types-DRXvc8Nt.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-DZjyS6UX.mjs';
7
+ import { l as logger, p as packageJson, A as ApiClient, c as configuration, r as readSettings, e as projectPath } from './types-Bgzap7qR.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-wkeSi0iC.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';
@@ -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-CN-EDgzo.cjs');
10
- var index = require('./index-wU3LFfZh.cjs');
9
+ var types = require('./types-5z8UADAi.cjs');
10
+ var index = require('./index-IntvnrmZ.cjs');
11
11
  var node_child_process = require('node:child_process');
12
12
  var sdk = require('@agentclientprotocol/sdk');
13
13
  var fs = require('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.51";
47
+ var version = "0.10.52";
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-CN-EDgzo.cjs', document.baseURI).href))));
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-5z8UADAi.cjs', document.baseURI).href))));
836
836
  function projectPath() {
837
837
  const path = path$1.resolve(__dirname$1, "..");
838
838
  return path;
@@ -4017,6 +4017,91 @@ Log: ${buildLogPath}`
4017
4017
  return { ok: true, buildLogPath };
4018
4018
  }
4019
4019
 
4020
+ function normalizeWindowsPath(value) {
4021
+ return path.win32.normalize(String(value || "").trim()).replace(/[\\/]+$/, "");
4022
+ }
4023
+ function equalsIgnoreCaseWindows(a, b) {
4024
+ return normalizeWindowsPath(a || "").toLowerCase() === normalizeWindowsPath(b || "").toLowerCase();
4025
+ }
4026
+ function extractUprojectPathFromCommandLine(commandLine) {
4027
+ const raw = String(commandLine || "").trim();
4028
+ if (!raw) return null;
4029
+ const matches = Array.from(raw.matchAll(/"([^"\r\n]+?\.uproject)"|([^\s"]+?\.uproject)/gi));
4030
+ for (const match of matches) {
4031
+ const candidate = String(match[1] || match[2] || "").trim();
4032
+ if (!candidate) continue;
4033
+ return normalizeWindowsPath(candidate);
4034
+ }
4035
+ return null;
4036
+ }
4037
+ function inferEngineRootFromExecutablePath(executablePath) {
4038
+ const normalized = normalizeWindowsPath(executablePath);
4039
+ if (!normalized) return null;
4040
+ const marker = `${path.win32.sep}Engine${path.win32.sep}Binaries${path.win32.sep}`;
4041
+ const idx = normalized.toLowerCase().indexOf(marker.toLowerCase());
4042
+ if (idx === -1) return null;
4043
+ return normalized.slice(0, idx);
4044
+ }
4045
+ function compareCreationDateDesc(a, b) {
4046
+ const aa = String(a || "").trim();
4047
+ const bb = String(b || "").trim();
4048
+ return bb.localeCompare(aa);
4049
+ }
4050
+ function parseRunningUnrealEditorProjectsFromWindowsJson(input) {
4051
+ const engineRoot = String(input.engineRoot || "").trim();
4052
+ const wantedEngineRoot = engineRoot ? normalizeWindowsPath(engineRoot) : "";
4053
+ const raw = String(input.raw || "").trim();
4054
+ if (!raw) return [];
4055
+ let parsed;
4056
+ try {
4057
+ parsed = JSON.parse(raw);
4058
+ } catch {
4059
+ return [];
4060
+ }
4061
+ const records = (Array.isArray(parsed) ? parsed : [parsed]).filter(Boolean);
4062
+ const out = [];
4063
+ for (const record of records) {
4064
+ const uprojectPath = extractUprojectPathFromCommandLine(String(record?.CommandLine || ""));
4065
+ if (!uprojectPath) continue;
4066
+ const executablePath = record?.ExecutablePath ? normalizeWindowsPath(record.ExecutablePath) : null;
4067
+ const inferredEngineRoot = executablePath ? inferEngineRootFromExecutablePath(executablePath) : null;
4068
+ if (wantedEngineRoot && !equalsIgnoreCaseWindows(inferredEngineRoot, wantedEngineRoot)) continue;
4069
+ const processIdNumber = Number(record?.ProcessId);
4070
+ out.push({
4071
+ processId: Number.isFinite(processIdNumber) && processIdNumber > 0 ? processIdNumber : null,
4072
+ executablePath,
4073
+ engineRoot: inferredEngineRoot,
4074
+ uprojectPath,
4075
+ commandLine: record?.CommandLine ? String(record.CommandLine) : null,
4076
+ creationDate: record?.CreationDate ? String(record.CreationDate) : null
4077
+ });
4078
+ }
4079
+ out.sort((a, b) => compareCreationDateDesc(a.creationDate, b.creationDate));
4080
+ return out;
4081
+ }
4082
+ function detectRunningUnrealEditorProject(options) {
4083
+ if (process.platform !== "win32") return null;
4084
+ const execFileSyncImpl = options?.execFileSyncImpl || node_child_process.execFileSync;
4085
+ const script = [
4086
+ '$ErrorActionPreference = "Stop"',
4087
+ `$procs = Get-CimInstance Win32_Process -Filter "Name = 'UnrealEditor.exe'" | Select-Object ProcessId, ExecutablePath, CommandLine, CreationDate`,
4088
+ 'if ($null -eq $procs) { "[]" } else { $procs | ConvertTo-Json -Compress -Depth 3 }'
4089
+ ].join("; ");
4090
+ try {
4091
+ const raw = execFileSyncImpl("powershell.exe", ["-NoProfile", "-Command", script], {
4092
+ encoding: "utf8",
4093
+ windowsHide: true
4094
+ });
4095
+ const matches = parseRunningUnrealEditorProjectsFromWindowsJson({
4096
+ raw: typeof raw === "string" ? raw : String(raw || ""),
4097
+ engineRoot: options?.engineRoot
4098
+ });
4099
+ return matches[0] || null;
4100
+ } catch {
4101
+ return null;
4102
+ }
4103
+ }
4104
+
4020
4105
  function canWriteDir$1(dir) {
4021
4106
  const root = String(dir || "").trim();
4022
4107
  if (!root) return false;
@@ -4092,11 +4177,14 @@ function getUnrealMcpPluginDiskStatus(params) {
4092
4177
  const checkedAtMs = Date.now();
4093
4178
  const engineRoot = String(params?.engineRoot || "").trim();
4094
4179
  const installScope = String(params?.installScope || "auto");
4095
- const projectUprojectPathRaw = typeof params?.projectUprojectPath === "string" ? params.projectUprojectPath.trim() : "";
4180
+ const requestedProjectUprojectPath = typeof params?.projectUprojectPath === "string" ? params.projectUprojectPath.trim() : "";
4096
4181
  if (!engineRoot) return { success: false, error: "Missing engineRoot." };
4097
4182
  if (!looksLikeEngineRoot(engineRoot)) {
4098
4183
  return { success: false, error: `Invalid engine root (expected an Unreal Engine install folder containing Engine/Plugins): ${engineRoot}` };
4099
4184
  }
4185
+ const installedEngine = isInstalledEngineRoot(engineRoot);
4186
+ const runningProject = detectRunningUnrealEditorProject({ engineRoot });
4187
+ const projectUprojectPathRaw = runningProject?.uprojectPath || requestedProjectUprojectPath;
4100
4188
  const enginePluginsDir = path.join(engineRoot, "Engine", "Plugins");
4101
4189
  const enginePluginDir = path.join(enginePluginsDir, "FlockbayMCP");
4102
4190
  const engineUpluginPath = path.join(enginePluginDir, "FlockbayMCP.uplugin");
@@ -4164,7 +4252,7 @@ function getUnrealMcpPluginDiskStatus(params) {
4164
4252
  }
4165
4253
  const engineInstalled = engineInfo.exists && engineInfo.descriptorOk && engineInfo.hasBinaries;
4166
4254
  const projectInstalled = Boolean(project && project.exists && project.descriptorOk && project.enabledInUproject);
4167
- const effectiveScope = installScope === "engine" ? "engine" : installScope === "project" ? "project" : engineInstalled ? "engine" : project && !engineInfo.enginePluginsWritable ? "project" : "engine";
4255
+ const effectiveScope = installScope === "engine" ? "engine" : installScope === "project" ? "project" : installedEngine && project ? "project" : engineInstalled ? "engine" : project && !engineInfo.enginePluginsWritable ? "project" : "engine";
4168
4256
  const conflict = engineInfo.conflicts.length > 0;
4169
4257
  const legacyConflict = engineInfo.legacy.length > 0;
4170
4258
  const baseInstalled = effectiveScope === "engine" ? engineInstalled : projectInstalled;
@@ -4879,12 +4967,14 @@ class ApiMachineClient {
4879
4967
  async (params) => {
4880
4968
  const engineRoot = String(params?.engineRoot || "").trim();
4881
4969
  const scope = String(params?.installScope || "auto");
4882
- const projectUprojectPath = typeof params?.projectUprojectPath === "string" ? params.projectUprojectPath.trim() : "";
4970
+ const requestedProjectUprojectPath = typeof params?.projectUprojectPath === "string" ? params.projectUprojectPath.trim() : "";
4883
4971
  const enginePluginsDir = path.join(engineRoot, "Engine", "Plugins");
4884
4972
  const enginePluginDir = path.join(enginePluginsDir, "FlockbayMCP");
4885
4973
  const enginePluginUplugin = path.join(enginePluginDir, "FlockbayMCP.uplugin");
4886
4974
  const enginePluginHasBinaries = fs.existsSync(path.join(enginePluginDir, "Binaries"));
4887
4975
  const installedEngine = isInstalledEngineRoot(engineRoot);
4976
+ const runningProject = installedEngine ? detectRunningUnrealEditorProject({ engineRoot }) : null;
4977
+ const projectUprojectPath = runningProject?.uprojectPath || requestedProjectUprojectPath;
4888
4978
  if (installedEngine) {
4889
4979
  const quarantine = quarantineLegacyEnginePlugins(engineRoot);
4890
4980
  if (!quarantine.ok) return { success: false, error: quarantine.errorMessage };
@@ -18,12 +18,12 @@ import { fileURLToPath } from 'url';
18
18
  import process$1 from 'node:process';
19
19
  import { platform } from 'os';
20
20
  import net from 'node:net';
21
- import { spawn as spawn$1 } from 'node:child_process';
21
+ import { spawn as spawn$1, execFileSync } from 'node:child_process';
22
22
  import { createServer } from 'http';
23
23
  import open$2 from 'open';
24
24
 
25
25
  var name = "flockbay";
26
- var version = "0.10.51";
26
+ var version = "0.10.52";
27
27
  var description = "Flockbay CLI (local agent + daemon)";
28
28
  var author = "Eduardo Orellana";
29
29
  var license = "UNLICENSED";
@@ -3996,6 +3996,91 @@ Log: ${buildLogPath}`
3996
3996
  return { ok: true, buildLogPath };
3997
3997
  }
3998
3998
 
3999
+ function normalizeWindowsPath(value) {
4000
+ return path__default.win32.normalize(String(value || "").trim()).replace(/[\\/]+$/, "");
4001
+ }
4002
+ function equalsIgnoreCaseWindows(a, b) {
4003
+ return normalizeWindowsPath(a || "").toLowerCase() === normalizeWindowsPath(b || "").toLowerCase();
4004
+ }
4005
+ function extractUprojectPathFromCommandLine(commandLine) {
4006
+ const raw = String(commandLine || "").trim();
4007
+ if (!raw) return null;
4008
+ const matches = Array.from(raw.matchAll(/"([^"\r\n]+?\.uproject)"|([^\s"]+?\.uproject)/gi));
4009
+ for (const match of matches) {
4010
+ const candidate = String(match[1] || match[2] || "").trim();
4011
+ if (!candidate) continue;
4012
+ return normalizeWindowsPath(candidate);
4013
+ }
4014
+ return null;
4015
+ }
4016
+ function inferEngineRootFromExecutablePath(executablePath) {
4017
+ const normalized = normalizeWindowsPath(executablePath);
4018
+ if (!normalized) return null;
4019
+ const marker = `${path__default.win32.sep}Engine${path__default.win32.sep}Binaries${path__default.win32.sep}`;
4020
+ const idx = normalized.toLowerCase().indexOf(marker.toLowerCase());
4021
+ if (idx === -1) return null;
4022
+ return normalized.slice(0, idx);
4023
+ }
4024
+ function compareCreationDateDesc(a, b) {
4025
+ const aa = String(a || "").trim();
4026
+ const bb = String(b || "").trim();
4027
+ return bb.localeCompare(aa);
4028
+ }
4029
+ function parseRunningUnrealEditorProjectsFromWindowsJson(input) {
4030
+ const engineRoot = String(input.engineRoot || "").trim();
4031
+ const wantedEngineRoot = engineRoot ? normalizeWindowsPath(engineRoot) : "";
4032
+ const raw = String(input.raw || "").trim();
4033
+ if (!raw) return [];
4034
+ let parsed;
4035
+ try {
4036
+ parsed = JSON.parse(raw);
4037
+ } catch {
4038
+ return [];
4039
+ }
4040
+ const records = (Array.isArray(parsed) ? parsed : [parsed]).filter(Boolean);
4041
+ const out = [];
4042
+ for (const record of records) {
4043
+ const uprojectPath = extractUprojectPathFromCommandLine(String(record?.CommandLine || ""));
4044
+ if (!uprojectPath) continue;
4045
+ const executablePath = record?.ExecutablePath ? normalizeWindowsPath(record.ExecutablePath) : null;
4046
+ const inferredEngineRoot = executablePath ? inferEngineRootFromExecutablePath(executablePath) : null;
4047
+ if (wantedEngineRoot && !equalsIgnoreCaseWindows(inferredEngineRoot, wantedEngineRoot)) continue;
4048
+ const processIdNumber = Number(record?.ProcessId);
4049
+ out.push({
4050
+ processId: Number.isFinite(processIdNumber) && processIdNumber > 0 ? processIdNumber : null,
4051
+ executablePath,
4052
+ engineRoot: inferredEngineRoot,
4053
+ uprojectPath,
4054
+ commandLine: record?.CommandLine ? String(record.CommandLine) : null,
4055
+ creationDate: record?.CreationDate ? String(record.CreationDate) : null
4056
+ });
4057
+ }
4058
+ out.sort((a, b) => compareCreationDateDesc(a.creationDate, b.creationDate));
4059
+ return out;
4060
+ }
4061
+ function detectRunningUnrealEditorProject(options) {
4062
+ if (process.platform !== "win32") return null;
4063
+ const execFileSyncImpl = options?.execFileSyncImpl || execFileSync;
4064
+ const script = [
4065
+ '$ErrorActionPreference = "Stop"',
4066
+ `$procs = Get-CimInstance Win32_Process -Filter "Name = 'UnrealEditor.exe'" | Select-Object ProcessId, ExecutablePath, CommandLine, CreationDate`,
4067
+ 'if ($null -eq $procs) { "[]" } else { $procs | ConvertTo-Json -Compress -Depth 3 }'
4068
+ ].join("; ");
4069
+ try {
4070
+ const raw = execFileSyncImpl("powershell.exe", ["-NoProfile", "-Command", script], {
4071
+ encoding: "utf8",
4072
+ windowsHide: true
4073
+ });
4074
+ const matches = parseRunningUnrealEditorProjectsFromWindowsJson({
4075
+ raw: typeof raw === "string" ? raw : String(raw || ""),
4076
+ engineRoot: options?.engineRoot
4077
+ });
4078
+ return matches[0] || null;
4079
+ } catch {
4080
+ return null;
4081
+ }
4082
+ }
4083
+
3999
4084
  function canWriteDir$1(dir) {
4000
4085
  const root = String(dir || "").trim();
4001
4086
  if (!root) return false;
@@ -4071,11 +4156,14 @@ function getUnrealMcpPluginDiskStatus(params) {
4071
4156
  const checkedAtMs = Date.now();
4072
4157
  const engineRoot = String(params?.engineRoot || "").trim();
4073
4158
  const installScope = String(params?.installScope || "auto");
4074
- const projectUprojectPathRaw = typeof params?.projectUprojectPath === "string" ? params.projectUprojectPath.trim() : "";
4159
+ const requestedProjectUprojectPath = typeof params?.projectUprojectPath === "string" ? params.projectUprojectPath.trim() : "";
4075
4160
  if (!engineRoot) return { success: false, error: "Missing engineRoot." };
4076
4161
  if (!looksLikeEngineRoot(engineRoot)) {
4077
4162
  return { success: false, error: `Invalid engine root (expected an Unreal Engine install folder containing Engine/Plugins): ${engineRoot}` };
4078
4163
  }
4164
+ const installedEngine = isInstalledEngineRoot(engineRoot);
4165
+ const runningProject = detectRunningUnrealEditorProject({ engineRoot });
4166
+ const projectUprojectPathRaw = runningProject?.uprojectPath || requestedProjectUprojectPath;
4079
4167
  const enginePluginsDir = path__default.join(engineRoot, "Engine", "Plugins");
4080
4168
  const enginePluginDir = path__default.join(enginePluginsDir, "FlockbayMCP");
4081
4169
  const engineUpluginPath = path__default.join(enginePluginDir, "FlockbayMCP.uplugin");
@@ -4143,7 +4231,7 @@ function getUnrealMcpPluginDiskStatus(params) {
4143
4231
  }
4144
4232
  const engineInstalled = engineInfo.exists && engineInfo.descriptorOk && engineInfo.hasBinaries;
4145
4233
  const projectInstalled = Boolean(project && project.exists && project.descriptorOk && project.enabledInUproject);
4146
- const effectiveScope = installScope === "engine" ? "engine" : installScope === "project" ? "project" : engineInstalled ? "engine" : project && !engineInfo.enginePluginsWritable ? "project" : "engine";
4234
+ const effectiveScope = installScope === "engine" ? "engine" : installScope === "project" ? "project" : installedEngine && project ? "project" : engineInstalled ? "engine" : project && !engineInfo.enginePluginsWritable ? "project" : "engine";
4147
4235
  const conflict = engineInfo.conflicts.length > 0;
4148
4236
  const legacyConflict = engineInfo.legacy.length > 0;
4149
4237
  const baseInstalled = effectiveScope === "engine" ? engineInstalled : projectInstalled;
@@ -4858,12 +4946,14 @@ class ApiMachineClient {
4858
4946
  async (params) => {
4859
4947
  const engineRoot = String(params?.engineRoot || "").trim();
4860
4948
  const scope = String(params?.installScope || "auto");
4861
- const projectUprojectPath = typeof params?.projectUprojectPath === "string" ? params.projectUprojectPath.trim() : "";
4949
+ const requestedProjectUprojectPath = typeof params?.projectUprojectPath === "string" ? params.projectUprojectPath.trim() : "";
4862
4950
  const enginePluginsDir = path__default.join(engineRoot, "Engine", "Plugins");
4863
4951
  const enginePluginDir = path__default.join(enginePluginsDir, "FlockbayMCP");
4864
4952
  const enginePluginUplugin = path__default.join(enginePluginDir, "FlockbayMCP.uplugin");
4865
4953
  const enginePluginHasBinaries = fs__default.existsSync(path__default.join(enginePluginDir, "Binaries"));
4866
4954
  const installedEngine = isInstalledEngineRoot(engineRoot);
4955
+ const runningProject = installedEngine ? detectRunningUnrealEditorProject({ engineRoot }) : null;
4956
+ const projectUprojectPath = runningProject?.uprojectPath || requestedProjectUprojectPath;
4867
4957
  if (installedEngine) {
4868
4958
  const quarantine = quarantineLegacyEnginePlugins(engineRoot);
4869
4959
  if (!quarantine.ok) return { success: false, error: quarantine.errorMessage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flockbay",
3
- "version": "0.10.51",
3
+ "version": "0.10.52",
4
4
  "description": "Flockbay CLI (local agent + daemon)",
5
5
  "author": "Eduardo Orellana",
6
6
  "license": "UNLICENSED",