flockbay 0.10.43 → 0.10.45

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/README.md CHANGED
@@ -51,6 +51,10 @@ Run `flockbay --help` for the complete list of options.
51
51
  to mobile app
52
52
  - Claude CLI installed & logged in (`claude` command available in PATH)
53
53
 
54
+ ## Windows UX note
55
+
56
+ - Codex MCP child processes are started with hidden console windows to prevent blank `cmd.exe` popups during session startup.
57
+
54
58
  ## License
55
59
 
56
60
  Proprietary. Copyright (c) 2024-2026 Flockbay. All rights reserved.
@@ -3,7 +3,7 @@
3
3
  import { execFileSync } from 'node:child_process';
4
4
  import { existsSync } from 'node:fs';
5
5
  import { dirname, join } from 'node:path';
6
- import { fileURLToPath } from 'node:url';
6
+ import { fileURLToPath, pathToFileURL } from 'node:url';
7
7
 
8
8
  // Ensure Node flags to reduce noisy warnings on stdout (which could interfere with MCP).
9
9
  const hasNoWarnings = process.execArgv.includes('--no-warnings');
@@ -25,7 +25,13 @@ function resolveTsxImportArgs() {
25
25
  join(projectRoot, 'node_modules', 'tsx', 'dist', 'index.js'),
26
26
  ];
27
27
  const resolved = candidates.find(existsSync);
28
- return resolved ? ['--import', resolved] : ['--import', 'tsx'];
28
+ return resolved ? ['--import', toNodeSpecifier(resolved)] : ['--import', 'tsx'];
29
+ }
30
+
31
+ function toNodeSpecifier(p) {
32
+ if (process.platform !== 'win32') return p;
33
+ if (!/^[a-zA-Z]:[\\/]/.test(p)) return p;
34
+ return pathToFileURL(p).href;
29
35
  }
30
36
 
31
37
  if (!hasNoWarnings || !hasNoDeprecation || useTsx) {
package/bin/flockbay.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  import { execFileSync } from 'node:child_process';
4
4
  import { existsSync, statSync } from 'node:fs';
5
5
  import { dirname, join } from 'node:path';
6
- import { fileURLToPath } from 'node:url';
6
+ import { fileURLToPath, pathToFileURL } from 'node:url';
7
7
 
8
8
  // Ensure Node flags to reduce noisy warnings on stdout.
9
9
  const hasNoWarnings = process.execArgv.includes('--no-warnings');
@@ -54,7 +54,13 @@ function resolveTsxImportArgs() {
54
54
  join(projectRoot, 'node_modules', 'tsx', 'dist', 'index.js'),
55
55
  ];
56
56
  const resolved = candidates.find(existsSync);
57
- return resolved ? ['--import', resolved] : ['--import', 'tsx'];
57
+ return resolved ? ['--import', toNodeSpecifier(resolved)] : ['--import', 'tsx'];
58
+ }
59
+
60
+ function toNodeSpecifier(p) {
61
+ if (process.platform !== 'win32') return p;
62
+ if (!/^[a-zA-Z]:[\\/]/.test(p)) return p;
63
+ return pathToFileURL(p).href;
58
64
  }
59
65
 
60
66
  const rewrittenArgs = rewriteTopLevelAliases(process.argv.slice(2));
@@ -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-1s9-Oj5w.mjs';
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-Cq5rjOkx.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';
@@ -14,7 +14,7 @@ import fs$1, { readFile, access as access$1, mkdir, readdir, stat, writeFile, co
14
14
  import fs$2, { watch, access, mkdir as mkdir$1, writeFile as writeFile$1, rm } from 'fs/promises';
15
15
  import { useStdout, useInput, Box, Text, render } from 'ink';
16
16
  import React, { useState, useRef, useEffect, useCallback } from 'react';
17
- import { fileURLToPath } from 'node:url';
17
+ import { fileURLToPath, pathToFileURL } from 'node:url';
18
18
  import axios from 'axios';
19
19
  import 'socket.io-client';
20
20
  import { spawn as spawn$1, execFileSync as execFileSync$1 } from 'child_process';
@@ -5261,13 +5261,35 @@ function resolveTsxImportArgs(projectRoot) {
5261
5261
  join(projectRoot, "node_modules", "tsx", "dist", "index.js")
5262
5262
  ];
5263
5263
  const resolved = candidates.find(existsSync);
5264
- return resolved ? ["--import", resolved] : ["--import", "tsx"];
5264
+ return resolved ? ["--import", toNodeSpecifier(resolved)] : ["--import", "tsx"];
5265
+ }
5266
+ function toNodeSpecifier(p) {
5267
+ if (process$1.platform !== "win32") return p;
5268
+ if (!/^[a-zA-Z]:[\\/]/.test(p)) return p;
5269
+ return pathToFileURL(p).href;
5265
5270
  }
