Unified, portable Unreal Engine MCP system plugin
Merge of the two project copies into one self-contained plugin (the superset: variable_op + variables.py, full pcg_op runtime/declarative/preset ops, the CreateWidgetFloatAnimation widget tool, and full Voxel graph authoring). Made fully project- and machine-agnostic — no hardcoded paths: - New src/projectPaths.js auto-detects the host .uproject (walk-up), project name, Editor build target, log file, and engine install (EngineAssociation via launcher manifest/registry, else installed-engine scan). All overridable via UE_* env vars. - Rewired buildOrchestrator/insights/launcher/insightsExporter/server.js and the Python workers (cpp_scaffold, live_coding, apply_graph, console) off the old C:/Github/ihy, IHY*, E:/UE_Versions and UE_5.7 literals onto the resolver. - Voxel made optional: Build.cs auto-detects the Voxel plugin (env UE_MCP_WITH_VOXEL override) and the C++ compiles to stubs under WITH_MCP_VOXEL, so the module builds in projects without Voxel; .uplugin marks Voxel optional. - De-branded the agent-gateway and docs; scrubbed a leaked API key; excluded node_modules/Binaries/Intermediate/__pycache__/secrets from the repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
70
test/nodeSpec.test.js
Normal file
70
test/nodeSpec.test.js
Normal file
@ -0,0 +1,70 @@
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { validateGraph, NODE_KINDS } from "../src/nodeSpec.js";
|
||||
|
||||
test("validateGraph allows missing bp_path (auto-detect mode)", () => {
|
||||
const errs = validateGraph({ nodes: [] });
|
||||
assert.deepEqual(errs, []);
|
||||
});
|
||||
|
||||
test("validateGraph rejects bp_path not under /Game/ when provided", () => {
|
||||
const errs = validateGraph({ bp_path: "/Engine/Foo", nodes: [] });
|
||||
assert.ok(errs.some(e => e.includes("bp_path")));
|
||||
});
|
||||
|
||||
test("validateGraph accepts empty-string bp_path as auto-detect", () => {
|
||||
const errs = validateGraph({ bp_path: "", nodes: [] });
|
||||
assert.deepEqual(errs, []);
|
||||
});
|
||||
|
||||
test("validateGraph accepts a minimal valid graph", () => {
|
||||
const errs = validateGraph({
|
||||
bp_path: "/Game/Test/BP_Foo",
|
||||
nodes: [{ id: "n1", kind: "branch" }],
|
||||
edges: [],
|
||||
});
|
||||
assert.deepEqual(errs, []);
|
||||
});
|
||||
|
||||
test("validateGraph catches duplicate ids", () => {
|
||||
const errs = validateGraph({
|
||||
bp_path: "/Game/X",
|
||||
nodes: [
|
||||
{ id: "a", kind: "branch" },
|
||||
{ id: "a", kind: "sequence" },
|
||||
],
|
||||
});
|
||||
assert.ok(errs.some(e => e.includes("duplicate")));
|
||||
});
|
||||
|
||||
test("validateGraph catches unknown kind", () => {
|
||||
const errs = validateGraph({
|
||||
bp_path: "/Game/X",
|
||||
nodes: [{ id: "a", kind: "teleport_to_mars" }],
|
||||
});
|
||||
assert.ok(errs.some(e => e.includes("teleport_to_mars")));
|
||||
});
|
||||
|
||||
test("validateGraph catches edge to unknown node", () => {
|
||||
const errs = validateGraph({
|
||||
bp_path: "/Game/X",
|
||||
nodes: [{ id: "a", kind: "branch" }],
|
||||
edges: [{ from: ["a", "Then"], to: ["ghost", "Exec"] }],
|
||||
});
|
||||
assert.ok(errs.some(e => e.includes("ghost")));
|
||||
});
|
||||
|
||||
test("NODE_KINDS contains the documented set", () => {
|
||||
for (const k of [
|
||||
"call_function", "event", "custom_event", "component_event",
|
||||
"variable_get", "variable_set", "self",
|
||||
"branch", "sequence",
|
||||
"switch_int", "switch_string", "switch_enum",
|
||||
"macro", "cast",
|
||||
"make_array", "make_struct", "break_struct", "set_fields_in_struct",
|
||||
"spawn_actor", "format_text", "get_subsystem", "load_asset",
|
||||
"bind_delegate", "unbind_delegate", "call_delegate", "assign_delegate",
|
||||
]) {
|
||||
assert.ok(NODE_KINDS.has(k), `missing kind: ${k}`);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user