unreal-engine-mcp-server 0.5.0 → 0.5.2

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.
Files changed (188) hide show
  1. package/.env.example +1 -1
  2. package/.github/release-drafter-config.yml +51 -0
  3. package/.github/workflows/greetings.yml +5 -1
  4. package/.github/workflows/labeler.yml +2 -1
  5. package/.github/workflows/publish-mcp.yml +2 -4
  6. package/.github/workflows/release-drafter.yml +3 -2
  7. package/.github/workflows/release.yml +3 -3
  8. package/CHANGELOG.md +109 -0
  9. package/CONTRIBUTING.md +1 -1
  10. package/GEMINI.md +115 -0
  11. package/Public/Plugin_setup_guide.mp4 +0 -0
  12. package/README.md +166 -200
  13. package/dist/automation/bridge.d.ts +1 -2
  14. package/dist/automation/bridge.js +24 -23
  15. package/dist/automation/connection-manager.d.ts +1 -0
  16. package/dist/automation/connection-manager.js +10 -0
  17. package/dist/automation/message-handler.js +5 -4
  18. package/dist/automation/request-tracker.d.ts +4 -0
  19. package/dist/automation/request-tracker.js +11 -3
  20. package/dist/config.d.ts +0 -1
  21. package/dist/config.js +0 -1
  22. package/dist/constants.d.ts +4 -0
  23. package/dist/constants.js +4 -0
  24. package/dist/graphql/loaders.d.ts +64 -0
  25. package/dist/graphql/loaders.js +117 -0
  26. package/dist/graphql/resolvers.d.ts +3 -3
  27. package/dist/graphql/resolvers.js +33 -30
  28. package/dist/graphql/server.js +3 -1
  29. package/dist/graphql/types.d.ts +2 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.js +13 -2
  32. package/dist/server-setup.d.ts +0 -1
  33. package/dist/server-setup.js +0 -40
  34. package/dist/tools/actors.d.ts +58 -24
  35. package/dist/tools/actors.js +22 -6
  36. package/dist/tools/assets.d.ts +19 -71
  37. package/dist/tools/assets.js +28 -22
  38. package/dist/tools/base-tool.d.ts +4 -4
  39. package/dist/tools/base-tool.js +1 -1
  40. package/dist/tools/blueprint.d.ts +45 -61
  41. package/dist/tools/blueprint.js +43 -14
  42. package/dist/tools/consolidated-tool-definitions.js +2 -1
  43. package/dist/tools/consolidated-tool-handlers.js +96 -110
  44. package/dist/tools/dynamic-handler-registry.d.ts +11 -9
  45. package/dist/tools/dynamic-handler-registry.js +17 -95
  46. package/dist/tools/editor.d.ts +19 -193
  47. package/dist/tools/editor.js +11 -2
  48. package/dist/tools/environment.d.ts +8 -14
  49. package/dist/tools/foliage.d.ts +18 -143
  50. package/dist/tools/foliage.js +4 -2
  51. package/dist/tools/handlers/actor-handlers.d.ts +1 -1
  52. package/dist/tools/handlers/actor-handlers.js +14 -13
  53. package/dist/tools/handlers/asset-handlers.js +454 -454
  54. package/dist/tools/handlers/sequence-handlers.d.ts +1 -1
  55. package/dist/tools/handlers/sequence-handlers.js +24 -13
  56. package/dist/tools/introspection.d.ts +1 -1
  57. package/dist/tools/introspection.js +1 -1
  58. package/dist/tools/landscape.d.ts +16 -116
  59. package/dist/tools/landscape.js +7 -3
  60. package/dist/tools/level.d.ts +22 -103
  61. package/dist/tools/level.js +26 -18
  62. package/dist/tools/lighting.d.ts +54 -7
  63. package/dist/tools/lighting.js +9 -5
  64. package/dist/tools/materials.d.ts +1 -1
  65. package/dist/tools/materials.js +5 -1
  66. package/dist/tools/niagara.js +37 -2
  67. package/dist/tools/performance.d.ts +0 -1
  68. package/dist/tools/performance.js +0 -1
  69. package/dist/tools/physics.js +5 -1
  70. package/dist/tools/sequence.d.ts +24 -24
  71. package/dist/tools/sequence.js +13 -0
  72. package/dist/tools/ui.d.ts +0 -2
  73. package/dist/types/automation-responses.d.ts +115 -0
  74. package/dist/types/automation-responses.js +2 -0
  75. package/dist/types/responses.d.ts +249 -0
  76. package/dist/types/responses.js +2 -0
  77. package/dist/types/tool-interfaces.d.ts +135 -135
  78. package/dist/types/tool-types.d.ts +2 -0
  79. package/dist/unreal-bridge.js +4 -4
  80. package/dist/utils/command-validator.js +7 -5
  81. package/dist/utils/error-handler.d.ts +24 -2
  82. package/dist/utils/error-handler.js +58 -23
  83. package/dist/utils/normalize.d.ts +7 -4
  84. package/dist/utils/normalize.js +12 -10
  85. package/dist/utils/path-security.d.ts +2 -0
  86. package/dist/utils/path-security.js +24 -0
  87. package/dist/utils/response-factory.d.ts +4 -4
  88. package/dist/utils/response-factory.js +15 -21
  89. package/dist/utils/response-validator.js +88 -73
  90. package/dist/utils/unreal-command-queue.d.ts +2 -0
  91. package/dist/utils/unreal-command-queue.js +8 -1
  92. package/docs/Migration-Guide-v0.5.0.md +1 -9
  93. package/docs/handler-mapping.md +4 -2
  94. package/docs/testing-guide.md +2 -2
  95. package/package.json +12 -6
  96. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +298 -33
  97. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +7 -8
  98. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +229 -319
  99. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +98 -0
  100. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +24 -0
  101. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +96 -0
  102. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +52 -5
  103. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +5 -268
  104. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +57 -2
  105. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +0 -1
  106. package/scripts/run-all-tests.mjs +25 -20
  107. package/server.json +3 -2
  108. package/src/automation/bridge.ts +27 -25
  109. package/src/automation/connection-manager.ts +18 -0
  110. package/src/automation/message-handler.ts +33 -8
  111. package/src/automation/request-tracker.ts +39 -7
  112. package/src/config.ts +1 -1
  113. package/src/constants.ts +7 -0
  114. package/src/graphql/loaders.ts +244 -0
  115. package/src/graphql/resolvers.ts +47 -49
  116. package/src/graphql/server.ts +3 -1
  117. package/src/graphql/types.ts +3 -0
  118. package/src/index.ts +15 -2
  119. package/src/resources/assets.ts +5 -4
  120. package/src/server/tool-registry.ts +3 -3
  121. package/src/server-setup.ts +3 -37
  122. package/src/tools/actors.ts +77 -44
  123. package/src/tools/animation.ts +1 -0
  124. package/src/tools/assets.ts +76 -65
  125. package/src/tools/base-tool.ts +3 -3
  126. package/src/tools/blueprint.ts +170 -104
  127. package/src/tools/consolidated-tool-definitions.ts +2 -1
  128. package/src/tools/consolidated-tool-handlers.ts +129 -150
  129. package/src/tools/dynamic-handler-registry.ts +22 -140
  130. package/src/tools/editor.ts +43 -29
  131. package/src/tools/environment.ts +21 -27
  132. package/src/tools/foliage.ts +28 -25
  133. package/src/tools/handlers/actor-handlers.ts +16 -17
  134. package/src/tools/handlers/asset-handlers.ts +484 -484
  135. package/src/tools/handlers/sequence-handlers.ts +85 -62
  136. package/src/tools/introspection.ts +7 -7
  137. package/src/tools/landscape.ts +34 -28
  138. package/src/tools/level.ts +100 -80
  139. package/src/tools/lighting.ts +25 -20
  140. package/src/tools/materials.ts +9 -3
  141. package/src/tools/niagara.ts +44 -2
  142. package/src/tools/performance.ts +1 -2
  143. package/src/tools/physics.ts +7 -1
  144. package/src/tools/sequence.ts +42 -26
  145. package/src/tools/ui.ts +1 -3
  146. package/src/types/automation-responses.ts +119 -0
  147. package/src/types/responses.ts +355 -0
  148. package/src/types/tool-interfaces.ts +135 -135
  149. package/src/types/tool-types.ts +4 -0
  150. package/src/unreal-bridge.ts +71 -26
  151. package/src/utils/command-validator.ts +47 -5
  152. package/src/utils/error-handler.ts +128 -45
  153. package/src/utils/normalize.test.ts +162 -0
  154. package/src/utils/normalize.ts +38 -16
  155. package/src/utils/path-security.ts +43 -0
  156. package/src/utils/response-factory.ts +29 -24
  157. package/src/utils/response-validator.ts +103 -87
  158. package/src/utils/safe-json.test.ts +90 -0
  159. package/src/utils/unreal-command-queue.ts +13 -1
  160. package/src/utils/validation.test.ts +184 -0
  161. package/tests/test-animation.mjs +358 -33
  162. package/tests/test-asset-graph.mjs +311 -0
  163. package/tests/test-audio.mjs +314 -116
  164. package/tests/test-behavior-tree.mjs +327 -144
  165. package/tests/test-blueprint-graph.mjs +343 -12
  166. package/tests/test-control-editor.mjs +85 -53
  167. package/tests/test-graphql.mjs +58 -8
  168. package/tests/test-input.mjs +349 -0
  169. package/tests/test-inspect.mjs +291 -61
  170. package/tests/test-landscape.mjs +304 -48
  171. package/tests/test-lighting.mjs +428 -0
  172. package/tests/test-manage-level.mjs +70 -51
  173. package/tests/test-performance.mjs +539 -0
  174. package/tests/test-sequence.mjs +82 -46
  175. package/tests/test-system.mjs +72 -33
  176. package/tests/test-wasm.mjs +98 -8
  177. package/vitest.config.ts +35 -0
  178. package/.github/release-drafter.yml +0 -148
  179. package/dist/prompts/index.d.ts +0 -21
  180. package/dist/prompts/index.js +0 -217
  181. package/dist/tools/blueprint/helpers.d.ts +0 -29
  182. package/dist/tools/blueprint/helpers.js +0 -182
  183. package/src/prompts/index.ts +0 -249
  184. package/src/tools/blueprint/helpers.ts +0 -189
  185. package/tests/test-blueprint-events.mjs +0 -35
  186. package/tests/test-extra-tools.mjs +0 -38
  187. package/tests/test-render.mjs +0 -33
  188. package/tests/test-search-assets.mjs +0 -66