5266
5271
  function spawnFlockbayCLI(args, options = {}) {
5267
5272
  const projectRoot = projectPath();
5268
5273
  const distEntrypoint = join(projectRoot, "dist", "index.mjs");
5269
5274
  const devEntrypoint = join(projectRoot, "src", "index.ts");
5270
- const entrypoint = existsSync(distEntrypoint) ? distEntrypoint : devEntrypoint;
5275
+ const entrypoint = (() => {
5276
+ const forceSrc = process$1.env.FLOCKBAY_USE_SRC === "1";
5277
+ const forceDist = process$1.env.FLOCKBAY_USE_DIST === "1";
5278
+ const hasDist = existsSync(distEntrypoint);
5279
+ const hasDev = existsSync(devEntrypoint);
5280
+ if (forceSrc && hasDev) return devEntrypoint;
5281
+ if (forceDist && hasDist) return distEntrypoint;
5282
+ if (hasDist && hasDev) {
5283
+ try {
5284
+ const devTime = statSync(devEntrypoint).mtimeMs;
5285
+ const distTime = statSync(distEntrypoint).mtimeMs;
5286
+ if (devTime > distTime) return devEntrypoint;
5287
+ } catch {
5288
+ }
5289
+ return distEntrypoint;
5290
+ }
5291
+ return hasDist ? distEntrypoint : devEntrypoint;
5292
+ })();
5271
5293
  const useTsx = entrypoint.endsWith(".ts");
5272
5294
  const desiredCwd = "cwd" in options && typeof options.cwd === "string" ? options.cwd : process$1.cwd();
5273
5295
  const windowsHide = typeof options?.windowsHide === "boolean" ? Boolean(options.windowsHide) : process$1.platform === "win32";
@@ -5683,12 +5705,14 @@ async function enforceCliVersionPolicy(opts) {
5683
5705
  const policy = await fetchCliVersionPolicy({ serverUrl: opts.serverUrl, timeoutMs: opts.timeoutMs });
5684
5706
  const evaluation = evaluateCliVersion({ currentVersion, policy });
5685
5707
  if (evaluation.status === "update_required") {
5686
- const header = `CLI update required (installed: ${currentVersion}, required: ${evaluation.minimumSupported})`;
5687
- const msg = evaluation.message ? `
5688
- ${evaluation.message}` : "";
5689
- const help = `
5690
- Update: ${evaluation.updateCommand}`;
5691
- throw new Error(`${header}${msg}${help}`);
5708
+ try {
5709
+ opts.onUpdateRequired?.({
5710
+ minimumSupported: evaluation.minimumSupported,
5711
+ updateCommand: evaluation.updateCommand,
5712
+ message: evaluation.message
5713
+ });
5714
+ } catch {
5715
+ }
5692
5716
  }
5693
5717
  if (evaluation.status === "update_available") {
5694
5718
  try {
@@ -5789,6 +5813,14 @@ async function startDaemon() {
5789
5813
  serverUrl: configuration.serverUrl,
5790
5814
  currentVersion: packageJson.version,
5791
5815
  timeoutMs: Number.parseInt(process.env.FLOCKBAY_CLI_VERSION_CHECK_TIMEOUT_MS || "3000", 10) || 3e3,
5816
+ onUpdateRequired: ({ minimumSupported, updateCommand, message }) => {
5817
+ const note = message ? `
5818
+ ${message}` : "";
5819
+ console.error(
5820
+ `CLI update required (installed: ${packageJson.version}, required: ${minimumSupported})${note}
5821
+ Update: ${updateCommand}`
5822
+ );
5823
+ },
5792
5824
  onUpdateAvailable: ({ latest, updateCommand, message }) => {
5793
5825
  const note = message ? `
5794
5826
  ${message}` : "";
@@ -5798,12 +5830,7 @@ Update: ${updateCommand}`);
5798
5830
  });
5799
5831
  } catch (err) {
5800
5832
  const msg = err instanceof Error ? err.message : String(err);
5801
- if (/^CLI update required\b/i.test(msg)) {
5802
- console.error(msg);
5803
- process.exit(1);
5804
- } else {
5805
- logger.debug("[DAEMON RUN] CLI version policy check failed (non-fatal):", msg);
5806
- }
5833
+ logger.debug("[DAEMON RUN] CLI version policy check failed (non-fatal):", msg);
5807
5834
  }
5808
5835
  logger.debug("[DAEMON RUN] Auth and machine setup complete");
5809
5836
  const shouldStartUnrealMcp = String(process.env.FLOCKBAY_UNREAL_MCP_ENABLED || "").trim() === "1";
@@ -6579,10 +6606,18 @@ Log: ${logPath || `not found (check ${configuration.logsDir})`}` + formatLogExce
6579
6606
  cliPolicyCheckInFlight = true;
6580
6607
  lastCliPolicyCheckAtMs = Date.now();
6581
6608
  try {
6582
- await enforceCliVersionPolicy({
6609
+ const { evaluation } = await enforceCliVersionPolicy({
6583
6610
  serverUrl: configuration.serverUrl,
6584
6611
  currentVersion: packageJson.version,
6585
6612
  timeoutMs: Number.parseInt(process.env.FLOCKBAY_CLI_VERSION_CHECK_TIMEOUT_MS || "3000", 10) || 3e3,
6613
+ onUpdateRequired: ({ minimumSupported, updateCommand, message }) => {
6614
+ const note = message ? `
6615
+ ${message}` : "";
6616
+ logger.debug(
6617
+ `[DAEMON RUN] CLI update required (installed: ${packageJson.version}, required: ${minimumSupported}).${note}
6618
+ Update: ${updateCommand}`
6619
+ );
6620
+ },
6586
6621
  onUpdateAvailable: ({ latest, updateCommand, message }) => {
6587
6622
  const note = message ? `
6588
6623
  ${message}` : "";
@@ -6592,13 +6627,10 @@ Update: ${updateCommand}`
6592
6627
  );
6593
6628
  }
6594
6629
  });
6630
+ if (evaluation.status === "update_required") {
6631
+ }
6595
6632
  } catch (err) {
6596
6633
  const msg = err instanceof Error ? err.message : String(err);
6597
- if (/^CLI update required\b/i.test(msg)) {
6598
- logger.debug("[DAEMON RUN] CLI update required; shutting down daemon:", msg);
6599
- requestShutdown("exception", msg);
6600
- return;
6601
- }
6602
6634
  logger.debug("[DAEMON RUN] CLI version policy check failed (non-fatal):", msg);
6603
6635
  } finally {
6604
6636
  cliPolicyCheckInFlight = false;
@@ -14882,7 +14914,8 @@ async function startDaemonDetachedOrExit(opts) {
14882
14914
  console.log(chalk.gray(`Daemon: ${daemon?.pid ? `pid=${daemon.pid} port=${daemon.httpPort}` : "not running"}`));
14883
14915
  console.log("");
14884
14916
  if (opts?.openWebapp) openUrlBestEffort(configuration.webappUrl);
14885
- process.exit(0);
14917
+ process.exitCode = 0;
14918
+ return;
14886
14919
  }
14887
14920
  const authMismatch = lastUpsertStatus === 401 || /unauthorized/i.test(lastConnectError);
14888
14921
  if (authMismatch && !opts?.reauthAttempted) {
@@ -14953,7 +14986,8 @@ async function startDaemonDetachedOrExit(opts) {
14953
14986
  console.log(chalk.gray(`Daemon: ${daemon?.pid ? `pid=${daemon.pid} port=${daemon.httpPort}` : "not running"}`));
14954
14987
  console.log("");
14955
14988
  if (opts?.openWebapp) openUrlBestEffort(configuration.webappUrl);
14956
- process.exit(0);
14989
+ process.exitCode = 0;
14990
+ return;
14957
14991
  } else {
14958
14992
  const latest = await getLatestDaemonLog();
14959
14993
  if (latest?.path) console.error(`Latest daemon log: ${latest.path}`);
@@ -15083,7 +15117,7 @@ async function authAndSetupMachineIfNeeded() {
15083
15117
  process.exit(1);
15084
15118
  }
15085
15119
  try {
15086
- const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-BenVKITz.mjs');
15120
+ const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-JesDYgpP.mjs');
15087
15121
  const result = migrateUnrealMcpToFlockbayMcp({
15088
15122
  engineRoot,
15089
15123
  projectUprojectPath: project || void 0,
@@ -15222,7 +15256,7 @@ ${engineRoot}`, {
15222
15256
  } else if (subcommand === "codex") {
15223
15257
  try {
15224
15258
  await chdirToNearestUprojectRootIfPresent();
15225
- const { runCodex } = await import('./runCodex-aBjsormW.mjs');
15259
+ const { runCodex } = await import('./runCodex-DeNgXSEc.mjs');
15226
15260
  let startedBy = void 0;
15227
15261
  let sessionId = void 0;
15228
15262
  for (let i = 1; i < args.length; i++) {
@@ -15324,7 +15358,7 @@ ${engineRoot}`, {
15324
15358
  }
15325
15359
  try {
15326
15360
  await chdirToNearestUprojectRootIfPresent();
15327
- const { runGemini } = await import('./runGemini-D9bi1Ih3.mjs');
15361
+ const { runGemini } = await import('./runGemini-X5dTcwGa.mjs');
15328
15362
  let startedBy = void 0;
15329
15363
  let sessionId = void 0;
15330
15364
  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-DTy-RPNv.cjs');
6
+ var types = require('./types-AsI7cuLg.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');
@@ -1316,7 +1316,7 @@ function buildDaemonSafeEnv(baseEnv, binPath) {
1316
1316
  env[pathKey] = [...prepend, ...existingParts].join(pathSep);
1317
1317
  return env;
1318
1318
  }
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-Bih-iANW.cjs', document.baseURI).href)));
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-CpdfIEVW.cjs', document.baseURI).href)));
1320
1320
  const __dirname$1 = path.join(__filename$1, "..");
1321
1321
  function getGlobalClaudeVersion(claudeExecutable) {
1322
1322
  try {
@@ -5283,13 +5283,35 @@ function resolveTsxImportArgs(projectRoot) {
5283
5283
  path.join(projectRoot, "node_modules", "tsx", "dist", "index.js")
5284
5284
  ];
5285
5285
  const resolved = candidates.find(fs.existsSync);
5286
- return resolved ? ["--import", resolved] : ["--import", "tsx"];
5286
+ return resolved ? ["--import", toNodeSpecifier(resolved)] : ["--import", "tsx"];
5287
+ }
5288
+ function toNodeSpecifier(p) {
5289
+ if (process$1.platform !== "win32") return p;
5290
+ if (!/^[a-zA-Z]:[\\/]/.test(p)) return p;
5291
+ return node_url.pathToFileURL(p).href;
5287
5292
  }
5288
5293
  function spawnFlockbayCLI(args, options = {}) {
5289
5294
  const projectRoot = types.projectPath();
5290
5295
  const distEntrypoint = path.join(projectRoot, "dist", "index.mjs");
5291
5296
  const devEntrypoint = path.join(projectRoot, "src", "index.ts");
5292
- const entrypoint = fs.existsSync(distEntrypoint) ? distEntrypoint : devEntrypoint;
5297
+ const entrypoint = (() => {
5298
+ const forceSrc = process$1.env.FLOCKBAY_USE_SRC === "1";
5299
+ const forceDist = process$1.env.FLOCKBAY_USE_DIST === "1";
5300
+ const hasDist = fs.existsSync(distEntrypoint);
5301
+ const hasDev = fs.existsSync(devEntrypoint);
5302
+ if (forceSrc && hasDev) return devEntrypoint;
5303
+ if (forceDist && hasDist) return distEntrypoint;
5304
+ if (hasDist && hasDev) {
5305
+ try {
5306
+ const devTime = fs.statSync(devEntrypoint).mtimeMs;
5307
+ const distTime = fs.statSync(distEntrypoint).mtimeMs;
5308
+ if (devTime > distTime) return devEntrypoint;
5309
+ } catch {
5310
+ }
5311
+ return distEntrypoint;
5312
+ }
5313
+ return hasDist ? distEntrypoint : devEntrypoint;
5314
+ })();
5293
5315
  const useTsx = entrypoint.endsWith(".ts");
5294
5316
  const desiredCwd = "cwd" in options && typeof options.cwd === "string" ? options.cwd : process$1.cwd();
5295
5317
  const windowsHide = typeof options?.windowsHide === "boolean" ? Boolean(options.windowsHide) : process$1.platform === "win32";
@@ -5705,12 +5727,14 @@ async function enforceCliVersionPolicy(opts) {
5705
5727
  const policy = await fetchCliVersionPolicy({ serverUrl: opts.serverUrl, timeoutMs: opts.timeoutMs });
5706
5728
  const evaluation = evaluateCliVersion({ currentVersion, policy });
5707
5729
  if (evaluation.status === "update_required") {
5708
- const header = `CLI update required (installed: ${currentVersion}, required: ${evaluation.minimumSupported})`;
5709
- const msg = evaluation.message ? `
5710
- ${evaluation.message}` : "";
5711
- const help = `
5712
- Update: ${evaluation.updateCommand}`;
5713
- throw new Error(`${header}${msg}${help}`);
5730
+ try {
5731
+ opts.onUpdateRequired?.({
5732
+ minimumSupported: evaluation.minimumSupported,
5733
+ updateCommand: evaluation.updateCommand,
5734
+ message: evaluation.message
5735
+ });
5736
+ } catch {
5737
+ }
5714
5738
  }
5715
5739
  if (evaluation.status === "update_available") {
5716
5740
  try {
@@ -5811,6 +5835,14 @@ async function startDaemon() {
5811
5835
  serverUrl: types.configuration.serverUrl,
5812
5836
  currentVersion: types.packageJson.version,
5813
5837
  timeoutMs: Number.parseInt(process.env.FLOCKBAY_CLI_VERSION_CHECK_TIMEOUT_MS || "3000", 10) || 3e3,
5838
+ onUpdateRequired: ({ minimumSupported, updateCommand, message }) => {
5839
+ const note = message ? `
5840
+ ${message}` : "";
5841
+ console.error(
5842
+ `CLI update required (installed: ${types.packageJson.version}, required: ${minimumSupported})${note}
5843
+ Update: ${updateCommand}`
5844
+ );
5845
+ },
5814
5846
  onUpdateAvailable: ({ latest, updateCommand, message }) => {
5815
5847
  const note = message ? `
5816
5848
  ${message}` : "";
@@ -5820,12 +5852,7 @@ Update: ${updateCommand}`);
5820
5852
  });
5821
5853
  } catch (err) {
5822
5854
  const msg = err instanceof Error ? err.message : String(err);
5823
- if (/^CLI update required\b/i.test(msg)) {
5824
- console.error(msg);
5825
- process.exit(1);
5826
- } else {
5827
- types.logger.debug("[DAEMON RUN] CLI version policy check failed (non-fatal):", msg);
5828
- }
5855
+ types.logger.debug("[DAEMON RUN] CLI version policy check failed (non-fatal):", msg);
5829
5856
  }
5830
5857
  types.logger.debug("[DAEMON RUN] Auth and machine setup complete");
5831
5858
  const shouldStartUnrealMcp = String(process.env.FLOCKBAY_UNREAL_MCP_ENABLED || "").trim() === "1";
@@ -6601,10 +6628,18 @@ Log: ${logPath || `not found (check ${types.configuration.logsDir})`}` + formatL
6601
6628
  cliPolicyCheckInFlight = true;
6602
6629
  lastCliPolicyCheckAtMs = Date.now();
6603
6630
  try {
6604
- await enforceCliVersionPolicy({
6631
+ const { evaluation } = await enforceCliVersionPolicy({
6605
6632
  serverUrl: types.configuration.serverUrl,
6606
6633
  currentVersion: types.packageJson.version,
6607
6634
  timeoutMs: Number.parseInt(process.env.FLOCKBAY_CLI_VERSION_CHECK_TIMEOUT_MS || "3000", 10) || 3e3,
6635
+ onUpdateRequired: ({ minimumSupported, updateCommand, message }) => {
6636
+ const note = message ? `
6637
+ ${message}` : "";
6638
+ types.logger.debug(
6639
+ `[DAEMON RUN] CLI update required (installed: ${types.packageJson.version}, required: ${minimumSupported}).${note}
6640
+ Update: ${updateCommand}`
6641
+ );
6642
+ },
6608
6643
  onUpdateAvailable: ({ latest, updateCommand, message }) => {
6609
6644
  const note = message ? `
6610
6645
  ${message}` : "";
@@ -6614,13 +6649,10 @@ Update: ${updateCommand}`
6614
6649
  );
6615
6650
  }
6616
6651
  });
6652
+ if (evaluation.status === "update_required") {
6653
+ }
6617
6654
  } catch (err) {
6618
6655
  const msg = err instanceof Error ? err.message : String(err);
6619
- if (/^CLI update required\b/i.test(msg)) {
6620
- types.logger.debug("[DAEMON RUN] CLI update required; shutting down daemon:", msg);
6621
- requestShutdown("exception", msg);
6622
- return;
6623
- }
6624
6656
  types.logger.debug("[DAEMON RUN] CLI version policy check failed (non-fatal):", msg);
6625
6657
  } finally {
6626
6658
  cliPolicyCheckInFlight = false;
@@ -14904,7 +14936,8 @@ async function startDaemonDetachedOrExit(opts) {
14904
14936
  console.log(chalk.gray(`Daemon: ${daemon?.pid ? `pid=${daemon.pid} port=${daemon.httpPort}` : "not running"}`));
14905
14937
  console.log("");
14906
14938
  if (opts?.openWebapp) openUrlBestEffort(types.configuration.webappUrl);
14907
- process.exit(0);
14939
+ process.exitCode = 0;
14940
+ return;
14908
14941
  }
14909
14942
  const authMismatch = lastUpsertStatus === 401 || /unauthorized/i.test(lastConnectError);
14910
14943
  if (authMismatch && !opts?.reauthAttempted) {
@@ -14975,7 +15008,8 @@ async function startDaemonDetachedOrExit(opts) {
14975
15008
  console.log(chalk.gray(`Daemon: ${daemon?.pid ? `pid=${daemon.pid} port=${daemon.httpPort}` : "not running"}`));
14976
15009
  console.log("");
14977
15010
  if (opts?.openWebapp) openUrlBestEffort(types.configuration.webappUrl);
14978
- process.exit(0);
15011
+ process.exitCode = 0;
15012
+ return;
14979
15013
  } else {
14980
15014
  const latest = await types.getLatestDaemonLog();
14981
15015
  if (latest?.path) console.error(`Latest daemon log: ${latest.path}`);
@@ -15105,7 +15139,7 @@ async function authAndSetupMachineIfNeeded() {
15105
15139
  process.exit(1);
15106
15140
  }
15107
15141
  try {
15108
- const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin-CrSh19dY.cjs'); });
15142
+ const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin--pdww8Jg.cjs'); });
15109
15143
  const result = migrateUnrealMcpToFlockbayMcp({
15110
15144
  engineRoot,
15111
15145
  projectUprojectPath: project || void 0,
@@ -15244,7 +15278,7 @@ ${engineRoot}`, {
15244
15278
  } else if (subcommand === "codex") {
15245
15279
  try {
15246
15280
  await chdirToNearestUprojectRootIfPresent();
15247
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-CJa61r9H.cjs'); });
15281
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-t2FSXDl4.cjs'); });
15248
15282
  let startedBy = void 0;
15249
15283
  let sessionId = void 0;
15250
15284
  for (let i = 1; i < args.length; i++) {
@@ -15346,7 +15380,7 @@ ${engineRoot}`, {
15346
15380
  }
15347
15381
  try {
15348
15382
  await chdirToNearestUprojectRootIfPresent();
15349
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-gcPF3ASy.cjs'); });
15383
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-D__vNNGK.cjs'); });
15350
15384
  let startedBy = void 0;
15351
15385
  let sessionId = void 0;
15352
15386
  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-Bih-iANW.cjs');
5
- require('./types-DTy-RPNv.cjs');
4
+ require('./index-CpdfIEVW.cjs');
5
+ require('./types-AsI7cuLg.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-ZFx58JSw.mjs';
3
- import './types-1s9-Oj5w.mjs';
2
+ import './index-BRx_RPRT.mjs';
3
+ import './types-Cq5rjOkx.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-DTy-RPNv.cjs');
3
+ var types = require('./types-AsI7cuLg.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-1s9-Oj5w.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-Cq5rjOkx.mjs';
2
2
  import 'axios';
3
3
  import 'node:fs';
4
4
  import 'node:os';
@@ -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-DTy-RPNv.cjs');
5
+ var types = require('./types-AsI7cuLg.cjs');
6
6
  require('axios');
7
7
  require('node:os');
8
8
  require('node:events');
@@ -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-1s9-Oj5w.mjs';
3
+ import { i as installUnrealMcpPluginToEngine } from './types-Cq5rjOkx.mjs';
4
4
  import 'axios';
5
5
  import 'node:os';
6
6
  import 'node:events';
@@ -1,8 +1,7 @@
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-1s9-Oj5w.mjs';
3
+ import { l as logger, A as ApiClient, p as packageJson, c as configuration, r as readSettings, b as projectPath } from './types-Cq5rjOkx.mjs';
4
4
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
- import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
5
  import { z } from 'zod';
7
6
  import { ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js';
8
7
  import { randomUUID } from 'node:crypto';
@@ -10,7 +9,12 @@ import fs__default from 'node:fs';
10
9
  import os__default from 'node:os';
11
10
  import path__default, { resolve, join } from 'node:path';
12
11
  import { spawnSync } from 'node:child_process';
13
- 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-ZFx58JSw.mjs';
12
+ import spawn from 'cross-spawn';
13
+ import process$1 from 'node:process';
14
+ import { PassThrough } from 'node:stream';
15
+ import { getDefaultEnvironment } from '@modelcontextprotocol/sdk/client/stdio.js';
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-BRx_RPRT.mjs';
14
18
  import 'axios';
15
19
  import 'node:events';
16
20
  import 'socket.io-client';
@@ -22,7 +26,6 @@ import 'fs/promises';
22
26
  import 'crypto';
23
27
  import 'path';
24
28
  import 'url';
25
- import 'node:process';
26
29
  import 'os';
27
30
  import 'node:net';
28
31
  import 'http';
@@ -30,7 +33,6 @@ import 'open';
30
33
  import 'node:readline';
31
34
  import 'node:url';
32
35
  import 'ps-list';
33
- import 'cross-spawn';
34
36
  import 'tmp';
35
37
  import 'fastify';
36
38
  import 'fastify-type-provider-zod';
@@ -334,6 +336,111 @@ function buildMcpElicitationResult(decision, requestedSchemaRaw, options) {
334
336
  return { action, content, decision: codexDecision };
335
337
  }
336
338
 
339
+ class WindowsHiddenStdioClientTransport {
340
+ processRef;
341
+ abortController = new AbortController();
342
+ readBuffer = new ReadBuffer();
343
+ serverParams;
344
+ stderrStream = null;
345
+ platform;
346
+ onclose;
347
+ onerror;
348
+ onmessage;
349
+ constructor(server, options = {}) {
350
+ this.serverParams = server;
351
+ this.platform = options.platform ?? process$1.platform;
352
+ if (server.stderr === "pipe" || server.stderr === "overlapped") {
353
+ this.stderrStream = new PassThrough();
354
+ }
355
+ }
356
+ async start() {
357
+ if (this.processRef) {
358
+ throw new Error("WindowsHiddenStdioClientTransport already started");
359
+ }
360
+ await new Promise((resolve, reject) => {
361
+ this.processRef = spawn(this.serverParams.command, this.serverParams.args ?? [], {
362
+ env: {
363
+ ...getDefaultEnvironment(),
364
+ ...this.serverParams.env
365
+ },
366
+ stdio: ["pipe", "pipe", this.serverParams.stderr ?? "inherit"],
367
+ shell: false,
368
+ signal: this.abortController.signal,
369
+ windowsHide: this.platform === "win32",
370
+ cwd: this.serverParams.cwd
371
+ });
372
+ this.processRef.on("error", (error) => {
373
+ if (error.name === "AbortError") {
374
+ this.onclose?.();
375
+ return;
376
+ }
377
+ reject(error);
378
+ this.onerror?.(error);
379
+ });
380
+ this.processRef.on("spawn", () => {
381
+ resolve();
382
+ });
383
+ this.processRef.on("close", () => {
384
+ this.processRef = void 0;
385
+ this.onclose?.();
386
+ });
387
+ this.processRef.stdin?.on("error", (error) => {
388
+ this.onerror?.(error);
389
+ });
390
+ this.processRef.stdout?.on("data", (chunk) => {
391
+ this.readBuffer.append(chunk);
392
+ this.processReadBuffer();
393
+ });
394
+ this.processRef.stdout?.on("error", (error) => {
395
+ this.onerror?.(error);
396
+ });
397
+ if (this.stderrStream && this.processRef.stderr) {
398
+ this.processRef.stderr.pipe(this.stderrStream);
399
+ }
400
+ });
401
+ }
402
+ get stderr() {
403
+ if (this.stderrStream) {
404
+ return this.stderrStream;
405
+ }
406
+ return this.processRef?.stderr ?? null;
407
+ }
408
+ get pid() {
409
+ return this.processRef?.pid ?? null;
410
+ }
411
+ async close() {
412
+ this.abortController.abort();
413
+ this.processRef = void 0;
414
+ this.readBuffer.clear();
415
+ }
416
+ send(message) {
417
+ return new Promise((resolve) => {
418
+ if (!this.processRef?.stdin) {
419
+ throw new Error("Not connected");
420
+ }
421
+ const payload = serializeMessage(message);
422
+ if (this.processRef.stdin.write(payload)) {
423
+ resolve();
424
+ return;
425
+ }
426
+ this.processRef.stdin.once("drain", resolve);
427
+ });
428
+ }
429
+ processReadBuffer() {
430
+ while (true) {
431
+ try {
432
+ const message = this.readBuffer.readMessage();
433
+ if (message === null) {
434
+ break;
435
+ }
436
+ this.onmessage?.(message);
437
+ } catch (error) {
438
+ this.onerror?.(error);
439
+ }
440
+ }
441
+ }
442
+ }
443
+
337
444
  const DEFAULT_TIMEOUT = 14 * 24 * 60 * 60 * 1e3;
338
445
  function getCodexMcpCommand() {
339
446
  try {
@@ -788,7 +895,7 @@ class CodexMcpClient {
788
895
  const codexBin = resolveCodexBin();
789
896
  logger.debug(`[CodexMCP] Connecting to Codex MCP server using command: ${codexBin} ${mcpCommand}`);
790
897
  const env = buildCodexSpawnEnv(codexBin);
791
- this.transport = new StdioClientTransport({
898
+ this.transport = new WindowsHiddenStdioClientTransport({
792
899
  command: codexBin,
793
900
  args: [mcpCommand],
794
901
  env