Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit af6b5ad

Browse files
committed
sync: cli-v1.25.10
1 parent e41f11b commit af6b5ad

18 files changed

Lines changed: 1313 additions & 12 deletions

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,24 @@
22

33
All notable changes to soft-ue-cli will be documented in this file.
44

5+
## [1.25.10] - 2026-04-25
6+
7+
### Fixed
8+
- CLI export: restored the public `inspect-customizable-object-graph`, `inspect-mutable-parameters`, and `inspect-mutable-diagnostics` command wrappers so the packaged CLI matches the documented Mutable inspection surface
9+
10+
## [1.25.9] - 2026-04-25
11+
12+
### Added
13+
- new `inspect-customizable-object-graph` command returns machine-readable graph, node, pin, and edge data for Mutable/CustomizableObject assets
14+
- new `inspect-mutable-parameters` command derives structured Mutable parameter metadata such as groups, defaults, options, tags, and related graph links
15+
- new `inspect-mutable-diagnostics` command reports Mutable plugin availability plus best-effort capability and runtime diagnostics for a target asset
16+
17+
### Fixed
18+
- plugin build: `AssetIntrospectionUtils.cpp` now compiles against UE 5.7 by including `UserDefinedStructEditorData.h` when available and passing a compatible parent object to `ExportText_Direct`
19+
20+
### Changed
21+
- Mutable inspection commands are implemented without a hard compile-time Mutable dependency, so projects without the plugin return structured unavailable/limited results instead of failing to compile
22+
523
## [1.25.8] - 2026-04-23
624

725
### Fixed

README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,11 @@
1313

