flockbay 0.10.44 → 0.10.46

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
  var chalk = require('chalk');
4
4
  var os = require('node:os');
5
5
  var node_crypto = require('node:crypto');
6
- var types = require('./types-tRJ8NBIX.cjs');
6
+ var types = require('./types-CziwW90U.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-CVBvClyV.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-BsespsLC.cjs', document.baseURI).href)));
1320
1320
  const __dirname$1 = path.join(__filename$1, "..");
1321
1321
  function getGlobalClaudeVersion(claudeExecutable) {
1322
1322
  try {
@@ -15139,7 +15139,7 @@ async function authAndSetupMachineIfNeeded() {
15139
15139
  process.exit(1);
15140
15140
  }
15141
15141
  try {
15142
- const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin-BL02mitg.cjs'); });
15142
+ const { migrateUnrealMcpToFlockbayMcp } = await Promise.resolve().then(function () { return require('./migratePlugin-B2SM0IhP.cjs'); });
15143
15143
  const result = migrateUnrealMcpToFlockbayMcp({
15144
15144
  engineRoot,
15145
15145
  projectUprojectPath: project || void 0,
@@ -15278,7 +15278,7 @@ ${engineRoot}`, {
15278
15278
  } else if (subcommand === "codex") {
15279
15279
  try {
15280
15280
  await chdirToNearestUprojectRootIfPresent();
15281
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-DcQmhprg.cjs'); });
15281
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-Rx9uhhBt.cjs'); });
15282
15282
  let startedBy = void 0;
15283
15283
  let sessionId = void 0;
15284
15284
  for (let i = 1; i < args.length; i++) {
@@ -15380,7 +15380,7 @@ ${engineRoot}`, {
15380
15380
  }
15381
15381
  try {
15382
15382
  await chdirToNearestUprojectRootIfPresent();
15383
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-CJF0id5I.cjs'); });
15383
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-BEFeFruX.cjs'); });
15384
15384
  let startedBy = void 0;
15385
15385
  let sessionId = void 0;
15386
15386
  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, 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-D8EqTVgB.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-H7oBEqpR.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';
@@ -15117,7 +15117,7 @@ async function authAndSetupMachineIfNeeded() {
15117
15117
  process.exit(1);
15118
15118
  }
15119
15119
  try {
15120
- const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-DAAX2TDX.mjs');
15120
+ const { migrateUnrealMcpToFlockbayMcp } = await import('./migratePlugin-CcRAl4zO.mjs');
15121
15121
  const result = migrateUnrealMcpToFlockbayMcp({
15122
15122
  engineRoot,
15123
15123
  projectUprojectPath: project || void 0,
@@ -15256,7 +15256,7 @@ ${engineRoot}`, {
15256
15256
  } else if (subcommand === "codex") {
15257
15257
  try {
15258
15258
  await chdirToNearestUprojectRootIfPresent();
15259
- const { runCodex } = await import('./runCodex-C_dwGw9p.mjs');
15259
+ const { runCodex } = await import('./runCodex-b9J0CZko.mjs');
15260
15260
  let startedBy = void 0;
15261
15261
  let sessionId = void 0;
15262
15262
  for (let i = 1; i < args.length; i++) {
@@ -15358,7 +15358,7 @@ ${engineRoot}`, {
15358
15358
  }
15359
15359
  try {
15360
15360
  await chdirToNearestUprojectRootIfPresent();
15361
- const { runGemini } = await import('./runGemini-CWiIoJag.mjs');
15361
+ const { runGemini } = await import('./runGemini-C3cdyIH7.mjs');
15362
15362
  let startedBy = void 0;
15363
15363
  let sessionId = void 0;
15364
15364
  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-CVBvClyV.cjs');
5
- require('./types-tRJ8NBIX.cjs');
4
+ require('./index-BsespsLC.cjs');
5
+ require('./types-CziwW90U.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-BfBX93aY.mjs';
3
- import './types-D8EqTVgB.mjs';
2
+ import './index-CNHBXWGe.mjs';
3
+ import './types-H7oBEqpR.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-tRJ8NBIX.cjs');
3
+ var types = require('./types-CziwW90U.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-D8EqTVgB.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-H7oBEqpR.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-tRJ8NBIX.cjs');
5
+ var types = require('./types-CziwW90U.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-D8EqTVgB.mjs';
3
+ import { i as installUnrealMcpPluginToEngine } from './types-H7oBEqpR.mjs';
4
4
  import 'axios';
5
5
  import 'node:os';
6
6
  import 'node:events';
@@ -2,9 +2,8 @@
2
2
 
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
- var types = require('./types-tRJ8NBIX.cjs');
5
+ var types = require('./types-CziwW90U.cjs');
6
6
  var index_js = require('@modelcontextprotocol/sdk/client/index.js');
7
- var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
8
7
  var z = require('zod');
9
8
  var types_js = require('@modelcontextprotocol/sdk/types.js');
10
9
  var node_crypto = require('node:crypto');
@@ -12,7 +11,12 @@ var fs = require('node:fs');
12
11
  var os = require('node:os');
13
12
  var path = require('node:path');
14
13
  var node_child_process = require('node:child_process');
15
- var index = require('./index-CVBvClyV.cjs');
14
+ var spawn = require('cross-spawn');
15
+ var process$1 = require('node:process');
16
+ var node_stream = require('node:stream');
17
+ var stdio_js$1 = require('@modelcontextprotocol/sdk/client/stdio.js');
18
+ var stdio_js = require('@modelcontextprotocol/sdk/shared/stdio.js');
19
+ var index = require('./index-BsespsLC.cjs');
16
20
  require('axios');
17
21
  require('node:events');
18
22
  require('socket.io-client');
@@ -24,7 +28,6 @@ require('fs/promises');
24
28
  require('crypto');
25
29
  require('path');
26
30
  require('url');
27
- require('node:process');
28
31
  require('os');
29
32
  require('node:net');
30
33
  require('http');
@@ -32,7 +35,6 @@ require('open');
32
35
  require('node:readline');
33
36
  require('node:url');
34
37
  require('ps-list');
35
- require('cross-spawn');
36
38
  require('tmp');
37
39
  require('fastify');
38
40
  require('fastify-type-provider-zod');
@@ -336,6 +338,111 @@ function buildMcpElicitationResult(decision, requestedSchemaRaw, options) {
336
338
  return { action, content, decision: codexDecision };
337
339
  }
338
340
 
341
+ class WindowsHiddenStdioClientTransport {
342
+ processRef;
343
+ abortController = new AbortController();
344
+ readBuffer = new stdio_js.ReadBuffer();
345
+ serverParams;
346
+ stderrStream = null;
347
+ platform;
348
+ onclose;
349
+ onerror;
350
+ onmessage;
351
+ constructor(server, options = {}) {
352
+ this.serverParams = server;
353
+ this.platform = options.platform ?? process$1.platform;
354
+ if (server.stderr === "pipe" || server.stderr === "overlapped") {
355
+ this.stderrStream = new node_stream.PassThrough();
356
+ }
357
+ }
358
+ async start() {
359
+ if (this.processRef) {
360
+ throw new Error("WindowsHiddenStdioClientTransport already started");
361
+ }
362
+ await new Promise((resolve, reject) => {
363
+ this.processRef = spawn(this.serverParams.command, this.serverParams.args ?? [], {
364
+ env: {
365
+ ...stdio_js$1.getDefaultEnvironment(),
366
+ ...this.serverParams.env
367
+ },
368
+ stdio: ["pipe", "pipe", this.serverParams.stderr ?? "inherit"],
369
+ shell: false,
370
+ signal: this.abortController.signal,
371
+ windowsHide: this.platform === "win32",
372
+ cwd: this.serverParams.cwd
373
+ });
374
+ this.processRef.on("error", (error) => {
375
+ if (error.name === "AbortError") {
376
+ this.onclose?.();
377
+ return;
378
+ }
379
+ reject(error);
380
+ this.onerror?.(error);
381
+ });
382
+ this.processRef.on("spawn", () => {
383
+ resolve();
384
+ });
385
+ this.processRef.on("close", () => {
386
+ this.processRef = void 0;
387
+ this.onclose?.();
388
+ });
389
+ this.processRef.stdin?.on("error", (error) => {
390
+ this.onerror?.(error);
391
+ });
392
+ this.processRef.stdout?.on("data", (chunk) => {
393
+ this.readBuffer.append(chunk);
394
+ this.processReadBuffer();
395
+ });
396
+ this.processRef.stdout?.on("error", (error) => {
397
+ this.onerror?.(error);
398
+ });
399
+ if (this.stderrStream && this.processRef.stderr) {
400
+ this.processRef.stderr.pipe(this.stderrStream);
401
+ }
402
+ });
403
+ }
404
+ get stderr() {
405
+ if (this.stderrStream) {
406
+ return this.stderrStream;
407
+ }
408
+ return this.processRef?.stderr ?? null;
409
+ }
410
+ get pid() {
411
+ return this.processRef?.pid ?? null;
412
+ }
413
+ async close() {
414
+ this.abortController.abort();
415
+ this.processRef = void 0;
416
+ this.readBuffer.clear();
417
+ }
418
+ send(message) {
419
+ return new Promise((resolve) => {
420
+ if (!this.processRef?.stdin) {
421
+ throw new Error("Not connected");
422
+ }
423
+ const payload = stdio_js.serializeMessage(message);
424
+ if (this.processRef.stdin.write(payload)) {
425
+ resolve();
426
+ return;
427
+ }
428
+ this.processRef.stdin.once("drain", resolve);
429
+ });
430
+ }
431
+ processReadBuffer() {
432
+ while (true) {
433
+ try {
434
+ const message = this.readBuffer.readMessage();
435
+ if (message === null) {
436
+ break;
437
+ }
438
+ this.onmessage?.(message);
439
+ } catch (error) {
440
+ this.onerror?.(error);
441
+ }
442
+ }
443
+ }
444
+ }
445
+
339
446
  const DEFAULT_TIMEOUT = 14 * 24 * 60 * 60 * 1e3;
340
447
  function getCodexMcpCommand() {
341
448
  try {
@@ -790,7 +897,7 @@ class CodexMcpClient {
790
897
  const codexBin = resolveCodexBin();
791
898
  types.logger.debug(`[CodexMCP] Connecting to Codex MCP server using command: ${codexBin} ${mcpCommand}`);
792
899
  const env = buildCodexSpawnEnv(codexBin);
793
- this.transport = new stdio_js.StdioClientTransport({
900
+ this.transport = new WindowsHiddenStdioClientTransport({
794
901
  command: codexBin,
795
902
  args: [mcpCommand],
796
903
  env
@@ -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-D8EqTVgB.mjs';
3
+ import { l as logger, A as ApiClient, p as packageJson, c as configuration, r as readSettings, b as projectPath } from './types-H7oBEqpR.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-BfBX93aY.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-CNHBXWGe.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
@@ -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-tRJ8NBIX.cjs');
10
- var index = require('./index-CVBvClyV.cjs');
9
+ var types = require('./types-CziwW90U.cjs');
10
+ var index = require('./index-BsespsLC.cjs');
11
11
  var node_child_process = require('node:child_process');
12
12
  var sdk = require('@agentclientprotocol/sdk');
13
13
  var fs = require('fs');
@@ -4,8 +4,8 @@ import { randomUUID, createHash } from 'node:crypto';
4
4
  import os__default from 'node:os';
5
5
  import path__default, { resolve, join as join$1, basename } from 'node:path';
6
6
  import { mkdir, writeFile, readFile } from 'node:fs/promises';
7
- import { l as logger, p as packageJson, A as ApiClient, c as configuration, r as readSettings, b as projectPath } from './types-D8EqTVgB.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-BfBX93aY.mjs';
7
+ import { l as logger, p as packageJson, A as ApiClient, c as configuration, r as readSettings, b as projectPath } from './types-H7oBEqpR.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-CNHBXWGe.mjs';
9
9
  import { spawn, spawnSync } from 'node:child_process';
10
10
  import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
11
11
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
@@ -44,7 +44,7 @@ function _interopNamespaceDefault(e) {
44
44
  var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
45
45
 
46
46
  var name = "flockbay";
47
- var version = "0.10.44";
47
+ var version = "0.10.46";
48
48
  var description = "Flockbay CLI (local agent + daemon)";
49
49
  var author = "Eduardo Orellana";
50
50
  var license = "UNLICENSED";
@@ -292,6 +292,54 @@ const configuration = new Configuration();
292
292
  const defaultSettings = {
293
293
  onboardingCompleted: false
294
294
  };
295
+ const daemonStateSchema = z__namespace.object({
296
+ pid: z__namespace.number(),
297
+ httpPort: z__namespace.number(),
298
+ startTime: z__namespace.string(),
299
+ startedWithCliVersion: z__namespace.string(),
300
+ lastHeartbeat: z__namespace.string().optional(),
301
+ daemonLogPath: z__namespace.string().optional()
302
+ }).passthrough();
303
+ function sleepSync(ms) {
304
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
305
+ }
306
+ function writeFileSyncAtomic(destinationPath, content) {
307
+ const tmpPath = `${destinationPath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
308
+ fs.writeFileSync(tmpPath, content, "utf-8");
309
+ const maxAttempts = 5;
310
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
311
+ try {
312
+ if (fs.existsSync(destinationPath)) {
313
+ fs.unlinkSync(destinationPath);
314
+ }
315
+ } catch (error) {
316
+ const code = error?.code;
317
+ if (attempt === maxAttempts || code && !["EPERM", "EACCES", "EBUSY", "ENOENT"].includes(code)) {
318
+ try {
319
+ fs.unlinkSync(tmpPath);
320
+ } catch {
321
+ }
322
+ throw error;
323
+ }
324
+ sleepSync(10 * attempt);
325
+ continue;
326
+ }
327
+ try {
328
+ fs.renameSync(tmpPath, destinationPath);
329
+ return;
330
+ } catch (error) {
331
+ const code = error?.code;
332
+ if (attempt === maxAttempts || code && !["EPERM", "EACCES", "EBUSY", "EEXIST"].includes(code)) {
333
+ try {
334
+ fs.unlinkSync(tmpPath);
335
+ } catch {
336
+ }
337
+ throw error;
338
+ }
339
+ sleepSync(10 * attempt);
340
+ }
341
+ }
342
+ }
295
343
  async function readSettings() {
296
344
  if (!fs.existsSync(configuration.settingsFile)) {
297
345
  return { ...defaultSettings };
@@ -391,19 +439,29 @@ async function clearMachineId() {
391
439
  }));
392
440
  }
393
441
  async function readDaemonState() {
442
+ if (!fs.existsSync(configuration.daemonStateFile)) {
443
+ return null;
444
+ }
394
445
  try {
395
- if (!fs.existsSync(configuration.daemonStateFile)) {
396
- return null;
397
- }
398
446
  const content = await fs$1.readFile(configuration.daemonStateFile, "utf-8");
399
- return JSON.parse(content);
447
+ if (!content.trim()) {
448
+ throw new Error("Empty daemon state file");
449
+ }
450
+ const parsedJson = JSON.parse(content);
451
+ return daemonStateSchema.parse(parsedJson);
400
452
  } catch (error) {
401
- console.error(`[PERSISTENCE] Daemon state file corrupted: ${configuration.daemonStateFile}`, error);
453
+ await clearDaemonState().catch(() => null);
454
+ const message = error instanceof Error ? error.message : String(error);
455
+ if (process.env.DEBUG || process.env.FLOCKBAY_DEBUG_PERSISTENCE) {
456
+ console.error(`[PERSISTENCE] Daemon state file corrupted: ${configuration.daemonStateFile}`, error);
457
+ } else {
458
+ console.warn(`[PERSISTENCE] Daemon state file corrupted; cleared ${configuration.daemonStateFile} (${message})`);
459
+ }
402
460
  return null;
403
461
  }
404
462
  }
405
463
  function writeDaemonState(state) {
406
- fs.writeFileSync(configuration.daemonStateFile, JSON.stringify(state, null, 2), "utf-8");
464
+ writeFileSyncAtomic(configuration.daemonStateFile, JSON.stringify(state, null, 2));
407
465
  }
408
466
  async function clearDaemonState() {
409
467
  if (fs.existsSync(configuration.daemonStateFile)) {
@@ -774,7 +832,7 @@ class RpcHandlerManager {
774
832
  }
775
833
  }
776
834
 
777
- 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-tRJ8NBIX.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-CziwW90U.cjs', document.baseURI).href))));
778
836
  function projectPath() {
779
837
  const path = path$1.resolve(__dirname$1, "..");
780
838
  return path;
@@ -3778,7 +3836,7 @@ exitCode: ${exitCode}
3778
3836
  buildLogPath,
3779
3837
  errorMessage: `Failed to build the Flockbay MCP plugin.
3780
3838
  Log: ${buildLogPath}
3781
- Make sure your compiler tools are installed (Xcode on macOS, Visual Studio Build Tools on Windows).`
3839
+ Open the log to see the exact failure (missing compiler toolchain vs plugin compile errors).`
3782
3840
  };
3783
3841
  }
3784
3842
  const resolved = resolvePackagedPluginDir(packageDir);
@@ -1,5 +1,5 @@
1
1
  import axios from 'axios';
2
- import fs__default, { existsSync, readFileSync, mkdirSync, constants, unlinkSync, writeFileSync, readdirSync, statSync, createWriteStream } from 'node:fs';
2
+ import fs__default, { existsSync, readFileSync, mkdirSync, constants, unlinkSync, writeFileSync, renameSync, readdirSync, statSync, createWriteStream } from 'node:fs';
3
3
  import os__default, { homedir } from 'node:os';
4
4
  import path__default, { join, basename } from 'node:path';
5
5
  import { EventEmitter } from 'node:events';
@@ -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.44";
26
+ var version = "0.10.46";
27
27
  var description = "Flockbay CLI (local agent + daemon)";
28
28
  var author = "Eduardo Orellana";
29
29
  var license = "UNLICENSED";
@@ -271,6 +271,54 @@ const configuration = new Configuration();
271
271
  const defaultSettings = {
272
272
  onboardingCompleted: false
273
273
  };
274
+ const daemonStateSchema = z.object({
275
+ pid: z.number(),
276
+ httpPort: z.number(),
277
+ startTime: z.string(),
278
+ startedWithCliVersion: z.string(),
279
+ lastHeartbeat: z.string().optional(),
280
+ daemonLogPath: z.string().optional()
281
+ }).passthrough();
282
+ function sleepSync(ms) {
283
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
284
+ }
285
+ function writeFileSyncAtomic(destinationPath, content) {
286
+ const tmpPath = `${destinationPath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
287
+ writeFileSync(tmpPath, content, "utf-8");
288
+ const maxAttempts = 5;
289
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
290
+ try {
291
+ if (existsSync(destinationPath)) {
292
+ unlinkSync(destinationPath);
293
+ }
294
+ } catch (error) {
295
+ const code = error?.code;
296
+ if (attempt === maxAttempts || code && !["EPERM", "EACCES", "EBUSY", "ENOENT"].includes(code)) {
297
+ try {
298
+ unlinkSync(tmpPath);
299
+ } catch {
300
+ }
301
+ throw error;
302
+ }
303
+ sleepSync(10 * attempt);
304
+ continue;
305
+ }
306
+ try {
307
+ renameSync(tmpPath, destinationPath);
308
+ return;
309
+ } catch (error) {
310
+ const code = error?.code;
311
+ if (attempt === maxAttempts || code && !["EPERM", "EACCES", "EBUSY", "EEXIST"].includes(code)) {
312
+ try {
313
+ unlinkSync(tmpPath);
314
+ } catch {
315
+ }
316
+ throw error;
317
+ }
318
+ sleepSync(10 * attempt);
319
+ }
320
+ }
321
+ }
274
322
  async function readSettings() {
275
323
  if (!existsSync(configuration.settingsFile)) {
276
324
  return { ...defaultSettings };
@@ -370,19 +418,29 @@ async function clearMachineId() {
370
418
  }));
371
419
  }
372
420
  async function readDaemonState() {
421
+ if (!existsSync(configuration.daemonStateFile)) {
422
+ return null;
423
+ }
373
424
  try {
374
- if (!existsSync(configuration.daemonStateFile)) {
375
- return null;
376
- }
377
425
  const content = await readFile(configuration.daemonStateFile, "utf-8");
378
- return JSON.parse(content);
426
+ if (!content.trim()) {
427
+ throw new Error("Empty daemon state file");
428
+ }
429
+ const parsedJson = JSON.parse(content);
430
+ return daemonStateSchema.parse(parsedJson);
379
431
  } catch (error) {
380
- console.error(`[PERSISTENCE] Daemon state file corrupted: ${configuration.daemonStateFile}`, error);
432
+ await clearDaemonState().catch(() => null);
433
+ const message = error instanceof Error ? error.message : String(error);
434
+ if (process.env.DEBUG || process.env.FLOCKBAY_DEBUG_PERSISTENCE) {
435
+ console.error(`[PERSISTENCE] Daemon state file corrupted: ${configuration.daemonStateFile}`, error);
436
+ } else {
437
+ console.warn(`[PERSISTENCE] Daemon state file corrupted; cleared ${configuration.daemonStateFile} (${message})`);
438
+ }
381
439
  return null;
382
440
  }
383
441
  }
384
442
  function writeDaemonState(state) {
385
- writeFileSync(configuration.daemonStateFile, JSON.stringify(state, null, 2), "utf-8");
443
+ writeFileSyncAtomic(configuration.daemonStateFile, JSON.stringify(state, null, 2));
386
444
  }
387
445
  async function clearDaemonState() {
388
446
  if (existsSync(configuration.daemonStateFile)) {
@@ -3757,7 +3815,7 @@ exitCode: ${exitCode}
3757
3815
  buildLogPath,
3758
3816
  errorMessage: `Failed to build the Flockbay MCP plugin.
3759
3817
  Log: ${buildLogPath}
3760
- Make sure your compiler tools are installed (Xcode on macOS, Visual Studio Build Tools on Windows).`
3818
+ Open the log to see the exact failure (missing compiler toolchain vs plugin compile errors).`
3761
3819
  };
3762
3820
  }
3763
3821
  const resolved = resolvePackagedPluginDir(packageDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flockbay",
3
- "version": "0.10.44",
3
+ "version": "0.10.46",
4
4
  "description": "Flockbay CLI (local agent + daemon)",
5
5
  "author": "Eduardo Orellana",
6
6
  "license": "UNLICENSED",
@@ -16,6 +16,7 @@
16
16
  #include "Engine/SCS_Node.h"
17
17
  #include "UObject/Field.h"
18
18
  #include "UObject/FieldPath.h"
19
+ #include "UObject/UObjectGlobals.h"
19
20
  #include "EditorAssetLibrary.h"
20
21
  #include "AssetRegistry/AssetRegistryModule.h"
21
22
  #include "MessageLogModule.h"
@@ -23,6 +24,20 @@
23
24
  #include "GameFramework/Actor.h"
24
25
  #include "GameFramework/Pawn.h"
25
26
 
27
+ static UClass* FindMcpClassByName(const TCHAR* ClassName)
28
+ {
29
+ #if defined(ANY_PACKAGE)
30
+ return FindObject<UClass>(ANY_PACKAGE, ClassName);
31
+ #else
32
+ return FindFirstObject<UClass>(ClassName);
33
+ #endif
34
+ }
35
+
36
+ static UClass* FindMcpClassByName(const FString& ClassName)
37
+ {
38
+ return FindMcpClassByName(*ClassName);
39
+ }
40
+
26
41
  FUnrealMCPBlueprintCommands::FUnrealMCPBlueprintCommands()
27
42
  {
28
43
  }
@@ -249,26 +264,26 @@ TSharedPtr<FJsonObject> FUnrealMCPBlueprintCommands::HandleAddComponentToBluepri
249
264
  UClass* ComponentClass = nullptr;
250
265
 
251
266
  // Try to find the class with exact name first
252
- ComponentClass = FindObject<UClass>(ANY_PACKAGE, *ComponentType);
267
+ ComponentClass = FindMcpClassByName(ComponentType);
253
268
 
254
269
  // If not found, try with "Component" suffix
255
270
  if (!ComponentClass && !ComponentType.EndsWith(TEXT("Component")))
256
271
  {
257
272
  FString ComponentTypeWithSuffix = ComponentType + TEXT("Component");
258
- ComponentClass = FindObject<UClass>(ANY_PACKAGE, *ComponentTypeWithSuffix);
273
+ ComponentClass = FindMcpClassByName(ComponentTypeWithSuffix);
259
274
  }
260
275
 
261
276
  // If still not found, try with "U" prefix
262
277
  if (!ComponentClass && !ComponentType.StartsWith(TEXT("U")))
263
278
  {
264
279
  FString ComponentTypeWithPrefix = TEXT("U") + ComponentType;
265
- ComponentClass = FindObject<UClass>(ANY_PACKAGE, *ComponentTypeWithPrefix);
280
+ ComponentClass = FindMcpClassByName(ComponentTypeWithPrefix);
266
281
 
267
282
  // Try with both prefix and suffix
268
283
  if (!ComponentClass && !ComponentType.EndsWith(TEXT("Component")))
269
284
  {
270
285
  FString ComponentTypeWithBoth = TEXT("U") + ComponentType + TEXT("Component");
271
- ComponentClass = FindObject<UClass>(ANY_PACKAGE, *ComponentTypeWithBoth);
286
+ ComponentClass = FindMcpClassByName(ComponentTypeWithBoth);
272
287
  }
273
288
  }
274
289
 
@@ -17,11 +17,26 @@
17
17
  #include "Kismet/GameplayStatics.h"
18
18
  #include "EdGraphSchema_K2.h"
19
19
  #include "UObject/UObjectIterator.h"
20
+ #include "UObject/UObjectGlobals.h"
20
21
  #include "Kismet/BlueprintFunctionLibrary.h"
21
22
 
22
23
  // Declare the log category
23
24
  DEFINE_LOG_CATEGORY_STATIC(LogUnrealMCP, Log, All);
24
25
 
26
+ static UClass* FindMcpClassByName(const TCHAR* ClassName)
27
+ {
28
+ #if defined(ANY_PACKAGE)
29
+ return FindObject<UClass>(ANY_PACKAGE, ClassName);
30
+ #else
31
+ return FindFirstObject<UClass>(ClassName);
32
+ #endif
33
+ }
34
+
35
+ static UClass* FindMcpClassByName(const FString& ClassName)
36
+ {
37
+ return FindMcpClassByName(*ClassName);
38
+ }
39
+
25
40
  FUnrealMCPBlueprintNodeCommands::FUnrealMCPBlueprintNodeCommands()
26
41
  {
27
42
  }
@@ -413,7 +428,7 @@ TSharedPtr<FJsonObject> FUnrealMCPBlueprintNodeCommands::HandleAddBlueprintFunct
413
428
  UClass* TargetClass = nullptr;
414
429
 
415
430
  // First try without a prefix
416
- TargetClass = FindObject<UClass>(ANY_PACKAGE, *Target);
431
+ TargetClass = FindMcpClassByName(Target);
417
432
  UE_LOG(LogTemp, Display, TEXT("Tried to find class '%s': %s"),
418
433
  *Target, TargetClass ? TEXT("Found") : TEXT("Not found"));
419
434
 
@@ -421,7 +436,7 @@ TSharedPtr<FJsonObject> FUnrealMCPBlueprintNodeCommands::HandleAddBlueprintFunct
421
436
  if (!TargetClass && !Target.StartsWith(TEXT("U")))
422
437
  {
423
438
  FString TargetWithPrefix = FString(TEXT("U")) + Target;
424
- TargetClass = FindObject<UClass>(ANY_PACKAGE, *TargetWithPrefix);
439
+ TargetClass = FindMcpClassByName(TargetWithPrefix);
425
440
  UE_LOG(LogTemp, Display, TEXT("Tried to find class '%s': %s"),
426
441
  *TargetWithPrefix, TargetClass ? TEXT("Found") : TEXT("Not found"));
427
442
  }
@@ -436,7 +451,7 @@ TSharedPtr<FJsonObject> FUnrealMCPBlueprintNodeCommands::HandleAddBlueprintFunct
436
451
 
437
452
  for (const FString& ClassName : PossibleClassNames)
438
453
  {
439
- TargetClass = FindObject<UClass>(ANY_PACKAGE, *ClassName);
454
+ TargetClass = FindMcpClassByName(ClassName);
440
455
  if (TargetClass)
441
456
  {
442
457
  UE_LOG(LogTemp, Display, TEXT("Found class using alternative name '%s'"), *ClassName);
@@ -449,7 +464,7 @@ TSharedPtr<FJsonObject> FUnrealMCPBlueprintNodeCommands::HandleAddBlueprintFunct
449
464
  if (!TargetClass && Target == TEXT("UGameplayStatics"))
450
465
  {
451
466
  // For UGameplayStatics, use a direct reference to known class
452
- TargetClass = FindObject<UClass>(ANY_PACKAGE, TEXT("UGameplayStatics"));
467
+ TargetClass = FindMcpClassByName(TEXT("UGameplayStatics"));
453
468
  if (!TargetClass)
454
469
  {
455
470
  // Try loading it from its known package
@@ -594,7 +609,7 @@ TSharedPtr<FJsonObject> FUnrealMCPBlueprintNodeCommands::HandleAddBlueprintFunct
594
609
  const FString& ClassName = StringVal;
595
610
 
596
611
  // TODO: This likely won't work in UE5.5+, so don't rely on it.
597
- UClass* Class = FindObject<UClass>(ANY_PACKAGE, *ClassName);
612
+ UClass* Class = FindMcpClassByName(ClassName);
598
613
 
599
614
  if (!Class)
600
615
  {
@@ -796,18 +811,18 @@ static UClass* ResolveClassBestEffort(const FString& Target)
796
811
  return LoadObject<UClass>(nullptr, *T);
797
812
  }
798
813
 
799
- UClass* Found = FindObject<UClass>(ANY_PACKAGE, *T);
814
+ UClass* Found = FindMcpClassByName(T);
800
815
  if (!Found && !T.StartsWith(TEXT("U")))
801
816
  {
802
- Found = FindObject<UClass>(ANY_PACKAGE, *(FString(TEXT("U")) + T));
817
+ Found = FindMcpClassByName(FString(TEXT("U")) + T);
803
818
  }
804
819
  if (!Found && !T.EndsWith(TEXT("Library")))
805
820
  {
806
- Found = FindObject<UClass>(ANY_PACKAGE, *(FString(TEXT("U")) + T + TEXT("Library")));
821
+ Found = FindMcpClassByName(FString(TEXT("U")) + T + TEXT("Library"));
807
822
  }
808
823
  if (!Found && !T.EndsWith(TEXT("Component")))
809
824
  {
810
- Found = FindObject<UClass>(ANY_PACKAGE, *(FString(TEXT("U")) + T + TEXT("Component")));
825
+ Found = FindMcpClassByName(FString(TEXT("U")) + T + TEXT("Component"));
811
826
  }
812
827
  return Found;
813
828
  }
@@ -44,6 +44,7 @@
44
44
  #include "AssetRegistry/AssetRegistryModule.h"
45
45
  #include "UObject/SoftObjectPath.h"
46
46
  #include "UObject/Package.h"
47
+ #include "UObject/UObjectGlobals.h"
47
48
  #include "FileHelpers.h"
48
49
  #include "MessageLogModule.h"
49
50
  #include "IMessageLogListing.h"
@@ -56,6 +57,20 @@
56
57
  #include "Components/SceneCaptureComponent2D.h"
57
58
  #include "Engine/TextureRenderTarget2D.h"
58
59
 
60
+ static UClass* FindMcpClassByName(const TCHAR* ClassName)
61
+ {
62
+ #if defined(ANY_PACKAGE)
63
+ return FindObject<UClass>(ANY_PACKAGE, ClassName);
64
+ #else
65
+ return FindFirstObject<UClass>(ClassName);
66
+ #endif
67
+ }
68
+
69
+ static UClass* FindMcpClassByName(const FString& ClassName)
70
+ {
71
+ return FindMcpClassByName(*ClassName);
72
+ }
73
+
59
74
  static bool SavePngToFile(const FString& FilePath, int32 Width, int32 Height, TArray<FColor>& Bitmap)
60
75
  {
61
76
  IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
@@ -560,10 +575,10 @@ static bool TryResolveAssetClassFilter(const TSharedPtr<FJsonObject>& Params, FA
560
575
  }
561
576
  else
562
577
  {
563
- Class = FindObject<UClass>(ANY_PACKAGE, *ClassName);
578
+ Class = FindMcpClassByName(ClassName);
564
579
  if (!Class && !ClassName.StartsWith(TEXT("U")))
565
580
  {
566
- Class = FindObject<UClass>(ANY_PACKAGE, *(TEXT("U") + ClassName));
581
+ Class = FindMcpClassByName(TEXT("U") + ClassName);
567
582
  }
568
583
  }
569
584
 
@@ -12,7 +12,7 @@
12
12
  #include "HAL/PlatformTime.h"
13
13
 
14
14
  // Buffer size for receiving data
15
- const int32 BufferSize = 8192;
15
+ const int32 RecvBufferSizeBytes = 8192;
16
16
 
17
17
  static bool SendAll(FSocket* Socket, const uint8* Data, int32 TotalBytes, int32& OutTotalBytesSent)
18
18
  {
@@ -102,7 +102,7 @@ uint32 FMCPServerRunnable::Run()
102
102
  ClientSocket->SetSendBufferSize(SocketBufferSize, SocketBufferSize);
103
103
  ClientSocket->SetReceiveBufferSize(SocketBufferSize, SocketBufferSize);
104
104
 
105
- uint8 Buffer[8192 + 1];
105
+ uint8 Buffer[RecvBufferSizeBytes + 1];
106
106
  while (bRunning)
107
107
  {
108
108
  int32 BytesRead = 0;
@@ -116,7 +116,7 @@ uint32 FMCPServerRunnable::Run()
116
116
 
117
117
  // Convert received data to string
118
118
  // Null-terminate safely (Recv can fill the entire buffer).
119
- const int32 SafeIndex = FMath::Clamp(BytesRead, 0, 8192);
119
+ const int32 SafeIndex = FMath::Clamp(BytesRead, 0, RecvBufferSizeBytes);
120
120
  Buffer[SafeIndex] = '\0';
121
121
  FString ReceivedText = UTF8_TO_TCHAR(Buffer);
122
122
  UE_LOG(LogTemp, Display, TEXT("MCPServerRunnable: Received: %s"), *ReceivedText);