flockbay 0.10.53 → 0.10.55

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.
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { execFileSync } from 'node:child_process';
4
4
  import { existsSync } from 'node:fs';
package/bin/flockbay.mjs CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { execFileSync } from 'node:child_process';
4
4
  import { existsSync, statSync } from 'node:fs';
@@ -5,10 +5,29 @@ var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
5
5
  var index_js = require('@modelcontextprotocol/sdk/client/index.js');
6
6
  var streamableHttp_js = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
7
7
  var z = require('zod');
8
+ var node_url = require('node:url');
8
9
 
10
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
11
  function getToolCallTimeoutMs(name, args) {
10
12
  return void 0;
11
13
  }
14
+ async function callToolWithReconnect(opts) {
15
+ let lastError = null;
16
+ for (let attempt = 0; attempt < 2; attempt += 1) {
17
+ try {
18
+ const client = await opts.getClient();
19
+ return await client.callTool(
20
+ { name: opts.name, arguments: opts.args },
21
+ void 0,
22
+ opts.timeout ? { timeout: opts.timeout } : void 0
23
+ );
24
+ } catch (error) {
25
+ lastError = error;
26
+ await opts.resetClient();
27
+ }
28
+ }
29
+ throw lastError instanceof Error ? lastError : new Error(String(lastError ?? "Unknown MCP bridge error"));
30
+ }
12
31
  function parseArgs(argv) {
13
32
  let url = null;
14
33
  for (let i = 0; i < argv.length; i++) {
@@ -30,6 +49,7 @@ async function main() {
30
49
  process.exit(2);
31
50
  }
32
51
  let httpClient = null;
52
+ let httpTransport = null;
33
53
  async function ensureHttpClient() {
34
54
  if (httpClient) return httpClient;
35
55
  const client = new index_js.Client(
@@ -39,8 +59,23 @@ async function main() {
39
59
  const transport = new streamableHttp_js.StreamableHTTPClientTransport(new URL(baseUrl));
40
60
  await client.connect(transport);
41
61
  httpClient = client;
62
+ httpTransport = transport;
42
63
  return client;
43
64
  }
65
+ async function resetHttpClient() {
66
+ const prevClient = httpClient;
67
+ const prevTransport = httpTransport;
68
+ httpClient = null;
69
+ httpTransport = null;
70
+ try {
71
+ await prevClient?.close?.();
72
+ } catch {
73
+ }
74
+ try {
75
+ await prevTransport?.close?.();
76
+ } catch {
77
+ }
78
+ }
44
79
  const server = new mcp_js.McpServer({
45
80
  name: "MCP Local Connector",
46
81
  version: "1.0.0"
@@ -51,13 +86,14 @@ async function main() {
51
86
  { title, description, inputSchema },
52
87
  async (args) => {
53
88
  try {
54
- const client = await ensureHttpClient();
55
89
  const timeout = getToolCallTimeoutMs(name, args);
56
- const response = await client.callTool(
57
- { name, arguments: args },
58
- void 0,
59
- timeout ? { timeout } : void 0
60
- );
90
+ const response = await callToolWithReconnect({
91
+ getClient: ensureHttpClient,
92
+ resetClient: resetHttpClient,
93
+ name,
94
+ args,
95
+ timeout
96
+ });
61
97
  return response;
62
98
  } catch (error) {
63
99
  return {
@@ -756,11 +792,24 @@ async function main() {
756
792
  const stdio = new stdio_js.StdioServerTransport();
757
793
  await server.connect(stdio);
758
794
  }
759
- main().catch((err) => {
795
+ const isExecutedDirectly = (() => {
796
+ const argv1 = process.argv[1];
797
+ if (!argv1) return false;
760
798
  try {
761
- process.stderr.write(`[flockbay-mcp] Fatal: ${err instanceof Error ? err.message : String(err)}
762
- `);
763
- } finally {
764
- process.exit(1);
799
+ return (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('codex/flockbayMcpStdioBridge.cjs', document.baseURI).href)) === node_url.pathToFileURL(argv1).href;
800
+ } catch {
801
+ return false;
765
802
  }
766
- });
803
+ })();
804
+ if (isExecutedDirectly) {
805
+ main().catch((err) => {
806
+ try {
807
+ process.stderr.write(`[flockbay-mcp] Fatal: ${err instanceof Error ? err.message : String(err)}
808
+ `);
809
+ } finally {
810
+ process.exit(1);
811
+ }
812
+ });
813
+ }
814
+
815
+ exports.callToolWithReconnect = callToolWithReconnect;
@@ -1,2 +1,25 @@
1
+ /**
2
+ * MCP STDIO Bridge
3
+ *
4
+ * Minimal STDIO MCP server exposing a small set of tools.
5
+ * On invocation it forwards the tool call to an existing HTTP MCP server
6
+ * using the StreamableHTTPClientTransport.
7
+ *
8
+ * Configure the target HTTP MCP URL via env var `FLOCKBAY_HTTP_MCP_URL` or
9
+ * via CLI flag `--url <http://127.0.0.1:PORT>`.
10
+ *
11
+ * Note: This process must not print to stdout as it would break MCP STDIO.
12
+ */
13
+ type HttpMcpClientLike = {
14
+ callTool: (...args: any[]) => Promise<any>;
15
+ close?: () => Promise<void> | void;
16
+ };
17
+ declare function callToolWithReconnect<TClient extends HttpMcpClientLike>(opts: {
18
+ getClient: () => Promise<TClient>;
19
+ resetClient: () => Promise<void>;
20
+ name: string;
21
+ args: Record<string, any>;
22
+ timeout?: number;
23
+ }): Promise<any>;
1
24
 
2
- export { };
25
+ export { callToolWithReconnect };
@@ -1,2 +1,25 @@
1
+ /**
2
+ * MCP STDIO Bridge
3
+ *
4
+ * Minimal STDIO MCP server exposing a small set of tools.
5
+ * On invocation it forwards the tool call to an existing HTTP MCP server
6
+ * using the StreamableHTTPClientTransport.
7
+ *
8
+ * Configure the target HTTP MCP URL via env var `FLOCKBAY_HTTP_MCP_URL` or
9
+ * via CLI flag `--url <http://127.0.0.1:PORT>`.
10
+ *
11
+ * Note: This process must not print to stdout as it would break MCP STDIO.
12
+ */
13
+ type HttpMcpClientLike = {
14
+ callTool: (...args: any[]) => Promise<any>;
15
+ close?: () => Promise<void> | void;
16
+ };
17
+ declare function callToolWithReconnect<TClient extends HttpMcpClientLike>(opts: {
18
+ getClient: () => Promise<TClient>;
19
+ resetClient: () => Promise<void>;
20
+ name: string;
21
+ args: Record<string, any>;
22
+ timeout?: number;
23
+ }): Promise<any>;
1
24
 
2
- export { };
25
+ export { callToolWithReconnect };
@@ -3,10 +3,28 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
3
3
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
4
4
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
5
5
  import { z } from 'zod';
6
+ import { pathToFileURL } from 'node:url';
6
7
 
7
8
  function getToolCallTimeoutMs(name, args) {
8
9
  return void 0;
9
10
  }
11
+ async function callToolWithReconnect(opts) {
12
+ let lastError = null;
13
+ for (let attempt = 0; attempt < 2; attempt += 1) {
14
+ try {
15
+ const client = await opts.getClient();
16
+ return await client.callTool(
17
+ { name: opts.name, arguments: opts.args },
18
+ void 0,
19
+ opts.timeout ? { timeout: opts.timeout } : void 0
20
+ );
21
+ } catch (error) {
22
+ lastError = error;
23
+ await opts.resetClient();
24
+ }
25
+ }
26
+ throw lastError instanceof Error ? lastError : new Error(String(lastError ?? "Unknown MCP bridge error"));
27
+ }
10
28
  function parseArgs(argv) {
11
29
  let url = null;
12
30
  for (let i = 0; i < argv.length; i++) {
@@ -28,6 +46,7 @@ async function main() {
28
46
  process.exit(2);
29
47
  }
30
48
  let httpClient = null;
49
+ let httpTransport = null;
31
50
  async function ensureHttpClient() {
32
51
  if (httpClient) return httpClient;
33
52
  const client = new Client(
@@ -37,8 +56,23 @@ async function main() {
37
56
  const transport = new StreamableHTTPClientTransport(new URL(baseUrl));
38
57
  await client.connect(transport);
39
58
  httpClient = client;
59
+ httpTransport = transport;
40
60
  return client;
41
61
  }
62
+ async function resetHttpClient() {
63
+ const prevClient = httpClient;
64
+ const prevTransport = httpTransport;
65
+ httpClient = null;
66
+ httpTransport = null;
67
+ try {
68
+ await prevClient?.close?.();
69
+ } catch {
70
+ }
71
+ try {
72
+ await prevTransport?.close?.();
73
+ } catch {
74
+ }
75
+ }
42
76
  const server = new McpServer({
43
77
  name: "MCP Local Connector",
44
78
  version: "1.0.0"
@@ -49,13 +83,14 @@ async function main() {
49
83
  { title, description, inputSchema },
50
84
  async (args) => {
51
85
  try {
52
- const client = await ensureHttpClient();
53
86
  const timeout = getToolCallTimeoutMs(name, args);
54
- const response = await client.callTool(
55
- { name, arguments: args },
56
- void 0,
57
- timeout ? { timeout } : void 0
58
- );
87
+ const response = await callToolWithReconnect({
88
+ getClient: ensureHttpClient,
89
+ resetClient: resetHttpClient,
90
+ name,
91
+ args,
92
+ timeout
93
+ });
59
94
  return response;
60
95
  } catch (error) {
61
96
  return {
@@ -754,11 +789,24 @@ async function main() {
754
789
  const stdio = new StdioServerTransport();
755
790
  await server.connect(stdio);
756
791
  }
757
- main().catch((err) => {
792
+ const isExecutedDirectly = (() => {
793
+ const argv1 = process.argv[1];
794
+ if (!argv1) return false;
758
795
  try {
759
- process.stderr.write(`[flockbay-mcp] Fatal: ${err instanceof Error ? err.message : String(err)}
760
- `);
761
- } finally {
762
- process.exit(1);
796
+ return import.meta.url === pathToFileURL(argv1).href;
797
+ } catch {
798
+ return false;
763
799
  }
764
- });
800
+ })();
801
+ if (isExecutedDirectly) {
802
+ main().catch((err) => {
803
+ try {
804
+ process.stderr.write(`[flockbay-mcp] Fatal: ${err instanceof Error ? err.message : String(err)}
805
+ `);
806
+ } finally {
807
+ process.exit(1);
808
+ }
809
+ });
810
+ }
811
+
812
+ export { callToolWithReconnect };
@@ -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-Dsn3eNAB.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-xflr9vd_.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';
@@ -505,7 +505,8 @@ async function claudeLocal(opts) {
505
505
  stdio: ["inherit", "inherit", "inherit", "pipe"],
506
506
  signal: opts.abort,
507
507
  cwd: opts.path,
508
- env
508
+ env,
509
+ windowsHide: process$1.platform === "win32"
509
510
  });
510
511
  if (child.stdio[3]) {
511
512
  const rl = createInterface({
@@ -1306,16 +1307,23 @@ const __dirname$1 = join(__filename$1, "..");
1306
1307
  function getGlobalClaudeVersion(claudeExecutable) {
1307
1308
  try {
1308
1309
  const cleanEnv = buildDaemonSafeEnv(getCleanEnv(), claudeExecutable);
1309
- const output = (claudeExecutable.includes("/") || claudeExecutable.includes("\\")) && !claudeExecutable.startsWith("\\\\") ? execFileSync(claudeExecutable, ["--version"], {
1310
- encoding: "utf8",
1311
- stdio: ["pipe", "pipe", "pipe"],
1312
- cwd: homedir(),
1313
- env: cleanEnv
1314
- }).trim() : execSync("claude --version", {
1310
+ const isPathLike = (claudeExecutable.includes("/") || claudeExecutable.includes("\\")) && !claudeExecutable.startsWith("\\\\");
1311
+ const output = isPathLike ? execFileSync(
1312
+ /\.(?:c|m)?js$/i.test(claudeExecutable) ? process$1.execPath : claudeExecutable,
1313
+ /\.(?:c|m)?js$/i.test(claudeExecutable) ? [claudeExecutable, "--version"] : ["--version"],
1314
+ {
1315
+ encoding: "utf8",
1316
+ stdio: ["pipe", "pipe", "pipe"],
1317
+ cwd: homedir(),
1318
+ env: cleanEnv,
1319
+ windowsHide: process$1.platform === "win32"
1320
+ }
1321
+ ).trim() : execSync("claude --version", {
1315
1322
  encoding: "utf8",
1316
1323
  stdio: ["pipe", "pipe", "pipe"],
1317
1324
  cwd: homedir(),
1318
- env: cleanEnv
1325
+ env: cleanEnv,
1326
+ windowsHide: process$1.platform === "win32"
1319
1327
  }).trim();
1320
1328
  const match = output.match(/(\d+\.\d+\.\d+)/);
1321
1329
  logger.debug(`[Claude SDK] Global claude --version output: ${output}`);
@@ -1372,6 +1380,7 @@ function getCleanEnv() {
1372
1380
  }
1373
1381
  function resolveClaudeBin() {
1374
1382
  const existsExecutable = (p) => {
1383
+ if (process$1.platform === "win32") return existsSync(p);
1375
1384
  try {
1376
1385
  accessSync(p, constants.X_OK);
1377
1386
  return true;
@@ -1379,6 +1388,31 @@ function resolveClaudeBin() {
1379
1388
  return false;
1380
1389
  }
1381
1390
  };
1391
+ if (process$1.platform === "win32") {
1392
+ const windowsCandidates = [
1393
+ join(homedir(), "AppData", "Roaming", "npm", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
1394
+ join(String(process$1.env.APPDATA || ""), "npm", "node_modules", "@anthropic-ai", "claude-code", "cli.js")
1395
+ ].filter(Boolean);
1396
+ for (const candidate of windowsCandidates) {
1397
+ if (candidate && existsSync(candidate)) return candidate;
1398
+ }
1399
+ try {
1400
+ const result = execFileSync("where.exe", ["claude.cmd"], {
1401
+ encoding: "utf8",
1402
+ stdio: ["pipe", "pipe", "pipe"],
1403
+ cwd: homedir(),
1404
+ env: buildDaemonSafeEnv(getCleanEnv()),
1405
+ windowsHide: true
1406
+ }).trim();
1407
+ const first = result.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
1408
+ if (first) {
1409
+ const npmDir = dirname(first);
1410
+ const cliJs = join(npmDir, "node_modules", "@anthropic-ai", "claude-code", "cli.js");
1411
+ if (existsSync(cliJs)) return cliJs;
1412
+ }
1413
+ } catch {
1414
+ }
1415
+ }
1382
1416
  const candidates = [
1383
1417
  join(homedir(), ".local", "bin", "claude"),
1384
1418
  "/opt/homebrew/bin/claude",
@@ -1433,7 +1467,8 @@ function findGlobalClaudePath() {
1433
1467
  encoding: "utf8",
1434
1468
  stdio: ["pipe", "pipe", "pipe"],
1435
1469
  cwd: homeDir,
1436
- env: cleanEnv
1470
+ env: cleanEnv,
1471
+ windowsHide: process$1.platform === "win32"
1437
1472
  });
1438
1473
  logger.debug("[Claude SDK] Global claude command available (checked with clean PATH)");
1439
1474
  return "claude";
@@ -1504,8 +1539,11 @@ async function streamToStdin(stream, stdin, abort) {
1504
1539
  stdin.end();
1505
1540
  }
1506
1541
 
1542
+ function stripAnsi(text) {
1543
+ return String(text || "").replace(/\u001b\[[0-9;?]*[ -/]*[@-~]/g, "");
1544
+ }
1507
1545
  function trimProcessDiagnostic(text) {
1508
- const lines = String(text || "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
1546
+ const lines = stripAnsi(text).split(/\r?\n/).map((line) => line.trim()).filter(Boolean).filter((line) => !/^Using Claude Code v[\d.]+ from /i.test(line));
1509
1547
  if (lines.length === 0) return "";
1510
1548
  return lines.slice(-8).join("\n");
1511
1549
  }
@@ -1796,6 +1834,7 @@ function query(config) {
1796
1834
  stdio: ["pipe", "pipe", "pipe"],
1797
1835
  signal: config.options?.abort,
1798
1836
  env: spawnEnv,
1837
+ windowsHide: process$1.platform === "win32",
1799
1838
  // Only use a shell on Windows when spawning a bare command (e.g. "claude").
1800
1839
  // Passing large `--allowedTools` lists through cmd.exe can hit the ~8k command line limit.
1801
1840
  shell: isCommandOnly && process$1.platform === "win32"
@@ -7796,7 +7835,12 @@ async function writeFastPreviewState(statePath, state) {
7796
7835
  }
7797
7836
  async function runUnrealAndCapture(args) {
7798
7837
  return await new Promise((resolve, reject) => {
7799
- const child = spawn(args.cmd, args.unrealArgs, { stdio: ["ignore", "pipe", "pipe"], cwd: args.cwd, env: args.env });
7838
+ const child = spawn(args.cmd, args.unrealArgs, {
7839
+ stdio: ["ignore", "pipe", "pipe"],
7840
+ cwd: args.cwd,
7841
+ env: args.env,
7842
+ windowsHide: process.platform === "win32"
7843
+ });
7800
7844
  const timeout = setTimeout(() => {
7801
7845
  child.kill("SIGKILL");
7802
7846
  reject(new Error(`Timed out after ${args.timeoutMs}ms`));
@@ -7823,7 +7867,12 @@ async function runUnrealAndCapture(args) {
7823
7867
  }
7824
7868
  async function runCmdAndCapture(args) {
7825
7869
  return await new Promise((resolvePromise, rejectPromise) => {
7826
- const child = spawn(args.cmd, args.cmdArgs, { stdio: ["ignore", "pipe", "pipe"], cwd: args.cwd, env: args.env });
7870
+ const child = spawn(args.cmd, args.cmdArgs, {
7871
+ stdio: ["ignore", "pipe", "pipe"],
7872
+ cwd: args.cwd,
7873
+ env: args.env,
7874
+ windowsHide: process.platform === "win32"
7875
+ });
7827
7876
  const timeout = setTimeout(() => {
7828
7877
  child.kill("SIGKILL");
7829
7878
  rejectPromise(new Error(`Timed out after ${args.timeoutMs}ms`));
@@ -8234,7 +8283,11 @@ async function startFlockbayServer(client, options) {
8234
8283
  };
8235
8284
  const runCommandCapture = async (cmd, args) => {
8236
8285
  return new Promise((resolve) => {
8237
- const child = spawn(cmd, args, { shell: false, stdio: ["ignore", "pipe", "pipe"] });
8286
+ const child = spawn(cmd, args, {
8287
+ shell: false,
8288
+ stdio: ["ignore", "pipe", "pipe"],
8289
+ windowsHide: process.platform === "win32"
8290
+ });
8238
8291
  let stdout = "";
8239
8292
  let stderr = "";
8240
8293
  child.stdout?.on("data", (c) => stdout += c.toString("utf8"));
@@ -8297,7 +8350,11 @@ ${res.stderr}`;
8297
8350
  const exe = getUnrealEditorExe(engineRoot);
8298
8351
  if (!exe) throw new Error(`Unsupported platform for Unreal Editor launch: ${process.platform}`);
8299
8352
  if (!existsSync(exe)) throw new Error(`Unreal Editor binary not found: ${exe}`);
8300
- const child = spawn(exe, [uprojectPath, ...extraArgs], { detached: true, stdio: "ignore" });
8353
+ const child = spawn(exe, [uprojectPath, ...extraArgs], {
8354
+ detached: true,
8355
+ stdio: "ignore",
8356
+ windowsHide: process.platform === "win32"
8357
+ });
8301
8358
  child.unref();
8302
8359
  const pid = typeof child.pid === "number" ? child.pid : 0;
8303
8360
  state.launched = {
@@ -10258,7 +10315,11 @@ ${chunk}` }],
10258
10315
  async function isUnrealEditorProcessRunningBestEffortGlobal() {
10259
10316
  const runCommandCapture = async (cmd, args) => {
10260
10317
  return new Promise((resolve) => {
10261
- const child = spawn(cmd, args, { shell: false, stdio: ["ignore", "pipe", "pipe"] });
10318
+ const child = spawn(cmd, args, {
10319
+ shell: false,
10320
+ stdio: ["ignore", "pipe", "pipe"],
10321
+ windowsHide: process.platform === "win32"
10322
+ });
10262
10323
  let stdout = "";
10263
10324
  let stderr = "";
10264
10325
  child.stdout?.on("data", (c) => stdout += c.toString("utf8"));
@@ -15247,7 +15308,7 @@ async function authAndSetupMachineIfNeeded() {
15247
15308
  process.exit(1);
15248
15309
  }
15249
15310
  try {
15250
- const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-_Voh9wUv.mjs');
15311
+ const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-BVy0Kw-1.mjs');
15251
15312
  const result = migrateUnrealMcpToFlockbayMcp({
15252
15313
  engineRoot,
15253
15314
  projectUprojectPath: project || void 0,
@@ -15403,7 +15464,7 @@ ${engineRoot}`;
15403
15464
  } else if (subcommand === "codex") {
15404
15465
  try {
15405
15466
  await chdirToNearestUprojectRootIfPresent();
15406
- const { runCodex } = await import('./runCodex-CBPYccVV.mjs');
15467
+ const { runCodex } = await import('./runCodex-BCWCnen8.mjs');
15407
15468
  let startedBy = void 0;
15408
15469
  let sessionId = void 0;
15409
15470
  for (let i = 1; i < args.length; i++) {
@@ -15505,7 +15566,7 @@ ${engineRoot}`;
15505
15566
  }
15506
15567
  try {
15507
15568
  await chdirToNearestUprojectRootIfPresent();
15508
- const { runGemini } = await import('./runGemini-ibnNbOeF.mjs');
15569
+ const { runGemini } = await import('./runGemini-Dq2TkMwC.mjs');
15509
15570
  let startedBy = void 0;
15510
15571
  let sessionId = void 0;
15511
15572
  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-DQ4IqofE.cjs');
6
+ var types = require('./types-reygbXgh.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');
@@ -527,7 +527,8 @@ async function claudeLocal(opts) {
527
527
  stdio: ["inherit", "inherit", "inherit", "pipe"],
528
528
  signal: opts.abort,
529
529
  cwd: opts.path,
530
- env
530
+ env,
531
+ windowsHide: process$1.platform === "win32"
531
532
  });
532
533
  if (child.stdio[3]) {
533
534
  const rl = node_readline.createInterface({
@@ -1323,21 +1324,28 @@ function buildDaemonSafeEnv(baseEnv, binPath) {
1323
1324
  env[pathKey] = [...prepend, ...existingParts].join(pathSep);
1324
1325
  return env;
1325
1326
  }
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-CG7Ouk31.cjs', document.baseURI).href)));
1327
+ 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-BDpihows.cjs', document.baseURI).href)));
1327
1328
  const __dirname$1 = path.join(__filename$1, "..");
1328
1329
  function getGlobalClaudeVersion(claudeExecutable) {
1329
1330
  try {
1330
1331
  const cleanEnv = buildDaemonSafeEnv(getCleanEnv(), claudeExecutable);
1331
- const output = (claudeExecutable.includes("/") || claudeExecutable.includes("\\")) && !claudeExecutable.startsWith("\\\\") ? node_child_process.execFileSync(claudeExecutable, ["--version"], {
1332
- encoding: "utf8",
1333
- stdio: ["pipe", "pipe", "pipe"],
1334
- cwd: os.homedir(),
1335
- env: cleanEnv
1336
- }).trim() : node_child_process.execSync("claude --version", {
1332
+ const isPathLike = (claudeExecutable.includes("/") || claudeExecutable.includes("\\")) && !claudeExecutable.startsWith("\\\\");
1333
+ const output = isPathLike ? node_child_process.execFileSync(
1334
+ /\.(?:c|m)?js$/i.test(claudeExecutable) ? process$1.execPath : claudeExecutable,
1335
+ /\.(?:c|m)?js$/i.test(claudeExecutable) ? [claudeExecutable, "--version"] : ["--version"],
1336
+ {
1337
+ encoding: "utf8",
1338
+ stdio: ["pipe", "pipe", "pipe"],
1339
+ cwd: os.homedir(),
1340
+ env: cleanEnv,
1341
+ windowsHide: process$1.platform === "win32"
1342
+ }
1343
+ ).trim() : node_child_process.execSync("claude --version", {
1337
1344
  encoding: "utf8",
1338
1345
  stdio: ["pipe", "pipe", "pipe"],
1339
1346
  cwd: os.homedir(),
1340
- env: cleanEnv
1347
+ env: cleanEnv,
1348
+ windowsHide: process$1.platform === "win32"
1341
1349
  }).trim();
1342
1350
  const match = output.match(/(\d+\.\d+\.\d+)/);
1343
1351
  types.logger.debug(`[Claude SDK] Global claude --version output: ${output}`);
@@ -1394,6 +1402,7 @@ function getCleanEnv() {
1394
1402
  }
1395
1403
  function resolveClaudeBin() {
1396
1404
  const existsExecutable = (p) => {
1405
+ if (process$1.platform === "win32") return fs.existsSync(p);
1397
1406
  try {
1398
1407
  fs.accessSync(p, fs.constants.X_OK);
1399
1408
  return true;
@@ -1401,6 +1410,31 @@ function resolveClaudeBin() {
1401
1410
  return false;
1402
1411
  }
1403
1412
  };
1413
+ if (process$1.platform === "win32") {
1414
+ const windowsCandidates = [
1415
+ path.join(os.homedir(), "AppData", "Roaming", "npm", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
1416
+ path.join(String(process$1.env.APPDATA || ""), "npm", "node_modules", "@anthropic-ai", "claude-code", "cli.js")
1417
+ ].filter(Boolean);
1418
+ for (const candidate of windowsCandidates) {
1419
+ if (candidate && fs.existsSync(candidate)) return candidate;
1420
+ }
1421
+ try {
1422
+ const result = node_child_process.execFileSync("where.exe", ["claude.cmd"], {
1423
+ encoding: "utf8",
1424
+ stdio: ["pipe", "pipe", "pipe"],
1425
+ cwd: os.homedir(),
1426
+ env: buildDaemonSafeEnv(getCleanEnv()),
1427
+ windowsHide: true
1428
+ }).trim();
1429
+ const first = result.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
1430
+ if (first) {
1431
+ const npmDir = path.dirname(first);
1432
+ const cliJs = path.join(npmDir, "node_modules", "@anthropic-ai", "claude-code", "cli.js");
1433
+ if (fs.existsSync(cliJs)) return cliJs;
1434
+ }
1435
+ } catch {
1436
+ }
1437
+ }
1404
1438
  const candidates = [
1405
1439
  path.join(os.homedir(), ".local", "bin", "claude"),
1406
1440
  "/opt/homebrew/bin/claude",
@@ -1455,7 +1489,8 @@ function findGlobalClaudePath() {
1455
1489
  encoding: "utf8",
1456
1490
  stdio: ["pipe", "pipe", "pipe"],
1457
1491
  cwd: homeDir,
1458
- env: cleanEnv
1492
+ env: cleanEnv,
1493
+ windowsHide: process$1.platform === "win32"
1459
1494
  });
1460
1495
  types.logger.debug("[Claude SDK] Global claude command available (checked with clean PATH)");
1461
1496
  return "claude";
@@ -1526,8 +1561,11 @@ async function streamToStdin(stream, stdin, abort) {
1526
1561
  stdin.end();
1527
1562
  }
1528
1563
 
1564
+ function stripAnsi(text) {
1565
+ return String(text || "").replace(/\u001b\[[0-9;?]*[ -/]*[@-~]/g, "");
1566
+ }
1529
1567
  function trimProcessDiagnostic(text) {
1530
- const lines = String(text || "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
1568
+ const lines = stripAnsi(text).split(/\r?\n/).map((line) => line.trim()).filter(Boolean).filter((line) => !/^Using Claude Code v[\d.]+ from /i.test(line));
1531
1569
  if (lines.length === 0) return "";
1532
1570
  return lines.slice(-8).join("\n");
1533
1571
  }
@@ -1818,6 +1856,7 @@ function query(config) {
1818
1856
  stdio: ["pipe", "pipe", "pipe"],
1819
1857
  signal: config.options?.abort,
1820
1858
  env: spawnEnv,
1859
+ windowsHide: process$1.platform === "win32",
1821
1860
  // Only use a shell on Windows when spawning a bare command (e.g. "claude").
1822
1861
  // Passing large `--allowedTools` lists through cmd.exe can hit the ~8k command line limit.
1823
1862
  shell: isCommandOnly && process$1.platform === "win32"
@@ -7818,7 +7857,12 @@ async function writeFastPreviewState(statePath, state) {
7818
7857
  }
7819
7858
  async function runUnrealAndCapture(args) {
7820
7859
  return await new Promise((resolve, reject) => {
7821
- const child = node_child_process.spawn(args.cmd, args.unrealArgs, { stdio: ["ignore", "pipe", "pipe"], cwd: args.cwd, env: args.env });
7860
+ const child = node_child_process.spawn(args.cmd, args.unrealArgs, {
7861
+ stdio: ["ignore", "pipe", "pipe"],
7862
+ cwd: args.cwd,
7863
+ env: args.env,
7864
+ windowsHide: process.platform === "win32"
7865
+ });
7822
7866
  const timeout = setTimeout(() => {
7823
7867
  child.kill("SIGKILL");
7824
7868
  reject(new Error(`Timed out after ${args.timeoutMs}ms`));
@@ -7845,7 +7889,12 @@ async function runUnrealAndCapture(args) {
7845
7889
  }
7846
7890
  async function runCmdAndCapture(args) {
7847
7891
  return await new Promise((resolvePromise, rejectPromise) => {
7848
- const child = node_child_process.spawn(args.cmd, args.cmdArgs, { stdio: ["ignore", "pipe", "pipe"], cwd: args.cwd, env: args.env });
7892
+ const child = node_child_process.spawn(args.cmd, args.cmdArgs, {
7893
+ stdio: ["ignore", "pipe", "pipe"],
7894
+ cwd: args.cwd,
7895
+ env: args.env,
7896
+ windowsHide: process.platform === "win32"
7897
+ });
7849
7898
  const timeout = setTimeout(() => {
7850
7899
  child.kill("SIGKILL");
7851
7900
  rejectPromise(new Error(`Timed out after ${args.timeoutMs}ms`));
@@ -8256,7 +8305,11 @@ async function startFlockbayServer(client, options) {
8256
8305
  };
8257
8306
  const runCommandCapture = async (cmd, args) => {
8258
8307
  return new Promise((resolve) => {
8259
- const child = node_child_process.spawn(cmd, args, { shell: false, stdio: ["ignore", "pipe", "pipe"] });
8308
+ const child = node_child_process.spawn(cmd, args, {
8309
+ shell: false,
8310
+ stdio: ["ignore", "pipe", "pipe"],
8311
+ windowsHide: process.platform === "win32"
8312
+ });
8260
8313
  let stdout = "";
8261
8314
  let stderr = "";
8262
8315
  child.stdout?.on("data", (c) => stdout += c.toString("utf8"));
@@ -8319,7 +8372,11 @@ ${res.stderr}`;
8319
8372
  const exe = getUnrealEditorExe(engineRoot);
8320
8373
  if (!exe) throw new Error(`Unsupported platform for Unreal Editor launch: ${process.platform}`);
8321
8374
  if (!fs.existsSync(exe)) throw new Error(`Unreal Editor binary not found: ${exe}`);
8322
- const child = node_child_process.spawn(exe, [uprojectPath, ...extraArgs], { detached: true, stdio: "ignore" });
8375
+ const child = node_child_process.spawn(exe, [uprojectPath, ...extraArgs], {
8376
+ detached: true,
8377
+ stdio: "ignore",
8378
+ windowsHide: process.platform === "win32"
8379
+ });
8323
8380
  child.unref();
8324
8381
  const pid = typeof child.pid === "number" ? child.pid : 0;
8325
8382
  state.launched = {
@@ -10280,7 +10337,11 @@ ${chunk}` }],
10280
10337
  async function isUnrealEditorProcessRunningBestEffortGlobal() {
10281
10338
  const runCommandCapture = async (cmd, args) => {
10282
10339
  return new Promise((resolve) => {
10283
- const child = node_child_process.spawn(cmd, args, { shell: false, stdio: ["ignore", "pipe", "pipe"] });
10340
+ const child = node_child_process.spawn(cmd, args, {
10341
+ shell: false,
10342
+ stdio: ["ignore", "pipe", "pipe"],
10343
+ windowsHide: process.platform === "win32"
10344
+ });
10284
10345
  let stdout = "";
10285
10346
  let stderr = "";
10286
10347
  child.stdout?.on("data", (c) => stdout += c.toString("utf8"));
@@ -15269,7 +15330,7 @@ async function authAndSetupMachineIfNeeded() {
15269
15330
  process.exit(1);
15270
15331
  }
15271
15332
  try {
15272
- const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin-CZ3rEkKy.cjs'); });
15333
+ const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin-BNbQyujP.cjs'); });
15273
15334
  const result = migrateUnrealMcpToFlockbayMcp({
15274
15335
  engineRoot,
15275
15336
  projectUprojectPath: project || void 0,
@@ -15425,7 +15486,7 @@ ${engineRoot}`;
15425
15486
  } else if (subcommand === "codex") {
15426
15487
  try {
15427
15488
  await chdirToNearestUprojectRootIfPresent();
15428
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-DFG80IBU.cjs'); });
15489
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-COq1y0uD.cjs'); });
15429
15490
  let startedBy = void 0;
15430
15491
  let sessionId = void 0;
15431
15492
  for (let i = 1; i < args.length; i++) {
@@ -15527,7 +15588,7 @@ ${engineRoot}`;
15527
15588
  }
15528
15589
  try {
15529
15590
  await chdirToNearestUprojectRootIfPresent();
15530
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-B6k0JjNw.cjs'); });
15591
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-HokTc0Z1.cjs'); });
15531
15592
  let startedBy = void 0;
15532
15593
  let sessionId = void 0;
15533
15594
  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-CG7Ouk31.cjs');
5
- require('./types-DQ4IqofE.cjs');
4
+ require('./index-BDpihows.cjs');
5
+ require('./types-reygbXgh.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-ZZAd2VNk.mjs';
3
- import './types-Dsn3eNAB.mjs';
2
+ import './index-AQTYO52f.mjs';
3
+ import './types-xflr9vd_.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-DQ4IqofE.cjs');
3
+ var types = require('./types-reygbXgh.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-Dsn3eNAB.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-xflr9vd_.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-DQ4IqofE.cjs');
5
+ var types = require('./types-reygbXgh.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 installUnrealMcpPluginToProject, b as isInstalledEngineRoot, q as quarantineLegacyEnginePlugins, d as installUnrealMcpPluginToEngine } from './types-Dsn3eNAB.mjs';
3
+ import { i as installUnrealMcpPluginToProject, b as isInstalledEngineRoot, q as quarantineLegacyEnginePlugins, d as installUnrealMcpPluginToEngine } from './types-xflr9vd_.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, e as projectPath } from './types-Dsn3eNAB.mjs';
3
+ import { l as logger, A as ApiClient, p as packageJson, c as configuration, r as readSettings, e as projectPath } from './types-xflr9vd_.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-ZZAd2VNk.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-AQTYO52f.mjs';
18
18
  import 'axios';
19
19
  import 'node:events';
20
20
  import 'socket.io-client';
@@ -444,7 +444,7 @@ class WindowsHiddenStdioClientTransport {
444
444
  function parseCodexCliVersion(output) {
445
445
  const raw = String(output || "").trim();
446
446
  if (!raw) return null;
447
- const m = raw.match(/codex-cli\s+(\d+)\.(\d+)\.(\d+)/);
447
+ const m = raw.match(/codex(?:-cli)?\s+(\d+)\.(\d+)\.(\d+)/i);
448
448
  if (!m) return null;
449
449
  return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]), raw: m[0] };
450
450
  }
@@ -467,7 +467,7 @@ function buildCodexSpawnEnv(codexBin) {
467
467
  if (!p) return;
468
468
  if (!prepend.includes(p) && !existingParts.includes(p)) prepend.push(p);
469
469
  };
470
- if (codexBin && codexBin.includes("/")) {
470
+ if (codexBin && (codexBin.includes("/") || codexBin.includes("\\"))) {
471
471
  add(path__default.dirname(codexBin));
472
472
  }
473
473
  add(path__default.dirname(process.execPath));
@@ -477,6 +477,8 @@ function buildCodexSpawnEnv(codexBin) {
477
477
  add("/bin");
478
478
  add("/usr/sbin");
479
479
  add("/sbin");
480
+ add(path__default.join(os__default.homedir(), "AppData", "Roaming", "npm"));
481
+ add(path__default.join(os__default.homedir(), "AppData", "Local", "OpenAI", "Codex", "bin"));
480
482
  env[pathKey] = [...prepend, ...existingParts].join(path__default.delimiter);
481
483
  if (pathKey !== "PATH") env.PATH = env[pathKey];
482
484
  return env;
@@ -486,13 +488,19 @@ function resolveCodexBin() {
486
488
  if (explicit) return explicit;
487
489
  const existsExecutable = (p) => {
488
490
  try {
489
- fs__default.accessSync(p, fs__default.constants.X_OK);
491
+ if (process.platform === "win32") {
492
+ fs__default.accessSync(p, fs__default.constants.F_OK);
493
+ } else {
494
+ fs__default.accessSync(p, fs__default.constants.X_OK);
495
+ }
490
496
  return true;
491
497
  } catch {
492
498
  return false;
493
499
  }
494
500
  };
495
501
  const candidates = [
502
+ path__default.join(os__default.homedir(), "AppData", "Roaming", "npm", "codex.cmd"),
503
+ path__default.join(os__default.homedir(), "AppData", "Local", "OpenAI", "Codex", "bin", "codex.exe"),
496
504
  path__default.join(os__default.homedir(), ".nvm", "versions", "node", "current", "bin", "codex"),
497
505
  path__default.join(os__default.homedir(), ".local", "bin", "codex"),
498
506
  "/opt/homebrew/bin/codex",
@@ -536,6 +544,29 @@ function resolveCodexBin() {
536
544
  }
537
545
  return null;
538
546
  };
547
+ if (process.platform === "win32") {
548
+ try {
549
+ const res = spawnSync("where.exe", ["codex.cmd"], {
550
+ encoding: "utf8",
551
+ env: buildCodexSpawnEnv(),
552
+ timeout: 4e3
553
+ });
554
+ const out = String(res.stdout || "").trim();
555
+ if (res.status === 0 && out) return out.split(/\r?\n/)[0].trim();
556
+ } catch {
557
+ }
558
+ try {
559
+ const res = spawnSync("where.exe", ["codex.exe"], {
560
+ encoding: "utf8",
561
+ env: buildCodexSpawnEnv(),
562
+ timeout: 4e3
563
+ });
564
+ const out = String(res.stdout || "").trim();
565
+ if (res.status === 0 && out) return out.split(/\r?\n/)[0].trim();
566
+ } catch {
567
+ }
568
+ return "codex.cmd";
569
+ }
539
570
  const fromZsh = tryShell("/bin/zsh", ["-lc", "command -v codex"]);
540
571
  if (fromZsh) return fromZsh;
541
572
  const fromBash = tryShell("/bin/bash", ["-lc", "command -v codex"]);
@@ -545,9 +576,16 @@ function resolveCodexBin() {
545
576
  function getInstalledCodexCliVersion(codexBin) {
546
577
  const bin = resolveCodexBin();
547
578
  try {
548
- const res = spawnSync(bin, ["--version"], {
579
+ const env = buildCodexSpawnEnv(bin);
580
+ const isWindowsShim = process.platform === "win32" && /\.(cmd|bat)$/i.test(bin);
581
+ const shellBin = bin.includes(" ") ? `"${bin}"` : bin;
582
+ const res = isWindowsShim ? spawnSync("cmd.exe", ["/d", "/s", "/c", `${shellBin} --version`], {
583
+ encoding: "utf8",
584
+ env,
585
+ timeout: 4e3
586
+ }) : spawnSync(bin, ["--version"], {
549
587
  encoding: "utf8",
550
- env: buildCodexSpawnEnv(bin),
588
+ env,
551
589
  timeout: 4e3
552
590
  });
553
591
  const versionOut = String(res.stdout || "").trim();
@@ -2,7 +2,7 @@
2
2
 
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
- var types = require('./types-DQ4IqofE.cjs');
5
+ var types = require('./types-reygbXgh.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-CG7Ouk31.cjs');
19
+ var index = require('./index-BDpihows.cjs');
20
20
  require('axios');
21
21
  require('node:events');
22
22
  require('socket.io-client');
@@ -446,7 +446,7 @@ class WindowsHiddenStdioClientTransport {
446
446
  function parseCodexCliVersion(output) {
447
447
  const raw = String(output || "").trim();
448
448
  if (!raw) return null;
449
- const m = raw.match(/codex-cli\s+(\d+)\.(\d+)\.(\d+)/);
449
+ const m = raw.match(/codex(?:-cli)?\s+(\d+)\.(\d+)\.(\d+)/i);
450
450
  if (!m) return null;
451
451
  return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]), raw: m[0] };
452
452
  }
@@ -469,7 +469,7 @@ function buildCodexSpawnEnv(codexBin) {
469
469
  if (!p) return;
470
470
  if (!prepend.includes(p) && !existingParts.includes(p)) prepend.push(p);
471
471
  };
472
- if (codexBin && codexBin.includes("/")) {
472
+ if (codexBin && (codexBin.includes("/") || codexBin.includes("\\"))) {
473
473
  add(path.dirname(codexBin));
474
474
  }
475
475
  add(path.dirname(process.execPath));
@@ -479,6 +479,8 @@ function buildCodexSpawnEnv(codexBin) {
479
479
  add("/bin");
480
480
  add("/usr/sbin");
481
481
  add("/sbin");
482
+ add(path.join(os.homedir(), "AppData", "Roaming", "npm"));
483
+ add(path.join(os.homedir(), "AppData", "Local", "OpenAI", "Codex", "bin"));
482
484
  env[pathKey] = [...prepend, ...existingParts].join(path.delimiter);
483
485
  if (pathKey !== "PATH") env.PATH = env[pathKey];
484
486
  return env;
@@ -488,13 +490,19 @@ function resolveCodexBin() {
488
490
  if (explicit) return explicit;
489
491
  const existsExecutable = (p) => {
490
492
  try {
491
- fs.accessSync(p, fs.constants.X_OK);
493
+ if (process.platform === "win32") {
494
+ fs.accessSync(p, fs.constants.F_OK);
495
+ } else {
496
+ fs.accessSync(p, fs.constants.X_OK);
497
+ }
492
498
  return true;
493
499
  } catch {
494
500
  return false;
495
501
  }
496
502
  };
497
503
  const candidates = [
504
+ path.join(os.homedir(), "AppData", "Roaming", "npm", "codex.cmd"),
505
+ path.join(os.homedir(), "AppData", "Local", "OpenAI", "Codex", "bin", "codex.exe"),
498
506
  path.join(os.homedir(), ".nvm", "versions", "node", "current", "bin", "codex"),
499
507
  path.join(os.homedir(), ".local", "bin", "codex"),
500
508
  "/opt/homebrew/bin/codex",
@@ -538,6 +546,29 @@ function resolveCodexBin() {
538
546
  }
539
547
  return null;
540
548
  };
549
+ if (process.platform === "win32") {
550
+ try {
551
+ const res = node_child_process.spawnSync("where.exe", ["codex.cmd"], {
552
+ encoding: "utf8",
553
+ env: buildCodexSpawnEnv(),
554
+ timeout: 4e3
555
+ });
556
+ const out = String(res.stdout || "").trim();
557
+ if (res.status === 0 && out) return out.split(/\r?\n/)[0].trim();
558
+ } catch {
559
+ }
560
+ try {
561
+ const res = node_child_process.spawnSync("where.exe", ["codex.exe"], {
562
+ encoding: "utf8",
563
+ env: buildCodexSpawnEnv(),
564
+ timeout: 4e3
565
+ });
566
+ const out = String(res.stdout || "").trim();
567
+ if (res.status === 0 && out) return out.split(/\r?\n/)[0].trim();
568
+ } catch {
569
+ }
570
+ return "codex.cmd";
571
+ }
541
572
  const fromZsh = tryShell("/bin/zsh", ["-lc", "command -v codex"]);
542
573
  if (fromZsh) return fromZsh;
543
574
  const fromBash = tryShell("/bin/bash", ["-lc", "command -v codex"]);
@@ -547,9 +578,16 @@ function resolveCodexBin() {
547
578
  function getInstalledCodexCliVersion(codexBin) {
548
579
  const bin = resolveCodexBin();
549
580
  try {
550
- const res = node_child_process.spawnSync(bin, ["--version"], {
581
+ const env = buildCodexSpawnEnv(bin);
582
+ const isWindowsShim = process.platform === "win32" && /\.(cmd|bat)$/i.test(bin);
583
+ const shellBin = bin.includes(" ") ? `"${bin}"` : bin;
584
+ const res = isWindowsShim ? node_child_process.spawnSync("cmd.exe", ["/d", "/s", "/c", `${shellBin} --version`], {
585
+ encoding: "utf8",
586
+ env,
587
+ timeout: 4e3
588
+ }) : node_child_process.spawnSync(bin, ["--version"], {
551
589
  encoding: "utf8",
552
- env: buildCodexSpawnEnv(bin),
590
+ env,
553
591
  timeout: 4e3
554
592
  });
555
593
  const versionOut = String(res.stdout || "").trim();
@@ -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-Dsn3eNAB.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-ZZAd2VNk.mjs';
7
+ import { l as logger, p as packageJson, A as ApiClient, c as configuration, r as readSettings, e as projectPath } from './types-xflr9vd_.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-AQTYO52f.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-DQ4IqofE.cjs');
10
- var index = require('./index-CG7Ouk31.cjs');
9
+ var types = require('./types-reygbXgh.cjs');
10
+ var index = require('./index-BDpihows.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.53";
47
+ var version = "0.10.55";
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-DQ4IqofE.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-reygbXgh.cjs', document.baseURI).href))));
836
836
  function projectPath() {
837
837
  const path = path$1.resolve(__dirname$1, "..");
838
838
  return path;
@@ -4346,6 +4346,7 @@ function getUnrealMcpPluginDiskStatus(params) {
4346
4346
  upluginPath,
4347
4347
  exists: fs.existsSync(upluginPath),
4348
4348
  descriptorOk: descriptor ? isPluginDescriptorOk(descriptor) : false,
4349
+ hasBinaries: fs.existsSync(path.join(pluginDir, "Binaries")),
4349
4350
  enabledInUproject: enabled.enabled
4350
4351
  };
4351
4352
  })();
@@ -4354,7 +4355,7 @@ function getUnrealMcpPluginDiskStatus(params) {
4354
4355
  return { success: false, error: "Missing projectUprojectPath (required for installScope=project)." };
4355
4356
  }
4356
4357
  const engineInstalled = engineInfo.exists && engineInfo.descriptorOk && engineInfo.hasBinaries;
4357
- const projectInstalled = Boolean(project && project.exists && project.descriptorOk && project.enabledInUproject);
4358
+ const projectInstalled = Boolean(project && project.exists && project.descriptorOk && project.hasBinaries && project.enabledInUproject);
4358
4359
  const effectiveScope = installScope === "engine" ? "engine" : installScope === "project" ? "project" : installedEngine && project ? "project" : engineInstalled ? "engine" : project && !engineInfo.enginePluginsWritable ? "project" : "engine";
4359
4360
  const conflict = engineInfo.conflicts.length > 0;
4360
4361
  const legacyConflict = engineInfo.legacy.length > 0;
@@ -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.53";
26
+ var version = "0.10.55";
27
27
  var description = "Flockbay CLI (local agent + daemon)";
28
28
  var author = "Eduardo Orellana";
29
29
  var license = "UNLICENSED";
@@ -4325,6 +4325,7 @@ function getUnrealMcpPluginDiskStatus(params) {
4325
4325
  upluginPath,
4326
4326
  exists: fs__default.existsSync(upluginPath),
4327
4327
  descriptorOk: descriptor ? isPluginDescriptorOk(descriptor) : false,
4328
+ hasBinaries: fs__default.existsSync(path__default.join(pluginDir, "Binaries")),
4328
4329
  enabledInUproject: enabled.enabled
4329
4330
  };
4330
4331
  })();
@@ -4333,7 +4334,7 @@ function getUnrealMcpPluginDiskStatus(params) {
4333
4334
  return { success: false, error: "Missing projectUprojectPath (required for installScope=project)." };
4334
4335
  }
4335
4336
  const engineInstalled = engineInfo.exists && engineInfo.descriptorOk && engineInfo.hasBinaries;
4336
- const projectInstalled = Boolean(project && project.exists && project.descriptorOk && project.enabledInUproject);
4337
+ const projectInstalled = Boolean(project && project.exists && project.descriptorOk && project.hasBinaries && project.enabledInUproject);
4337
4338
  const effectiveScope = installScope === "engine" ? "engine" : installScope === "project" ? "project" : installedEngine && project ? "project" : engineInstalled ? "engine" : project && !engineInfo.enginePluginsWritable ? "project" : "engine";
4338
4339
  const conflict = engineInfo.conflicts.length > 0;
4339
4340
  const legacyConflict = engineInfo.legacy.length > 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flockbay",
3
- "version": "0.10.53",
3
+ "version": "0.10.55",
4
4
  "description": "Flockbay CLI (local agent + daemon)",
5
5
  "author": "Eduardo Orellana",
6
6
  "license": "UNLICENSED",
@@ -35,13 +35,28 @@ function resolvePathSafe(filePath) {
35
35
  * Find path to npm globally installed Claude Code CLI
36
36
  * @returns {string|null} Path to cli.js or null if not found
37
37
  */
38
- function findNpmGlobalCliPath() {
39
- try {
40
- const globalRoot = execSync('npm root -g', { encoding: 'utf8' }).trim();
41
- const globalCliPath = path.join(globalRoot, '@anthropic-ai', 'claude-code', 'cli.js');
42
- if (fs.existsSync(globalCliPath)) {
43
- return globalCliPath;
44
- }
38
+ function findNpmGlobalCliPath() {
39
+ if (process.platform === 'win32') {
40
+ const npmRoots = [
41
+ path.join(process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'), 'npm', 'node_modules'),
42
+ ];
43
+
44
+ for (const root of npmRoots) {
45
+ const globalCliPath = path.join(root, '@anthropic-ai', 'claude-code', 'cli.js');
46
+ if (fs.existsSync(globalCliPath)) {
47
+ return globalCliPath;
48
+ }
49
+ }
50
+ }
51
+
52
+ try {
53
+ const globalRoot = process.platform === 'win32'
54
+ ? execFileSync('cmd.exe', ['/d', '/s', '/c', 'npm root -g'], { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true }).trim()
55
+ : execFileSync('npm', ['root', '-g'], { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
56
+ const globalCliPath = path.join(globalRoot, '@anthropic-ai', 'claude-code', 'cli.js');
57
+ if (fs.existsSync(globalCliPath)) {
58
+ return globalCliPath;
59
+ }
45
60
  } catch (e) {
46
61
  // npm root -g failed
47
62
  }
@@ -325,7 +340,11 @@ function getVersion(cliPath) {
325
340
  }
326
341
 
327
342
  // Binary install: try to ask it.
328
- const out = execFileSync(cliPath, ['--version'], { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
343
+ const out = execFileSync(cliPath, ['--version'], {
344
+ encoding: 'utf8',
345
+ stdio: ['pipe', 'pipe', 'pipe'],
346
+ windowsHide: process.platform === 'win32',
347
+ }).trim();
329
348
  const m = out.match(/(\d+\.\d+\.\d+)/);
330
349
  return m ? m[1] : null;
331
350
  } catch (e) {}
@@ -423,10 +442,11 @@ function runClaudeCli(cliPath) {
423
442
  // Note: Interceptors won't work with binary files, but that's acceptable
424
443
  // as binary files are self-contained and don't need interception
425
444
  const args = process.argv.slice(2);
426
- const child = spawn(cliPath, args, {
427
- stdio: 'inherit',
428
- env: process.env
429
- });
445
+ const child = spawn(cliPath, args, {
446
+ stdio: 'inherit',
447
+ env: process.env,
448
+ windowsHide: process.platform === 'win32',
449
+ });
430
450
  child.on('exit', (code) => {
431
451
  process.exit(code || 0);
432
452
  });