@@ -1,30 +1,60 @@
1
1
  import { BaseTool } from './base-tool.js';
2
- import { IBlueprintTools } from '../types/tool-interfaces.js';
2
+ import { IBlueprintTools, StandardActionResponse } from '../types/tool-interfaces.js';
3
3
  import { Logger } from '../utils/logger.js';
4
4
  import { validateAssetParams, concurrencyDelay } from '../utils/validation.js';
5
5
  import { coerceString } from '../utils/result-helpers.js';
6
6
 
7
+ /** Response from automation actions */
8
+ interface ActionResponse extends StandardActionResponse {
9
+ result?: Record<string, unknown>;
10
+ requestId?: string;
11
+ blueprint?: string;
12
+ blueprintPath?: string;
13
+ component?: string;
14
+ componentName?: string;
15
+ componentType?: string;
16
+ componentClass?: string;
17
+ found?: string;
18
+ checked?: string[];
19
+ path?: string;
20
+ nodes?: unknown[];
21
+ graphName?: string;
22
+ }
23
+
24
+ /** Response type guard */
25
+ interface ActionResponseInput {
26
+ success?: boolean;
27
+ message?: string;
28
+ error?: string;
29
+ result?: unknown;
30
+ requestId?: string;
31
+ [key: string]: unknown;
32
+ }
33
+
7
34
  export class BlueprintTools extends BaseTool implements IBlueprintTools {
8
35
  private log = new Logger('BlueprintTools');
9
36
  private pluginBlueprintActionsAvailable: boolean | null = null;
10
37
 
11
- private async sendAction(action: string, payload: Record<string, unknown> = {}, options?: { timeoutMs?: number; waitForEvent?: boolean; waitForEventTimeoutMs?: number }) {
38
+ private async sendAction(action: string, payload: Record<string, unknown> = {}, options?: { timeoutMs?: number; waitForEvent?: boolean; waitForEventTimeoutMs?: number }): Promise<ActionResponse> {
12
39
  const envDefault = Number(process.env.MCP_AUTOMATION_REQUEST_TIMEOUT_MS ?? '120000');
13
40
  const defaultTimeout = Number.isFinite(envDefault) && envDefault > 0 ? envDefault : 120000;
14
41
  const finalTimeout = typeof options?.timeoutMs === 'number' && options?.timeoutMs > 0 ? options.timeoutMs : defaultTimeout;
15
42
  try {
16
- const response: any = await this.sendAutomationRequest(action, payload, { timeoutMs: finalTimeout, waitForEvent: !!options?.waitForEvent, waitForEventTimeoutMs: options?.waitForEventTimeoutMs });
43
+ const response = await this.sendAutomationRequest(action, payload, { timeoutMs: finalTimeout, waitForEvent: !!options?.waitForEvent, waitForEventTimeoutMs: options?.waitForEventTimeoutMs }) as ActionResponseInput;
17
44
  const success = response && response.success !== false;
18
- const result = response.result ?? response;
19
- return { success, message: response.message ?? undefined, error: response.success === false ? (response.error ?? response.message) : undefined, result, requestId: response.requestId } as any;
20
- } catch (err: any) {
21
- return { success: false, error: String(err), message: String(err) } as const;
45
+ const result = (response.result ?? response) as Record<string, unknown>;
46
+ return { success, message: response.message ?? undefined, error: response.success === false ? (response.error ?? response.message) : undefined, result, requestId: response.requestId };
47
+ } catch (err: unknown) {
48
+ const errMsg = err instanceof Error ? err.message : String(err);
49
+ return { success: false, error: errMsg, message: errMsg };
22
50
  }
23
51
  }
24
52
 
25
- private isUnknownActionResponse(res: any): boolean {
53
+ private isUnknownActionResponse(res: ActionResponse | StandardActionResponse | null | undefined): boolean {
26
54
  if (!res) return false;
27
- const txt = String((res.error ?? res.message ?? '')).toLowerCase();
55
+ const errStr = typeof res.error === 'string' ? res.error : '';
56
+ const msgStr = typeof res.message === 'string' ? res.message : '';
57
+ const txt = (errStr || msgStr).toLowerCase();
28
58
  // Only treat specific error codes as "not implemented"
29
59
  return txt.includes('unknown_action') || txt.includes('unknown automation action') || txt.includes('not_implemented') || txt === 'unknown_plugin_action';
30
60
  }
@@ -54,7 +84,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
54
84
  return candidates.filter(Boolean);
55
85
  }
56
86
 
57
- async createBlueprint(params: { name: string; blueprintType?: string; savePath?: string; parentClass?: string; properties?: Record<string, unknown>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
87
+ async createBlueprint(params: { name: string; blueprintType?: string; savePath?: string; parentClass?: string; properties?: Record<string, unknown>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
58
88
  try {
59
89
  const validation = validateAssetParams({ name: params.name, savePath: params.savePath || '/Game/Blueprints' });
60
90
  if (!validation.valid) return { success: false, message: `Failed to create blueprint: ${validation.error}`, error: validation.error };
@@ -84,8 +114,8 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
84
114
  this.pluginBlueprintActionsAvailable = false;
85
115
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_create' } as const;
86
116
  }
87
- return res as any;
88
- } catch (err: any) {
117
+ return res;
118
+ } catch (err: unknown) {
89
119
  // ... (unchanged catch block)
90
120
  const errTxt = String(err ?? '');
91
121
  const isTimeout = errTxt.includes('Request timed out') || errTxt.includes('-32001') || errTxt.toLowerCase().includes('timeout');
@@ -94,12 +124,12 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
94
124
  }
95
125
  return { success: false, error: String(err), message: String(err) } as const;
96
126
  }
97
- } catch (err: any) {
127
+ } catch (err: unknown) {
98
128
  return { success: false, error: String(err), message: String(err) };
99
129
  }
100
130
  }
101
131
 
102
- async modifyConstructionScript(params: { blueprintPath: string; operations: any[]; compile?: boolean; save?: boolean; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
132
+ async modifyConstructionScript(params: { blueprintPath: string; operations: any[]; compile?: boolean; save?: boolean; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
103
133
  const blueprintPath = coerceString(params.blueprintPath);
104
134
  if (!blueprintPath) return { success: false, message: 'Blueprint path is required', error: 'INVALID_BLUEPRINT_PATH' };
105
135
  if (!Array.isArray(params.operations) || params.operations.length === 0) return { success: false, message: 'At least one SCS operation is required', error: 'MISSING_OPERATIONS' };
@@ -112,12 +142,12 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
112
142
  return op;
113
143
  });
114
144
 
115
- const payload: any = { blueprintPath, operations };
145
+ const payload: Record<string, unknown> = { blueprintPath, operations };
116
146
  if (typeof params.compile === 'boolean') payload.compile = params.compile;
117
147
  if (typeof params.save === 'boolean') payload.save = params.save;
118
148
  const res = await this.sendAction('blueprint_modify_scs', payload, { timeoutMs: params.timeoutMs, waitForEvent: !!params.waitForCompletion, waitForEventTimeoutMs: params.waitForCompletionTimeoutMs });
119
149
 
120
- if (res && res.result && typeof res.result === 'object' && (res.result as any).error === 'SCS_UNAVAILABLE') {
150
+ if (res && res.result && typeof res.result === 'object' && res.result?.error === 'SCS_UNAVAILABLE') {
121
151
  this.pluginBlueprintActionsAvailable = false;
122
152
  return { success: false, error: 'SCS_UNAVAILABLE', message: 'Plugin does not support construction script modification (blueprint_modify_scs)' } as const;
123
153
  }
@@ -128,7 +158,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
128
158
  return res;
129
159
  }
130
160
 
131
- async addComponent(params: { blueprintName: string; componentType: string; componentName: string; attachTo?: string; transform?: Record<string, unknown>; properties?: Record<string, unknown>; compile?: boolean; save?: boolean; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
161
+ async addComponent(params: { blueprintName: string; componentType: string; componentName: string; attachTo?: string; transform?: Record<string, unknown>; properties?: Record<string, unknown>; compile?: boolean; save?: boolean; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
132
162
  const blueprintName = coerceString(params.blueprintName);
133
163
  if (!blueprintName) return { success: false as const, message: 'Blueprint name is required', error: 'INVALID_BLUEPRINT' };
134
164
  const componentClass = coerceString(params.componentType);
@@ -144,23 +174,23 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
144
174
  const svcResult = await this.modifyConstructionScript({ blueprintPath: primary, operations: [op], compile: params.compile, save: params.save, timeoutMs: params.timeoutMs, waitForCompletion: params.waitForCompletion, waitForCompletionTimeoutMs: params.waitForCompletionTimeoutMs });
145
175
  if (svcResult && svcResult.success) {
146
176
  this.pluginBlueprintActionsAvailable = true;
147
- return { ...(svcResult as any), component: sanitizedComponentName, componentName: sanitizedComponentName, componentType: componentClass, componentClass, blueprintPath: svcResult.blueprintPath ?? primary } as const;
177
+ return { ...svcResult, component: sanitizedComponentName, componentName: sanitizedComponentName, componentType: componentClass, componentClass, blueprintPath: svcResult.blueprintPath ?? primary } as const;
148
178
  }
149
179
  if (svcResult && (this.isUnknownActionResponse(svcResult) || (svcResult.error && svcResult.error === 'SCS_UNAVAILABLE'))) {
150
180
  this.pluginBlueprintActionsAvailable = false;
151
181
  return { success: false, error: 'SCS_UNAVAILABLE', message: 'Plugin does not support construction script modification (blueprint_modify_scs)' } as const;
152
182
  }
153
- return svcResult as any;
154
- } catch (err: any) {
183
+ return svcResult;
184
+ } catch (err: unknown) {
155
185
  return { success: false, error: String(err) };
156
186
  }
157
187
  }
158
188
 
159
- async waitForBlueprint(blueprintRef: string | string[], timeoutMs?: number) {
189
+ async waitForBlueprint(blueprintRef: string | string[], timeoutMs?: number): Promise<StandardActionResponse> {
160
190
  const candidates = Array.isArray(blueprintRef) ? blueprintRef : this.buildCandidates(blueprintRef as string | undefined);
161
- if (!candidates || candidates.length === 0) return { success: false, error: 'Invalid blueprint reference', checked: [] } as any;
191
+ if (!candidates || candidates.length === 0) return { success: false, error: 'Invalid blueprint reference', checked: [] };
162
192
  if (this.pluginBlueprintActionsAvailable === false) {
163
- return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_exists' } as any;
193
+ return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_exists' };
164
194
  }
165
195
 
166
196
  const start = Date.now();
@@ -175,11 +205,11 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
175
205
  const r = await this.sendAction('blueprint_exists', { blueprintCandidates: [candidate], requestedPath: candidate }, { timeoutMs: Math.min(perCheck, tot) });
176
206
  if (r && r.success && r.result && (r.result.exists === true || r.result.found)) {
177
207
  this.pluginBlueprintActionsAvailable = true;
178
- return { success: true, found: r.result.found ?? candidate } as any;
208
+ return { success: true, found: r.result.found ?? candidate };
179
209
  }
180
210
  if (r && r.success === false && this.isUnknownActionResponse(r)) {
181
211
  this.pluginBlueprintActionsAvailable = false;
182
- return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_exists' } as any;
212
+ return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_exists' };
183
213
  }
184
214
  } catch (_e) {
185
215
  // ignore and try next candidate
@@ -188,12 +218,12 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
188
218
  await new Promise((r) => setTimeout(r, 1000));
189
219
  }
190
220
  if (this.pluginBlueprintActionsAvailable === null) {
191
- return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin availability unknown; blueprint_exists not implemented by plugin' } as any;
221
+ return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin availability unknown; blueprint_exists not implemented by plugin' };
192
222
  }
193
- return { success: false, error: `Timeout waiting for blueprint after ${tot}ms`, checked: candidates } as any;
223
+ return { success: false, error: `Timeout waiting for blueprint after ${tot}ms`, checked: candidates };
194
224
  }
195
225
 
196
- async getBlueprint(params: { blueprintName: string; timeoutMs?: number; }) {
226
+ async getBlueprint(params: { blueprintName: string; timeoutMs?: number; }): Promise<StandardActionResponse> {
197
227
  const candidates = this.buildCandidates(params.blueprintName);
198
228
  const primary = candidates[0];
199
229
  if (!primary) return { success: false, error: 'Invalid blueprint name' } as const;
@@ -201,7 +231,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
201
231
  const pluginResp = await this.sendAction('blueprint_get', { blueprintCandidates: candidates, requestedPath: primary }, { timeoutMs: params.timeoutMs });
202
232
  if (pluginResp && pluginResp.success) {
203
233
  if (pluginResp && typeof pluginResp === 'object') {
204
- return { ...pluginResp, blueprint: pluginResp.result, blueprintPath: primary } as any;
234
+ return { ...pluginResp, blueprint: pluginResp.result, blueprintPath: primary };
205
235
  }
206
236
  return pluginResp;
207
237
  }
@@ -209,12 +239,12 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
209
239
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_get' } as const;
210
240
  }
211
241
  return { success: false, error: pluginResp?.error ?? 'BLUEPRINT_GET_FAILED', message: pluginResp?.message ?? 'Failed to get blueprint via automation bridge' } as const;
212
- } catch (err: any) {
242
+ } catch (err: unknown) {
213
243
  return { success: false, error: String(err), message: String(err) } as const;
214
244
  }
215
245
  }
216
246
 
217
- async getBlueprintInfo(params: { blueprintPath: string; timeoutMs?: number }) {
247
+ async getBlueprintInfo(params: { blueprintPath: string; timeoutMs?: number }): Promise<StandardActionResponse> {
218
248
  const blueprintPath = coerceString(params.blueprintPath);
219
249
  if (!blueprintPath) {
220
250
  return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
@@ -243,29 +273,29 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
243
273
  }
244
274
 
245
275
  return { success: false, error: resp?.error ?? 'BLUEPRINT_GET_FAILED', message: resp?.message ?? 'Failed to get blueprint via automation bridge' } as const;
246
- } catch (err: any) {
276
+ } catch (err: unknown) {
247
277
  return { success: false, error: String(err), message: String(err) } as const;
248
278
  }
249
279
  }
250
280
 
251
- async probeSubobjectDataHandle(opts: { componentClass?: string } = {}) {
281
+ async probeSubobjectDataHandle(opts: { componentClass?: string } = {}): Promise<StandardActionResponse> {
252
282
  return await this.sendAction('blueprint_probe_subobject_handle', { componentClass: opts.componentClass });
253
283
  }
254
284
 
255
- async setBlueprintDefault(params: { blueprintName: string; propertyName: string; value: unknown }) {
285
+ async setBlueprintDefault(params: { blueprintName: string; propertyName: string; value: unknown }): Promise<StandardActionResponse> {
256
286
  const candidates = this.buildCandidates(params.blueprintName);
257
287
  const primary = candidates[0];
258
288
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
259
- return await this.sendAction('blueprint_set_default', { blueprintCandidates: candidates, requestedPath: primary, propertyName: params.propertyName, value: params.value });
289
+ return await this.sendAction('blueprint_set_default', { blueprintCandidates: candidates, requestedPath: primary, propertyName: params.propertyName, value: params.value }) as any;
260
290
  }
261
291
 
262
- async addVariable(params: { blueprintName: string; variableName: string; variableType: string; defaultValue?: any; category?: string; isReplicated?: boolean; isPublic?: boolean; variablePinType?: Record<string, unknown>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
292
+ async addVariable(params: { blueprintName: string; variableName: string; variableType: string; defaultValue?: any; category?: string; isReplicated?: boolean; isPublic?: boolean; variablePinType?: Record<string, unknown>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
263
293
  const candidates = this.buildCandidates(params.blueprintName);
264
294
  const primary = candidates[0];
265
295
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
266
296
  const pluginResp = await this.sendAction('blueprint_add_variable', { blueprintCandidates: candidates, requestedPath: primary, variableName: params.variableName, variableType: params.variableType, defaultValue: params.defaultValue, category: params.category, isReplicated: params.isReplicated, isPublic: params.isPublic, variablePinType: params.variablePinType }, { timeoutMs: params.timeoutMs, waitForEvent: !!params.waitForCompletion, waitForEventTimeoutMs: params.waitForCompletionTimeoutMs });
267
297
  if (pluginResp && pluginResp.success) {
268
- return pluginResp;
298
+ return pluginResp as any;
269
299
  }
270
300
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
271
301
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_add_variable' } as const;
@@ -273,24 +303,24 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
273
303
  return { success: false, error: pluginResp?.error ?? 'BLUEPRINT_ADD_VARIABLE_FAILED', message: pluginResp?.message ?? 'Failed to add variable via automation bridge' } as const;
274
304
  }
275
305
 
276
- async removeVariable(params: { blueprintName: string; variableName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
306
+ async removeVariable(params: { blueprintName: string; variableName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
277
307
  const candidates = this.buildCandidates(params.blueprintName);
278
308
  const primary = candidates[0];
279
309
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
280
310
  const pluginResp = await this.sendAction('blueprint_remove_variable', { blueprintCandidates: candidates, requestedPath: primary, variableName: params.variableName }, { timeoutMs: params.timeoutMs, waitForEvent: !!params.waitForCompletion, waitForEventTimeoutMs: params.waitForCompletionTimeoutMs });
281
- if (pluginResp && pluginResp.success) return pluginResp;
311
+ if (pluginResp && pluginResp.success) return pluginResp as any;
282
312
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
283
313
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_remove_variable' } as const;
284
314
  }
285
315
  return { success: false, error: pluginResp?.error ?? 'BLUEPRINT_REMOVE_VARIABLE_FAILED', message: pluginResp?.message ?? 'Failed to remove variable via automation bridge' } as const;
286
316
  }
287
317
 
288
- async renameVariable(params: { blueprintName: string; oldName: string; newName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
318
+ async renameVariable(params: { blueprintName: string; oldName: string; newName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
289
319
  const candidates = this.buildCandidates(params.blueprintName);
290
320
  const primary = candidates[0];
291
321
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
292
322
  const pluginResp = await this.sendAction('blueprint_rename_variable', { blueprintCandidates: candidates, requestedPath: primary, oldName: params.oldName, newName: params.newName }, { timeoutMs: params.timeoutMs, waitForEvent: !!params.waitForCompletion, waitForEventTimeoutMs: params.waitForCompletionTimeoutMs });
293
- if (pluginResp && pluginResp.success) return pluginResp;
323
+ if (pluginResp && pluginResp.success) return pluginResp as any;
294
324
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
295
325
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_rename_variable' } as const;
296
326
  }
@@ -299,13 +329,13 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
299
329
 
300
330
 
301
331
 
302
- async addEvent(params: { blueprintName: string; eventType: string; customEventName?: string; parameters?: Array<{ name: string; type: string }>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
332
+ async addEvent(params: { blueprintName: string; eventType: string; customEventName?: string; parameters?: Array<{ name: string; type: string }>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
303
333
  const candidates = this.buildCandidates(params.blueprintName);
304
334
  const primary = candidates[0];
305
335
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
306
336
  const pluginResp = await this.sendAction('blueprint_add_event', { blueprintCandidates: candidates, requestedPath: primary, eventType: params.eventType, customEventName: params.customEventName, parameters: params.parameters }, { timeoutMs: params.timeoutMs, waitForEvent: !!params.waitForCompletion, waitForEventTimeoutMs: params.waitForCompletionTimeoutMs });
307
337
  if (pluginResp && pluginResp.success) {
308
- return pluginResp;
338
+ return pluginResp as any;
309
339
  }
310
340
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
311
341
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_add_event' } as const;
@@ -313,7 +343,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
313
343
  return { success: false, error: pluginResp?.error ?? 'BLUEPRINT_ADD_EVENT_FAILED', message: pluginResp?.message ?? 'Failed to add event via automation bridge' } as const;
314
344
  }
315
345
 
316
- async removeEvent(params: { blueprintName: string; eventName: string; customEventName?: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
346
+ async removeEvent(params: { blueprintName: string; eventName: string; customEventName?: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
317
347
  const candidates = this.buildCandidates(params.blueprintName);
318
348
  const primary = candidates[0];
319
349
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
@@ -325,24 +355,24 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
325
355
  try {
326
356
  const pluginResp = await this.sendAction('blueprint_remove_event', { blueprintCandidates: candidates, requestedPath: primary, eventName: finalEventName }, { timeoutMs: params.timeoutMs, waitForEvent: !!params.waitForCompletion, waitForEventTimeoutMs: params.waitForCompletionTimeoutMs });
327
357
  if (pluginResp && pluginResp.success) {
328
- return pluginResp;
358
+ return pluginResp as any;
329
359
  }
330
360
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
331
361
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_remove_event' } as const;
332
362
  }
333
363
  return { success: false, error: pluginResp?.error ?? 'BLUEPRINT_REMOVE_EVENT_FAILED', message: pluginResp?.message ?? 'Failed to remove event via automation bridge' } as const;
334
- } catch (err: any) {
364
+ } catch (err: unknown) {
335
365
  return { success: false, error: String(err), message: String(err) } as const;
336
366
  }
337
367
  }
338
368
 
339
- async addFunction(params: { blueprintName: string; functionName: string; inputs?: Array<{ name: string; type: string }>; outputs?: Array<{ name: string; type: string }>; isPublic?: boolean; category?: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
369
+ async addFunction(params: { blueprintName: string; functionName: string; inputs?: Array<{ name: string; type: string }>; outputs?: Array<{ name: string; type: string }>; isPublic?: boolean; category?: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
340
370
  const candidates = this.buildCandidates(params.blueprintName);
341
371
  const primary = candidates[0];
342
372
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
343
373
  const pluginResp = await this.sendAction('blueprint_add_function', { blueprintCandidates: candidates, requestedPath: primary, functionName: params.functionName, inputs: params.inputs, outputs: params.outputs, isPublic: params.isPublic, category: params.category }, { timeoutMs: params.timeoutMs, waitForEvent: !!params.waitForCompletion, waitForEventTimeoutMs: params.waitForCompletionTimeoutMs });
344
374
  if (pluginResp && pluginResp.success) {
345
- return pluginResp;
375
+ return pluginResp as any;
346
376
  }
347
377
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
348
378
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_add_function' } as const;
@@ -350,13 +380,13 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
350
380
  return { success: false, error: pluginResp?.error ?? 'BLUEPRINT_ADD_FUNCTION_FAILED', message: pluginResp?.message ?? 'Failed to add function via automation bridge' } as const;
351
381
  }
352
382
 
353
- async setVariableMetadata(params: { blueprintName: string; variableName: string; metadata: Record<string, unknown>; timeoutMs?: number }) {
383
+ async setVariableMetadata(params: { blueprintName: string; variableName: string; metadata: Record<string, unknown>; timeoutMs?: number }): Promise<StandardActionResponse> {
354
384
  const candidates = this.buildCandidates(params.blueprintName);
355
385
  const primary = candidates[0];
356
386
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
357
387
  const pluginResp = await this.sendAction('blueprint_set_variable_metadata', { blueprintCandidates: candidates, requestedPath: primary, variableName: params.variableName, metadata: params.metadata }, { timeoutMs: params.timeoutMs });
358
388
  if (pluginResp && pluginResp.success) {
359
- return pluginResp;
389
+ return pluginResp as any;
360
390
  }
361
391
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
362
392
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_set_variable_metadata' } as const;
@@ -364,19 +394,19 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
364
394
  return { success: false, error: pluginResp?.error ?? 'SET_VARIABLE_METADATA_FAILED', message: pluginResp?.message ?? 'Failed to set variable metadata via automation bridge' } as const;
365
395
  }
366
396
 
367
- async addConstructionScript(params: { blueprintName: string; scriptName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }) {
397
+ async addConstructionScript(params: { blueprintName: string; scriptName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse> {
368
398
  const candidates = this.buildCandidates(params.blueprintName);
369
399
  const primary = candidates[0];
370
400
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
371
401
  const pluginResp = await this.sendAction('blueprint_add_construction_script', { blueprintCandidates: candidates, requestedPath: primary, scriptName: params.scriptName }, { timeoutMs: params.timeoutMs, waitForEvent: !!params.waitForCompletion, waitForEventTimeoutMs: params.waitForCompletionTimeoutMs });
372
- if (pluginResp && pluginResp.success) return pluginResp;
402
+ if (pluginResp && pluginResp.success) return pluginResp as any;
373
403
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
374
404
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_add_construction_script' } as const;
375
405
  }
376
406
  return { success: false, error: pluginResp?.error ?? 'ADD_CONSTRUCTION_SCRIPT_FAILED', message: pluginResp?.message ?? 'Failed to add construction script via automation bridge' } as const;
377
407
  }
378
408
 
379
- async compileBlueprint(params: { blueprintName: string; saveAfterCompile?: boolean; }) {
409
+ async compileBlueprint(params: { blueprintName: string; saveAfterCompile?: boolean; }): Promise<StandardActionResponse> {
380
410
  try {
381
411
  const candidates = this.buildCandidates(params.blueprintName);
382
412
  const primary = candidates[0] ?? params.blueprintName;
@@ -386,19 +416,19 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
386
416
  ...pluginResp,
387
417
  blueprint: primary,
388
418
  message: pluginResp.message || `Compiled ${primary}`
389
- };
419
+ } as any;
390
420
  }
391
421
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
392
422
  this.pluginBlueprintActionsAvailable = false;
393
423
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement blueprint_compile' } as const;
394
424
  }
395
425
  return { success: false, error: pluginResp?.error ?? 'BLUEPRINT_COMPILE_FAILED', message: pluginResp?.message ?? 'Failed to compile blueprint via automation bridge' } as const;
396
- } catch (err: any) {
426
+ } catch (err: unknown) {
397
427
  return { success: false, error: String(err) };
398
428
  }
399
429
  }
400
430
 
401
- async getBlueprintSCS(params: { blueprintPath: string; timeoutMs?: number }) {
431
+ async getBlueprintSCS(params: { blueprintPath: string; timeoutMs?: number }): Promise<StandardActionResponse> {
402
432
  const blueprintPath = coerceString(params.blueprintPath);
403
433
  if (!blueprintPath) {
404
434
  return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
@@ -409,12 +439,12 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
409
439
  { blueprint_path: blueprintPath },
410
440
  { timeoutMs: params.timeoutMs });
411
441
 
412
- if (pluginResp && pluginResp.success) return pluginResp;
442
+ if (pluginResp && pluginResp.success) return pluginResp as any;
413
443
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
414
444
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement get_blueprint_scs' } as const;
415
445
  }
416
446
  return { success: false, error: pluginResp?.error ?? 'GET_SCS_FAILED', message: pluginResp?.message ?? 'Failed to get SCS via automation bridge' } as const;
417
- } catch (err: any) {
447
+ } catch (err: unknown) {
418
448
  return { success: false, error: String(err), message: String(err) } as const;
419
449
  }
420
450
  }
@@ -427,7 +457,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
427
457
  meshPath?: string;
428
458
  materialPath?: string;
429
459
  timeoutMs?: number;
430
- }) {
460
+ }): Promise<StandardActionResponse> {
431
461
  const blueprintPath = coerceString(params.blueprintPath);
432
462
  if (!blueprintPath) {
433
463
  return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
@@ -463,21 +493,21 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
463
493
  const pluginResp = await this.sendAction('add_scs_component', payload, { timeoutMs: params.timeoutMs });
464
494
 
465
495
  if (pluginResp && pluginResp.success === false) {
466
- if ((pluginResp as any).message) {
467
- this.log.warn?.(`addSCSComponent reported warning: ${(pluginResp as any).message}`);
496
+ if (pluginResp?.message) {
497
+ this.log.warn?.(`addSCSComponent reported warning: ${pluginResp?.message}`);
468
498
  }
469
499
  }
470
- if (pluginResp && pluginResp.success) return pluginResp;
500
+ if (pluginResp && pluginResp.success) return pluginResp as any;
471
501
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
472
502
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement add_scs_component' } as const;
473
503
  }
474
504
  return { success: false, error: pluginResp?.error ?? 'ADD_SCS_COMPONENT_FAILED', message: pluginResp?.message ?? 'Failed to add SCS component via automation bridge' } as const;
475
- } catch (err: any) {
505
+ } catch (err: unknown) {
476
506
  return { success: false, error: String(err), message: String(err) } as const;
477
507
  }
478
508
  }
479
509
 
480
- async removeSCSComponent(params: { blueprintPath: string; componentName: string; timeoutMs?: number }) {
510
+ async removeSCSComponent(params: { blueprintPath: string; componentName: string; timeoutMs?: number }): Promise<StandardActionResponse> {
481
511
  const blueprintPath = coerceString(params.blueprintPath);
482
512
  if (!blueprintPath) {
483
513
  return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
@@ -494,16 +524,16 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
494
524
  { timeoutMs: params.timeoutMs });
495
525
 
496
526
  if (pluginResp && pluginResp.success === false) {
497
- if ((pluginResp as any).message) {
498
- this.log.warn?.(`removeSCSComponent reported warning: ${(pluginResp as any).message}`);
527
+ if (pluginResp?.message) {
528
+ this.log.warn?.(`removeSCSComponent reported warning: ${pluginResp?.message}`);
499
529
  }
500
530
  }
501
- if (pluginResp && pluginResp.success) return pluginResp;
531
+ if (pluginResp && pluginResp.success) return pluginResp as any;
502
532
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
503
533
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement remove_scs_component' } as const;
504
534
  }
505
535
  return { success: false, error: pluginResp?.error ?? 'REMOVE_SCS_COMPONENT_FAILED', message: pluginResp?.message ?? 'Failed to remove SCS component via automation bridge' } as const;
506
- } catch (err: any) {
536
+ } catch (err: unknown) {
507
537
  return { success: false, error: String(err), message: String(err) } as const;
508
538
  }
509
539
  }
@@ -513,7 +543,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
513
543
  componentName: string;
514
544
  newParent: string;
515
545
  timeoutMs?: number;
516
- }) {
546
+ }): Promise<StandardActionResponse> {
517
547
  const blueprintPath = coerceString(params.blueprintPath);
518
548
  if (!blueprintPath) {
519
549
  return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
@@ -534,16 +564,16 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
534
564
  { timeoutMs: params.timeoutMs });
535
565
 
536
566
  if (pluginResp && pluginResp.success === false) {
537
- if ((pluginResp as any).message) {
538
- this.log.warn?.(`reparentSCSComponent reported warning: ${(pluginResp as any).message}`);
567
+ if (pluginResp?.message) {
568
+ this.log.warn?.(`reparentSCSComponent reported warning: ${pluginResp?.message}`);
539
569
  }
540
570
  }
541
- if (pluginResp && pluginResp.success) return pluginResp;
571
+ if (pluginResp && pluginResp.success) return pluginResp as any;
542
572
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
543
573
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement reparent_scs_component' } as const;
544
574
  }
545
575
  return { success: false, error: pluginResp?.error ?? 'REPARENT_SCS_COMPONENT_FAILED', message: pluginResp?.message ?? 'Failed to reparent SCS component via automation bridge' } as const;
546
- } catch (err: any) {
576
+ } catch (err: unknown) {
547
577
  return { success: false, error: String(err), message: String(err) } as const;
548
578
  }
549
579
  }
@@ -555,7 +585,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
555
585
  rotation?: [number, number, number];
556
586
  scale?: [number, number, number];
557
587
  timeoutMs?: number;
558
- }) {
588
+ }): Promise<StandardActionResponse> {
559
589
  const blueprintPath = coerceString(params.blueprintPath);
560
590
  if (!blueprintPath) {
561
591
  return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
@@ -579,16 +609,16 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
579
609
  const pluginResp = await this.sendAction('set_scs_component_transform', payload, { timeoutMs: params.timeoutMs });
580
610
 
581
611
  if (pluginResp && pluginResp.success === false) {
582
- if ((pluginResp as any).message) {
583
- this.log.warn?.(`setSCSComponentTransform reported warning: ${(pluginResp as any).message}`);
612
+ if (pluginResp?.message) {
613
+ this.log.warn?.(`setSCSComponentTransform reported warning: ${pluginResp?.message}`);
584
614
  }
585
615
  }
586
- if (pluginResp && pluginResp.success) return pluginResp;
616
+ if (pluginResp && pluginResp.success) return pluginResp as any;
587
617
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
588
618
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement set_scs_component_transform' } as const;
589
619
  }
590
620
  return { success: false, error: pluginResp?.error ?? 'SET_SCS_TRANSFORM_FAILED', message: pluginResp?.message ?? 'Failed to set SCS component transform via automation bridge' } as const;
591
- } catch (err: any) {
621
+ } catch (err: unknown) {
592
622
  return { success: false, error: String(err), message: String(err) } as const;
593
623
  }
594
624
  }
@@ -599,7 +629,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
599
629
  propertyName: string;
600
630
  propertyValue: any;
601
631
  timeoutMs?: number;
602
- }) {
632
+ }): Promise<StandardActionResponse> {
603
633
  const blueprintPath = coerceString(params.blueprintPath);
604
634
  if (!blueprintPath) {
605
635
  return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
@@ -628,16 +658,16 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
628
658
  { timeoutMs: params.timeoutMs });
629
659
 
630
660
  if (pluginResp && pluginResp.success === false) {
631
- if ((pluginResp as any).message) {
632
- this.log.warn?.(`setSCSComponentProperty reported warning: ${(pluginResp as any).message}`);
661
+ if (pluginResp?.message) {
662
+ this.log.warn?.(`setSCSComponentProperty reported warning: ${pluginResp?.message}`);
633
663
  }
634
664
  }
635
- if (pluginResp && pluginResp.success) return pluginResp;
665
+ if (pluginResp && pluginResp.success) return pluginResp as any;
636
666
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
637
667
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement set_scs_component_property' } as const;
638
668
  }
639
669
  return { success: false, error: pluginResp?.error ?? 'SET_SCS_PROPERTY_FAILED', message: pluginResp?.message ?? 'Failed to set SCS component property via automation bridge' } as const;
640
- } catch (err: any) {
670
+ } catch (err: unknown) {
641
671
  return { success: false, error: String(err), message: String(err) } as const;
642
672
  }
643
673
  }
@@ -646,7 +676,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
646
676
  blueprintPath: string;
647
677
  graphName?: string;
648
678
  timeoutMs?: number;
649
- }) {
679
+ }): Promise<StandardActionResponse> {
650
680
  const blueprintPath = coerceString(params.blueprintPath);
651
681
  if (!blueprintPath) {
652
682
  return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
@@ -662,15 +692,15 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
662
692
  if (pluginResp && pluginResp.success) {
663
693
  return {
664
694
  success: true,
665
- nodes: (pluginResp.result as any).nodes,
666
- graphName: (pluginResp.result as any).graphName
695
+ nodes: (pluginResp.result as Record<string, unknown>).nodes,
696
+ graphName: (pluginResp.result as Record<string, unknown>).graphName
667
697
  };
668
698
  }
669
699
  if (pluginResp && this.isUnknownActionResponse(pluginResp)) {
670
700
  return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement get_nodes' } as const;
671
701
  }
672
702
  return { success: false, error: pluginResp?.error ?? 'GET_NODES_FAILED', message: pluginResp?.message ?? 'Failed to get blueprint nodes' } as const;
673
- } catch (err: any) {
703
+ } catch (err: unknown) {
674
704
  return { success: false, error: String(err), message: String(err) } as const;
675
705
  }
676
706
  }
@@ -688,13 +718,13 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
688
718
  posX?: number;
689
719
  posY?: number;
690
720
  timeoutMs?: number;
691
- }) {
721
+ }): Promise<StandardActionResponse> {
692
722
  const candidates = this.buildCandidates(params.blueprintName);
693
723
  const primary = candidates[0];
694
724
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
695
725
 
696
726
  // Fix: C++ expects 'manage_blueprint_graph' with 'subAction' = 'create_node'
697
- const payload: any = {
727
+ const payload: Record<string, unknown> = {
698
728
  subAction: 'create_node',
699
729
  assetPath: primary, // C++ expects 'assetPath' or 'blueprintPath'
700
730
  nodeType: params.nodeType,
@@ -708,7 +738,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
708
738
  y: params.posY
709
739
  };
710
740
  const res = await this.sendAction('manage_blueprint_graph', payload, { timeoutMs: params.timeoutMs });
711
- return res;
741
+ return res as any;
712
742
  }
713
743
 
714
744
  async deleteNode(params: {
@@ -716,7 +746,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
716
746
  nodeId: string;
717
747
  graphName?: string;
718
748
  timeoutMs?: number;
719
- }) {
749
+ }): Promise<StandardActionResponse> {
720
750
  const blueprintPath = coerceString(params.blueprintPath);
721
751
  if (!blueprintPath) return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
722
752
  if (!params.nodeId) return { success: false, error: 'INVALID_NODE_ID', message: 'Node ID is required' } as const;
@@ -727,7 +757,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
727
757
  graphName: params.graphName || 'EventGraph',
728
758
  nodeId: params.nodeId
729
759
  }, { timeoutMs: params.timeoutMs });
730
- return res;
760
+ return res as any;
731
761
  }
