flockbay 0.10.20 → 0.10.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-CX0Z8pmz.mjs → index-BjZUYSzh.mjs} +471 -31
- package/dist/{index-D_mglYG0.cjs → index-DQTqwzYd.cjs} +471 -31
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{runCodex-Biis9GFw.mjs → runCodex-B7fGICdv.mjs} +11 -13
- package/dist/{runCodex-CXJW0tzo.cjs → runCodex-CaWagdzG.cjs} +11 -13
- package/dist/{runGemini-FOBXtEU6.cjs → runGemini-8w5P093W.cjs} +234 -49
- package/dist/{runGemini-BSH4b0wu.mjs → runGemini-CK43WQk8.mjs} +234 -49
- package/dist/{types-C4QeUggl.mjs → types-CMWcip0F.mjs} +41 -3
- package/dist/{types-BYHCKlu_.cjs → types-Z2OYpI8c.cjs} +41 -2
- package/package.json +1 -1
- package/scripts/claude_version_utils.cjs +66 -12
- package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPEditorCommands.cpp +32 -11
- package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/UnrealMCP.Build.cs +1 -0
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - Windows CMD: curl -fsSL https://claude.ai/install.cmd | cmd
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
const { execSync } = require('child_process');
|
|
14
|
+
const { execSync, execFileSync } = require('child_process');
|
|
15
15
|
const path = require('path');
|
|
16
16
|
const fs = require('fs');
|
|
17
17
|
const os = require('os');
|
|
@@ -258,19 +258,53 @@ function findLatestVersionBinary(versionsDir, binaryName = null) {
|
|
|
258
258
|
* @returns {{path: string, source: string}|null} Path and source, or null if not found
|
|
259
259
|
*/
|
|
260
260
|
function findGlobalClaudeCliPath() {
|
|
261
|
-
|
|
261
|
+
const candidates = [];
|
|
262
|
+
|
|
262
263
|
const npmPath = findNpmGlobalCliPath();
|
|
263
|
-
if (npmPath)
|
|
264
|
+
if (npmPath) candidates.push({ path: npmPath, source: 'npm', priority: 3 });
|
|
264
265
|
|
|
265
|
-
// Check Homebrew installation
|
|
266
266
|
const homebrewPath = findHomebrewCliPath();
|
|
267
|
-
if (homebrewPath)
|
|
267
|
+
if (homebrewPath) candidates.push({ path: homebrewPath, source: 'Homebrew', priority: 2 });
|
|
268
268
|
|
|
269
|
-
// Check native installer
|
|
270
269
|
const nativePath = findNativeInstallerCliPath();
|
|
271
|
-
if (nativePath)
|
|
270
|
+
if (nativePath) candidates.push({ path: nativePath, source: 'native installer', priority: 1 });
|
|
272
271
|
|
|
273
|
-
return null;
|
|
272
|
+
if (candidates.length === 0) return null;
|
|
273
|
+
|
|
274
|
+
// Prefer the newest version across installs when we can determine it.
|
|
275
|
+
// If versions are missing/unparseable, fall back to the legacy priority ordering.
|
|
276
|
+
let best = null;
|
|
277
|
+
for (const c of candidates) {
|
|
278
|
+
const version = getVersion(c.path);
|
|
279
|
+
const parsed = parseSemver3(version);
|
|
280
|
+
const score = parsed ? parsed : null;
|
|
281
|
+
|
|
282
|
+
if (!best) {
|
|
283
|
+
best = { ...c, version, score };
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (best.score && score) {
|
|
288
|
+
if (compareVersions(version, best.version) > 0) {
|
|
289
|
+
best = { ...c, version, score };
|
|
290
|
+
}
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// If one has a parseable version and the other doesn't, prefer the parseable one.
|
|
295
|
+
if (!best.score && score) {
|
|
296
|
+
best = { ...c, version, score };
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (best.score && !score) continue;
|
|
300
|
+
|
|
301
|
+
// Neither has a version: use priority.
|
|
302
|
+
if ((c.priority || 0) > (best.priority || 0)) {
|
|
303
|
+
best = { ...c, version, score };
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return best ? { path: best.path, source: best.source } : candidates[0];
|
|
274
308
|
}
|
|
275
309
|
|
|
276
310
|
/**
|
|
@@ -280,15 +314,35 @@ function findGlobalClaudeCliPath() {
|
|
|
280
314
|
*/
|
|
281
315
|
function getVersion(cliPath) {
|
|
282
316
|
try {
|
|
283
|
-
const
|
|
284
|
-
if (
|
|
285
|
-
const
|
|
286
|
-
|
|
317
|
+
const isJsFile = cliPath.endsWith('.js') || cliPath.endsWith('.cjs');
|
|
318
|
+
if (isJsFile) {
|
|
319
|
+
const pkgPath = path.join(path.dirname(cliPath), 'package.json');
|
|
320
|
+
if (fs.existsSync(pkgPath)) {
|
|
321
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
322
|
+
return pkg.version;
|
|
323
|
+
}
|
|
324
|
+
return null;
|
|
287
325
|
}
|
|
326
|
+
|
|
327
|
+
// Binary install: try to ask it.
|
|
328
|
+
const out = execFileSync(cliPath, ['--version'], { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
329
|
+
const m = out.match(/(\d+\.\d+\.\d+)/);
|
|
330
|
+
return m ? m[1] : null;
|
|
288
331
|
} catch (e) {}
|
|
289
332
|
return null;
|
|
290
333
|
}
|
|
291
334
|
|
|
335
|
+
function parseSemver3(v) {
|
|
336
|
+
if (!v || typeof v !== 'string') return null;
|
|
337
|
+
const m = v.trim().match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
338
|
+
if (!m) return null;
|
|
339
|
+
const a = Number(m[1]);
|
|
340
|
+
const b = Number(m[2]);
|
|
341
|
+
const c = Number(m[3]);
|
|
342
|
+
if (!Number.isFinite(a) || !Number.isFinite(b) || !Number.isFinite(c)) return null;
|
|
343
|
+
return [a, b, c];
|
|
344
|
+
}
|
|
345
|
+
|
|
292
346
|
/**
|
|
293
347
|
* Compare semver versions
|
|
294
348
|
* @param {string} a - First version
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
#include "Components/StaticMeshComponent.h"
|
|
28
28
|
#include "Materials/MaterialInterface.h"
|
|
29
29
|
#include "Sound/SoundWave.h"
|
|
30
|
+
#include "IImageWrapper.h"
|
|
31
|
+
#include "IImageWrapperModule.h"
|
|
30
32
|
#include "EditorSubsystem.h"
|
|
31
33
|
#include "Subsystems/EditorActorSubsystem.h"
|
|
32
34
|
#include "Engine/Blueprint.h"
|
|
@@ -54,6 +56,31 @@
|
|
|
54
56
|
#include "Components/SceneCaptureComponent2D.h"
|
|
55
57
|
#include "Engine/TextureRenderTarget2D.h"
|
|
56
58
|
|
|
59
|
+
static bool SavePngToFile(const FString& FilePath, int32 Width, int32 Height, const TArray<FColor>& Bitmap)
|
|
60
|
+
{
|
|
61
|
+
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
|
|
62
|
+
TSharedPtr<IImageWrapper> Wrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
|
|
63
|
+
if (!Wrapper.IsValid())
|
|
64
|
+
{
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!Wrapper->SetRaw(Bitmap.GetData(), Bitmap.Num() * sizeof(FColor), Width, Height, ERGBFormat::BGRA, 8))
|
|
69
|
+
{
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const TArray64<uint8>& Compressed = Wrapper->GetCompressed(100);
|
|
74
|
+
if (Compressed.Num() <= 0 || Compressed.Num() > MAX_int32)
|
|
75
|
+
{
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
TArray<uint8> Out;
|
|
80
|
+
Out.Append(Compressed.GetData(), static_cast<int32>(Compressed.Num()));
|
|
81
|
+
return FFileHelper::SaveArrayToFile(Out, *FilePath);
|
|
82
|
+
}
|
|
83
|
+
|
|
57
84
|
FUnrealMCPEditorCommands::FUnrealMCPEditorCommands()
|
|
58
85
|
{
|
|
59
86
|
}
|
|
@@ -219,7 +246,7 @@ TSharedPtr<FJsonObject> FUnrealMCPEditorCommands::HandleSaveAll(const TSharedPtr
|
|
|
219
246
|
}
|
|
220
247
|
|
|
221
248
|
TArray<UPackage*> DirtyBefore;
|
|
222
|
-
FEditorFileUtils::GetDirtyPackages(DirtyBefore
|
|
249
|
+
FEditorFileUtils::GetDirtyPackages(DirtyBefore);
|
|
223
250
|
|
|
224
251
|
TSet<FString> DirtyBeforeNames;
|
|
225
252
|
for (UPackage* Pkg : DirtyBefore)
|
|
@@ -239,7 +266,7 @@ TSharedPtr<FJsonObject> FUnrealMCPEditorCommands::HandleSaveAll(const TSharedPtr
|
|
|
239
266
|
);
|
|
240
267
|
|
|
241
268
|
TArray<UPackage*> DirtyAfter;
|
|
242
|
-
FEditorFileUtils::GetDirtyPackages(DirtyAfter
|
|
269
|
+
FEditorFileUtils::GetDirtyPackages(DirtyAfter);
|
|
243
270
|
|
|
244
271
|
TSet<FString> DirtyAfterNames;
|
|
245
272
|
for (UPackage* Pkg : DirtyAfter)
|
|
@@ -293,8 +320,7 @@ TSharedPtr<FJsonObject> FUnrealMCPEditorCommands::HandleSaveAll(const TSharedPtr
|
|
|
293
320
|
Details->SetArrayField(TEXT("stillDirtyPackages"), StillDirty);
|
|
294
321
|
|
|
295
322
|
TSharedPtr<FJsonObject> ErrObj = FUnrealMCPCommonUtils::CreateErrorResponse(
|
|
296
|
-
TEXT("Some packages are still dirty after save_all. They may require manual Save As, source control checkout, or have save errors. Resolve in-editor and retry save_all.")
|
|
297
|
-
);
|
|
323
|
+
TEXT("Some packages are still dirty after save_all. They may require manual Save As, source control checkout, or have save errors. Resolve in-editor and retry save_all."));
|
|
298
324
|
ErrObj->SetObjectField(TEXT("details"), Details);
|
|
299
325
|
return ErrObj;
|
|
300
326
|
}
|
|
@@ -2445,9 +2471,7 @@ TSharedPtr<FJsonObject> FUnrealMCPEditorCommands::HandleTakeScreenshot(const TSh
|
|
|
2445
2471
|
|
|
2446
2472
|
CaptureActor->Destroy();
|
|
2447
2473
|
|
|
2448
|
-
|
|
2449
|
-
FImageUtils::CompressImageArray(Width, Height, Bitmap, CompressedBitmap);
|
|
2450
|
-
if (!FFileHelper::SaveArrayToFile(CompressedBitmap, *FilePath))
|
|
2474
|
+
if (!SavePngToFile(FilePath, Width, Height, Bitmap))
|
|
2451
2475
|
{
|
|
2452
2476
|
return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Failed to save screenshot PNG to disk."));
|
|
2453
2477
|
}
|
|
@@ -2472,10 +2496,7 @@ TSharedPtr<FJsonObject> FUnrealMCPEditorCommands::HandleTakeScreenshot(const TSh
|
|
|
2472
2496
|
|
|
2473
2497
|
if (Viewport->ReadPixels(Bitmap, FReadSurfaceDataFlags(), ViewportRect))
|
|
2474
2498
|
{
|
|
2475
|
-
|
|
2476
|
-
FImageUtils::CompressImageArray(ViewSize.X, ViewSize.Y, Bitmap, CompressedBitmap);
|
|
2477
|
-
|
|
2478
|
-
if (FFileHelper::SaveArrayToFile(CompressedBitmap, *FilePath))
|
|
2499
|
+
if (SavePngToFile(FilePath, ViewSize.X, ViewSize.Y, Bitmap))
|
|
2479
2500
|
{
|
|
2480
2501
|
TSharedPtr<FJsonObject> ResultObj = MakeShared<FJsonObject>();
|
|
2481
2502
|
ResultObj->SetStringField(TEXT("filepath"), FilePath);
|