1414
Built and maintained by a solo developer. [Support this project](#support-this-project) if it saves you time.
1515

16-
This project was originally created to help friends work with Unreal Engine more effectively.
1716

1817
**Control Unreal Engine 5 from your AI agent or terminal.** soft-ue-cli gives any LLM — via **MCP server** or **CLI** — 60+ tools to spawn actors, edit Blueprints, inspect materials, read and patch UE config files, run Play-In-Editor sessions, capture screenshots, profile performance, and more inside a running UE5 editor or packaged build.
1918

2019
Two connection paths. Same package. Bridge tools when Unreal is running, offline tools when it is not.
2120

22-
## Project Status
23-
24-
Public development of this repository is winding down.
25-
26-
Future work may continue in a private environment because ongoing development can involve proprietary employer-owned code that cannot be published here.
27-
28-
The code already published in this repository remains available as a prototype and reference implementation. You are welcome to use it, fork it, and extend it in accordance with the repository license.
2921

3022
```text
3123
LLM client / shell / CI
@@ -244,6 +236,9 @@ Every command is available via `soft-ue-cli <command>`. Run `soft-ue-cli <comman
244236
| `query-asset` | Search the Content Browser by name, class, or path -- also inspect DataTables and map `WorldSettings` such as `DefaultGameMode` |
245237
| `query-enum` | Inspect a UserDefinedEnum asset -- authored names, display names, tooltips, numeric values |
246238
| `query-struct` | Inspect a UserDefinedStruct asset -- authored member names, defaults, and metadata |
239+
| `inspect-customizable-object-graph` | Inspect a Mutable/CustomizableObject graph and return graphs, nodes, pins, edges, and derived node roles |
240+
| `inspect-mutable-parameters` | Derive structured Mutable parameter metadata such as groups, defaults, options, tags, and related graph links |
241+
| `inspect-mutable-diagnostics` | Report Mutable plugin availability and best-effort capability/runtime diagnostics for a target asset |
247242
| `create-asset` | Create new Blueprint, Material, DataTable, World (Level), or other asset types |
248243
| `delete-asset` | Delete an asset |
249244
| `release-asset-lock` | Best-effort close editors and release UE file handles for a specific asset |
@@ -480,6 +475,14 @@ soft-ue-cli query-enum /Game/Data/E_TraversalActionType
480475
soft-ue-cli query-struct /Game/Data/S_TraversalCheckResult
481476
```
482477

478+
### Inspect Mutable / CustomizableObject assets safely
479+
480+
```bash
481+
soft-ue-cli inspect-customizable-object-graph /Game/Characters/CO_Hero.CO_Hero
482+
soft-ue-cli inspect-mutable-parameters /Game/Characters/CO_Hero.CO_Hero
483+
soft-ue-cli inspect-mutable-diagnostics /Game/Characters/CO_Hero.CO_Hero
484+
```
485+
483486
### Start a PIE session and send input
484487

485488
```bash

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "soft-ue-cli"
7-
version = "1.25.8"
7+
version = "1.25.10"
88
description = "CLI tool for controlling Unreal Engine via soft-ue-bridge plugin"
99
requires-python = ">=3.10"
1010
classifiers = [

soft_ue_cli/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""soft-ue-cli — CLI interface to the SoftUEBridge UE plugin."""
22

3-
__version__ = "1.25.8"
3+
__version__ = "1.25.10"

soft_ue_cli/__main__.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,21 @@ def cmd_release_asset_lock(args: argparse.Namespace) -> None:
413413
_print_json(_run_tool("release-asset-lock", {"asset_path": args.asset_path}))
414414

415415

416+
def cmd_inspect_customizable_object_graph(args: argparse.Namespace) -> None:
417+
arguments: dict = {"asset_path": args.asset_path}
418+
if args.include_node_properties:
419+
arguments["include_node_properties"] = True
420+
_print_json(_run_tool("inspect-customizable-object-graph", arguments))
421+
422+
423+
def cmd_inspect_mutable_parameters(args: argparse.Namespace) -> None:
424+
_print_json(_run_tool("inspect-mutable-parameters", {"asset_path": args.asset_path}))
425+
426+
427+
def cmd_inspect_mutable_diagnostics(args: argparse.Namespace) -> None:
428+
_print_json(_run_tool("inspect-mutable-diagnostics", {"asset_path": args.asset_path}))
429+
430+
416431
def cmd_get_asset_diff(args: argparse.Namespace) -> None:
417432
arguments: dict = {"asset_path": args.asset_path}
418433
if args.scm_type:
@@ -2558,6 +2573,56 @@ def build_parser() -> argparse.ArgumentParser:
25582573
p_ral.add_argument("asset_path", help="Asset path to unlock")
25592574
p_ral.set_defaults(func=cmd_release_asset_lock)
25602575

2576+
p_icog = sub.add_parser(
2577+
"inspect-customizable-object-graph",
2578+
help="Inspect a Mutable/CustomizableObject graph without requiring a hard Mutable dependency.",
2579+
description=(
2580+
"Returns machine-readable graph data for a CustomizableObject asset, including graphs,\n"
2581+
"nodes, pins, edges, and graph-derived roles such as parameter/projector/output nodes.\n"
2582+
"If Mutable is not enabled for the project, the command returns an unavailable status\n"
2583+
"instead of hard-failing the CLI.\n\n"
2584+
"EXAMPLES:\n"
2585+
" soft-ue-cli inspect-customizable-object-graph /Game/Characters/CO_Hero.CO_Hero\n"
2586+
" soft-ue-cli inspect-customizable-object-graph /Game/Characters/CO_Hero.CO_Hero --include-node-properties"
2587+
),
2588+
formatter_class=argparse.RawDescriptionHelpFormatter,
2589+
)
2590+
p_icog.add_argument("asset_path", help="CustomizableObject asset path")
2591+
p_icog.add_argument("--include-node-properties", action="store_true", help="Include a larger reflected property dump per node")
2592+
p_icog.set_defaults(func=cmd_inspect_customizable_object_graph)
2593+
2594+
p_imp = sub.add_parser(
2595+
"inspect-mutable-parameters",
2596+
help="Derive structured Mutable parameter metadata from a CustomizableObject asset.",
2597+
description=(
2598+
"Returns parameter-oriented metadata such as derived parameter type, grouping hints,\n"
2599+
"defaults, options, tags, population tags, and related graph nodes.\n"
2600+
"If Mutable is not enabled for the project, the command returns an unavailable status\n"
2601+
"instead of hard-failing the CLI.\n\n"
2602+
"EXAMPLES:\n"
2603+
" soft-ue-cli inspect-mutable-parameters /Game/Characters/CO_Hero.CO_Hero"
2604+
),
2605+
formatter_class=argparse.RawDescriptionHelpFormatter,
2606+
)
2607+
p_imp.add_argument("asset_path", help="CustomizableObject asset path")
2608+
p_imp.set_defaults(func=cmd_inspect_mutable_parameters)
2609+
2610+
p_imd = sub.add_parser(
2611+
"inspect-mutable-diagnostics",
2612+
help="Report Mutable plugin availability and best-effort runtime diagnostics for a CustomizableObject asset.",
2613+
description=(
2614+
"Returns a structured diagnostic report covering plugin availability, engine version,\n"
2615+
"graph-derived capability hints, and reflected signals for the inspected asset.\n"
2616+
"If Mutable is not enabled for the project, the command returns a limited/unavailable\n"
2617+
"status instead of hard-failing the CLI.\n\n"
2618+
"EXAMPLES:\n"
2619+
" soft-ue-cli inspect-mutable-diagnostics /Game/Characters/CO_Hero.CO_Hero"
2620+
),
2621+
formatter_class=argparse.RawDescriptionHelpFormatter,
2622+
)
2623+
p_imd.add_argument("asset_path", help="CustomizableObject asset path")
2624+
p_imd.set_defaults(func=cmd_inspect_mutable_diagnostics)
2625+
25612626
p_gad = sub.add_parser(
25622627
"get-asset-diff",
25632628
help="Show SCM diff for an asset (git or Perforce).",

soft_ue_cli/plugin_data/SoftUEBridge/Source/SoftUEBridgeEditor/Private/SoftUEBridgeEditorModule.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
#include "Tools/Asset/DeleteAssetTool.h"
1616
#include "Tools/Asset/GetAssetDiffTool.h"
1717
#include "Tools/Asset/GetAssetPreviewTool.h"
18+
#include "Tools/Asset/InspectCustomizableObjectGraphTool.h"
19+
#include "Tools/Asset/InspectMutableDiagnosticsTool.h"
20+
#include "Tools/Asset/InspectMutableParametersTool.h"
1821
#include "Tools/Asset/OpenAssetTool.h"
1922
#include "Tools/Asset/ReleaseAssetLockTool.h"
2023

@@ -117,6 +120,9 @@ void FSoftUEBridgeEditorModule::StartupModule()
117120
Registry.RegisterToolClass<UDeleteAssetTool>();
118121
Registry.RegisterToolClass<UGetAssetDiffTool>();
119122
Registry.RegisterToolClass<UGetAssetPreviewTool>();
123+
Registry.RegisterToolClass<UInspectCustomizableObjectGraphTool>();
124+
Registry.RegisterToolClass<UInspectMutableDiagnosticsTool>();
125+
Registry.RegisterToolClass<UInspectMutableParametersTool>();
120126
Registry.RegisterToolClass<UOpenAssetTool>();
121127
Registry.RegisterToolClass<UReleaseAssetLockTool>();
122128

soft_ue_cli/plugin_data/SoftUEBridge/Source/SoftUEBridgeEditor/Private/Tools/Asset/AssetIntrospectionUtils.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#include "Internationalization/Text.h"
88
#include "Kismet2/StructureEditorUtils.h"
99
#include "StructUtils/UserDefinedStruct.h"
10+
#if __has_include("UserDefinedStructure/UserDefinedStructEditorData.h")
11+
#include "UserDefinedStructure/UserDefinedStructEditorData.h"
12+
#endif
1013
#include "UObject/EnumProperty.h"
1114
#include "UObject/UnrealType.h"
1215

@@ -131,7 +134,7 @@ namespace
131134
}
132135

133136
FString Exported;
134-
Property->ExportText_Direct(Exported, ValuePtr, ValuePtr, UserStruct, PPF_None);
137+
Property->ExportText_Direct(Exported, ValuePtr, ValuePtr, const_cast<UUserDefinedStruct*>(UserStruct), PPF_None);
135138
return Exported;
136139
}
137140
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright soft-ue-expert. All Rights Reserved.
2+
3+
#include "Tools/Asset/InspectCustomizableObjectGraphTool.h"
4+
5+
#include "Tools/Asset/MutableIntrospectionUtils.h"
6+
7+
FString UInspectCustomizableObjectGraphTool::GetToolDescription() const
8+
{
9+
return TEXT("Inspect a Mutable/CustomizableObject asset graph and return machine-readable nodes, edges, and graph structure. "
10+
"If Mutable is not enabled in the project, the command returns an unavailable status instead of failing the build.");
11+
}
12+
13+
TMap<FString, FBridgeSchemaProperty> UInspectCustomizableObjectGraphTool::GetInputSchema() const
14+
{
15+
TMap<FString, FBridgeSchemaProperty> Schema;
16+
17+
FBridgeSchemaProperty AssetPath;
18+
AssetPath.Type = TEXT("string");
19+
AssetPath.Description = TEXT("Asset path to the CustomizableObject asset (e.g., /Game/Characters/CO_Hero.CO_Hero)");
20+
AssetPath.bRequired = true;
21+
Schema.Add(TEXT("asset_path"), AssetPath);
22+
23+
FBridgeSchemaProperty IncludeNodeProperties;
24+
IncludeNodeProperties.Type = TEXT("boolean");
25+
IncludeNodeProperties.Description = TEXT("Include a broad reflected property dump for each node (default: false).");
26+
Schema.Add(TEXT("include_node_properties"), IncludeNodeProperties);
27+
28+
return Schema;
29+
}
30+
31+
TArray<FString> UInspectCustomizableObjectGraphTool::GetRequiredParams() const
32+
{
33+
return {TEXT("asset_path")};
34+
}
35+
36+
FBridgeToolResult UInspectCustomizableObjectGraphTool::Execute(
37+
const TSharedPtr<FJsonObject>& Arguments,
38+
const FBridgeToolContext& Context)
39+
{
40+
FString AssetPath;
41+
if (!GetStringArg(Arguments, TEXT("asset_path"), AssetPath))
42+
{
43+
return FBridgeToolResult::Error(TEXT("Missing required parameter: asset_path"));
44+
}
45+
46+
const bool bIncludeNodeProperties = GetBoolArgOrDefault(Arguments, TEXT("include_node_properties"), false);
47+
return FBridgeToolResult::Json(
48+
MutableIntrospectionUtils::BuildCustomizableObjectGraphResult(AssetPath, bIncludeNodeProperties));
49+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright soft-ue-expert. All Rights Reserved.
2+
3+
#include "Tools/Asset/InspectMutableDiagnosticsTool.h"
4+
5+
#include "Tools/Asset/MutableIntrospectionUtils.h"
6+
7+
FString UInspectMutableDiagnosticsTool::GetToolDescription() const
8+
{
9+
return TEXT("Inspect Mutable/CustomizableObject availability and best-effort runtime capability signals such as projector usage, plugin state, and graph-derived diagnostics. "
10+
"If Mutable is not enabled in the project, the command returns an unavailable/limited status instead of failing the build.");
11+
}
12+
13+
TMap<FString, FBridgeSchemaProperty> UInspectMutableDiagnosticsTool::GetInputSchema() const
14+
{
15+
TMap<FString, FBridgeSchemaProperty> Schema;
16+
17+
FBridgeSchemaProperty AssetPath;
18+
AssetPath.Type = TEXT("string");
19+
AssetPath.Description = TEXT("Asset path to the CustomizableObject asset (e.g., /Game/Characters/CO_Hero.CO_Hero)");
20+
AssetPath.bRequired = true;
21+
Schema.Add(TEXT("asset_path"), AssetPath);
22+
23+
return Schema;
24+
}
25+
26+
TArray<FString> UInspectMutableDiagnosticsTool::GetRequiredParams() const
27+
{
28+
return {TEXT("asset_path")};
29+
}
30+
31+
FBridgeToolResult UInspectMutableDiagnosticsTool::Execute(
32+
const TSharedPtr<FJsonObject>& Arguments,
33+
const FBridgeToolContext& Context)
34+
{
35+
FString AssetPath;
36+
if (!GetStringArg(Arguments, TEXT("asset_path"), AssetPath))
37+
{
38+
return FBridgeToolResult::Error(TEXT("Missing required parameter: asset_path"));
39+
}
40+
41+
return FBridgeToolResult::Json(MutableIntrospectionUtils::BuildMutableDiagnosticsResult(AssetPath));
42+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright soft-ue-expert. All Rights Reserved.
2+
3+
#include "Tools/Asset/InspectMutableParametersTool.h"
4+
5+
#include "Tools/Asset/MutableIntrospectionUtils.h"
6+
7+
FString UInspectMutableParametersTool::GetToolDescription() const
8+
{
9+
return TEXT("Inspect a Mutable/CustomizableObject asset and derive structured parameter metadata such as groups, defaults, options, tags, and related nodes. "
10+
"If Mutable is not enabled in the project, the command returns an unavailable status instead of failing the build.");
11+
}
12+
13+
TMap<FString, FBridgeSchemaProperty> UInspectMutableParametersTool::GetInputSchema() const
14+
{
15+
TMap<FString, FBridgeSchemaProperty> Schema;
16+
17+
FBridgeSchemaProperty AssetPath;
18+
AssetPath.Type = TEXT("string");
19+
AssetPath.Description = TEXT("Asset path to the CustomizableObject asset (e.g., /Game/Characters/CO_Hero.CO_Hero)");
20+
AssetPath.bRequired = true;
21+
Schema.Add(TEXT("asset_path"), AssetPath);
22+
23+
return Schema;
24+
}
25+
26+
TArray<FString> UInspectMutableParametersTool::GetRequiredParams() const
27+
{
28+
return {TEXT("asset_path")};
29+
}
30+
31+
FBridgeToolResult UInspectMutableParametersTool::Execute(
32+
const TSharedPtr<FJsonObject>& Arguments,
33+
const FBridgeToolContext& Context)
34+
{
35+
FString AssetPath;
36+
if (!GetStringArg(Arguments, TEXT("asset_path"), AssetPath))
37+
{
38+
return FBridgeToolResult::Error(TEXT("Missing required parameter: asset_path"));
39+
}
40+
41+
return FBridgeToolResult::Json(MutableIntrospectionUtils::BuildMutableParameterResult(AssetPath));
42+
}

0 commit comments

Comments
 (0)