732
762
 
733
763
  async createRerouteNode(params: {
@@ -736,7 +766,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
736
766
  x: number;
737
767
  y: number;
738
768
  timeoutMs?: number;
739
- }) {
769
+ }): Promise<StandardActionResponse> {
740
770
  const blueprintPath = coerceString(params.blueprintPath);
741
771
  if (!blueprintPath) return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
742
772
 
@@ -747,7 +777,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
747
777
  x: params.x,
748
778
  y: params.y
749
779
  }, { timeoutMs: params.timeoutMs });
750
- return res;
780
+ return res as any;
751
781
  }
752
782
 
753
783
  async setNodeProperty(params: {
@@ -757,7 +787,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
757
787
  value: string;
758
788
  graphName?: string;
759
789
  timeoutMs?: number;
760
- }) {
790
+ }): Promise<StandardActionResponse> {
761
791
  const blueprintPath = coerceString(params.blueprintPath);
762
792
  if (!blueprintPath) return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
763
793
  if (!params.nodeId) return { success: false, error: 'INVALID_NODE_ID', message: 'Node ID is required' } as const;
@@ -771,7 +801,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
771
801
  propertyName: params.propertyName,
772
802
  value: params.value
773
803
  }, { timeoutMs: params.timeoutMs });
774
- return res;
804
+ return res as any;
775
805
  }
776
806
 
777
807
  async getNodeDetails(params: {
@@ -779,7 +809,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
779
809
  nodeId: string;
780
810
  graphName?: string;
781
811
  timeoutMs?: number;
782
- }) {
812
+ }): Promise<StandardActionResponse> {
783
813
  const blueprintPath = coerceString(params.blueprintPath);
784
814
  if (!blueprintPath) return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
785
815
  if (!params.nodeId) return { success: false, error: 'INVALID_NODE_ID', message: 'Node ID is required' } as const;
@@ -790,14 +820,14 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
790
820
  graphName: params.graphName || 'EventGraph',
791
821
  nodeId: params.nodeId
792
822
  }, { timeoutMs: params.timeoutMs });
793
- return res;
823
+ return res as any;
794
824
  }
795
825
 
796
826
  async getGraphDetails(params: {
797
827
  blueprintPath: string;
798
828
  graphName?: string;
799
829
  timeoutMs?: number;
800
- }) {
830
+ }): Promise<StandardActionResponse> {
801
831
  const blueprintPath = coerceString(params.blueprintPath);
802
832
  if (!blueprintPath) return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
803
833
 
@@ -806,7 +836,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
806
836
  blueprintPath: blueprintPath,
807
837
  graphName: params.graphName || 'EventGraph'
808
838
  }, { timeoutMs: params.timeoutMs });
809
- return res;
839
+ return res as any;
810
840
  }
811
841
 
812
842
  async getPinDetails(params: {
@@ -815,7 +845,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
815
845
  pinName?: string;
816
846
  graphName?: string;
817
847
  timeoutMs?: number;
818
- }) {
848
+ }): Promise<StandardActionResponse> {
819
849
  const blueprintPath = coerceString(params.blueprintPath);
820
850
  if (!blueprintPath) return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
821
851
  if (!params.nodeId) return { success: false, error: 'INVALID_NODE_ID', message: 'Node ID is required' } as const;
@@ -827,7 +857,43 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
827
857
  nodeId: params.nodeId,
828
858
  pinName: params.pinName
829
859
  }, { timeoutMs: params.timeoutMs });
830
- return res;
860
+ return res as any;
861
+ }
862
+
863
+ async listNodeTypes(params: {
864
+ blueprintPath?: string;
865
+ timeoutMs?: number;
866
+ } = {}): Promise<StandardActionResponse> {
867
+ const res = await this.sendAction('manage_blueprint_graph', {
868
+ subAction: 'list_node_types',
869
+ blueprintPath: params.blueprintPath || '/Game/Temp',
870
+ graphName: 'EventGraph'
871
+ }, { timeoutMs: params.timeoutMs });
872
+ return res as any;
873
+ }
874
+
875
+ async setPinDefaultValue(params: {
876
+ blueprintPath: string;
877
+ nodeId: string;
878
+ pinName: string;
879
+ value: string;
880
+ graphName?: string;
881
+ timeoutMs?: number;
882
+ }): Promise<StandardActionResponse> {
883
+ const blueprintPath = coerceString(params.blueprintPath);
884
+ if (!blueprintPath) return { success: false, error: 'INVALID_BLUEPRINT_PATH', message: 'Blueprint path is required' } as const;
885
+ if (!params.nodeId) return { success: false, error: 'INVALID_NODE_ID', message: 'Node ID is required' } as const;
886
+ if (!params.pinName) return { success: false, error: 'INVALID_PIN_NAME', message: 'Pin name is required' } as const;
887
+
888
+ const res = await this.sendAction('manage_blueprint_graph', {
889
+ subAction: 'set_pin_default_value',
890
+ blueprintPath: blueprintPath,
891
+ graphName: params.graphName || 'EventGraph',
892
+ nodeId: params.nodeId,
893
+ pinName: params.pinName,
894
+ value: params.value
895
+ }, { timeoutMs: params.timeoutMs });
896
+ return res as any;
831
897
  }
832
898
 
833
899
 
@@ -838,7 +904,7 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
838
904
  sourcePinName?: string;
839
905
  targetPinName?: string;
840
906
  timeoutMs?: number;
841
- }) {
907
+ }): Promise<StandardActionResponse> {
842
908
  const candidates = this.buildCandidates(params.blueprintName);
843
909
  const primary = candidates[0];
844
910
  if (!primary) return { success: false as const, error: 'Invalid blueprint name' };
@@ -869,6 +935,6 @@ export class BlueprintTools extends BaseTool implements IBlueprintTools {
869
935
  fromPinName: fromPinName,
870
936
  toPinName: toPinName
871
937
  }, { timeoutMs: params.timeoutMs });
872
- return res;
938
+ return res as any;
873
939
  }
874
940
  }