blueprint-extractor-mcp 3.2.0 → 4.0.0

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 (45) hide show
  1. package/dist/catalogs/example-catalog.js +88 -0
  2. package/dist/helpers/alias-registration.d.ts +7 -0
  3. package/dist/helpers/alias-registration.js +36 -0
  4. package/dist/helpers/composite-patterns.d.ts +40 -0
  5. package/dist/helpers/composite-patterns.js +28 -0
  6. package/dist/helpers/live-coding.js +4 -0
  7. package/dist/helpers/subsystem.js +28 -1
  8. package/dist/helpers/tool-registration.d.ts +3 -2
  9. package/dist/helpers/tool-registration.js +6 -2
  10. package/dist/helpers/tool-results.js +5 -3
  11. package/dist/index.js +1 -1
  12. package/dist/project-controller.d.ts +9 -0
  13. package/dist/project-controller.js +19 -1
  14. package/dist/prompts/prompt-catalog.js +2 -2
  15. package/dist/register-server-tools.d.ts +2 -1
  16. package/dist/register-server-tools.js +14 -3
  17. package/dist/resources/static-doc-resources.js +2 -1
  18. package/dist/schemas/tool-inputs.d.ts +1125 -17
  19. package/dist/schemas/tool-inputs.js +19 -6
  20. package/dist/schemas/tool-results.d.ts +336 -0
  21. package/dist/schemas/tool-results.js +20 -0
  22. package/dist/server-config.d.ts +1 -1
  23. package/dist/server-config.js +34 -7
  24. package/dist/server-factory.d.ts +6 -1
  25. package/dist/server-factory.js +54 -2
  26. package/dist/tool-surface-manager.d.ts +28 -0
  27. package/dist/tool-surface-manager.js +234 -0
  28. package/dist/tools/blueprint-authoring.js +13 -1
  29. package/dist/tools/composite-tools.d.ts +10 -0
  30. package/dist/tools/composite-tools.js +207 -0
  31. package/dist/tools/extraction.d.ts +3 -1
  32. package/dist/tools/extraction.js +13 -33
  33. package/dist/tools/import-jobs.d.ts +6 -2
  34. package/dist/tools/import-jobs.js +92 -83
  35. package/dist/tools/material-authoring.d.ts +3 -1
  36. package/dist/tools/material-authoring.js +36 -73
  37. package/dist/tools/material-instance.js +8 -1
  38. package/dist/tools/project-control.js +47 -24
  39. package/dist/tools/schema-and-ai-authoring.d.ts +2 -2
  40. package/dist/tools/schema-and-ai-authoring.js +85 -49
  41. package/dist/tools/widget-extraction.js +2 -2
  42. package/dist/tools/widget-structure.js +392 -35
  43. package/dist/tools/widget-verification.js +11 -1
  44. package/dist/tools/window-ui.js +44 -11
  45. package/package.json +2 -2
@@ -482,4 +482,92 @@ export const exampleCatalog = {
482
482
  },
483
483
  ],
484
484
  },
485
+ state_tree_bindings: {
486
+ summary: 'Wire task outputs to task inputs using property path bindings. Extract an existing StateTree to discover structIds and property names, then use binding operations to set up data flow.',
487
+ recommended_flow: [
488
+ 'extract_asset (discover structIds and property names)',
489
+ 'modify_state_tree (add_binding / set_bindings)',
490
+ 'extract_asset (verify bindings)',
491
+ 'save_assets',
492
+ ],
493
+ examples: [
494
+ {
495
+ title: 'add_single_binding',
496
+ tool: 'modify_state_tree',
497
+ arguments: {
498
+ asset_path: '/Game/AI/ST_Character',
499
+ operation: 'add_binding',
500
+ payload: {
501
+ sourcePath: {
502
+ structId: 'EAB9611F4B07D7E2C25A948AFC790A50',
503
+ segments: [{ name: 'SelectedGestureTag' }],
504
+ },
505
+ targetPath: {
506
+ structId: 'F2A3B44C4D08E6A1C25A948AFC790A50',
507
+ segments: [{ name: 'MontageTag' }],
508
+ },
509
+ },
510
+ },
511
+ context: { description: 'Wire SelectRandomGesture output → PlayMontage input. structIds from extract_asset output.' },
512
+ },
513
+ {
514
+ title: 'set_all_bindings',
515
+ tool: 'modify_state_tree',
516
+ arguments: {
517
+ asset_path: '/Game/AI/ST_Character',
518
+ operation: 'set_bindings',
519
+ payload: {
520
+ propertyBindings: [
521
+ {
522
+ sourcePath: { segments: [{ name: 'SelectedTag' }] },
523
+ targetPath: { segments: [{ name: 'MontageTag' }] },
524
+ },
525
+ {
526
+ sourcePath: { segments: [{ name: 'Duration' }] },
527
+ targetPath: { segments: [{ name: 'WaitTime' }] },
528
+ },
529
+ ],
530
+ },
531
+ },
532
+ context: { description: 'Replace all bindings on the StateTree with a new set.' },
533
+ },
534
+ {
535
+ title: 'remove_binding_by_target',
536
+ tool: 'modify_state_tree',
537
+ arguments: {
538
+ asset_path: '/Game/AI/ST_Character',
539
+ operation: 'remove_binding',
540
+ payload: {
541
+ targetPath: { segments: [{ name: 'MontageTag' }] },
542
+ },
543
+ },
544
+ context: { description: 'Remove all bindings targeting the MontageTag property.' },
545
+ },
546
+ {
547
+ title: 'create_with_bindings',
548
+ tool: 'create_state_tree',
549
+ arguments: {
550
+ asset_path: '/Game/AI/ST_NewWithBindings',
551
+ payload: {
552
+ schema: '/Script/GameplayStateTreeModule.StateTreeComponentSchema',
553
+ states: [{
554
+ name: 'Root',
555
+ type: 'State',
556
+ tasks: [
557
+ { nodeStructType: '/Script/MyMod.STCSelectGesture', name: 'SelectGesture' },
558
+ { nodeStructType: '/Script/MyMod.STCPlayMontage', name: 'PlayMontage' },
559
+ ],
560
+ }],
561
+ bindings: {
562
+ propertyBindings: [{
563
+ sourcePath: { segments: [{ name: 'SelectedGestureTag' }] },
564
+ targetPath: { segments: [{ name: 'MontageTag' }] },
565
+ }],
566
+ },
567
+ },
568
+ },
569
+ context: { description: 'Create a StateTree with tasks and bindings in a single call.' },
570
+ },
571
+ ],
572
+ },
485
573
  };
@@ -0,0 +1,7 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ToolHelpEntry, ToolInputSchema } from './tool-help.js';
3
+ type RawToolHandler = (args: Record<string, unknown>, extra: unknown) => Promise<unknown> | unknown;
4
+ export declare const aliasMap: Map<string, string>;
5
+ export declare const rawHandlerRegistry: Map<string, RawToolHandler>;
6
+ export declare function registerAlias(server: McpServer, oldName: string, targetName: string, parameterMapping: (args: Record<string, unknown>) => Record<string, unknown>, deprecationMessage: string, toolHelpRegistry: Map<string, ToolHelpEntry>, aliasInputSchema?: ToolInputSchema): void;
7
+ export {};
@@ -0,0 +1,36 @@
1
+ // Global alias map: old name -> new name
2
+ export const aliasMap = new Map();
3
+ // Registry for raw (pre-normalization) handlers, keyed by tool name.
4
+ // Populated by installNormalizedToolRegistration and used by alias delegation.
5
+ export const rawHandlerRegistry = new Map();
6
+ export function registerAlias(server, oldName, targetName, parameterMapping, deprecationMessage, toolHelpRegistry, aliasInputSchema) {
7
+ const targetEntry = toolHelpRegistry.get(targetName);
8
+ if (!targetEntry) {
9
+ throw new Error(`Cannot register alias '${oldName}': target tool '${targetName}' not found in registry`);
10
+ }
11
+ const targetHandler = rawHandlerRegistry.get(targetName);
12
+ if (!targetHandler) {
13
+ throw new Error(`Cannot register alias '${oldName}': no raw handler found for target tool '${targetName}'`);
14
+ }
15
+ aliasMap.set(oldName, targetName);
16
+ const aliasDescription = `[DEPRECATED: use ${targetName}] ${targetEntry.description}`;
17
+ server.registerTool(oldName, {
18
+ title: `${targetEntry.title} (deprecated alias)`,
19
+ description: aliasDescription,
20
+ inputSchema: aliasInputSchema ?? targetEntry.inputSchema,
21
+ annotations: {
22
+ ...targetEntry.annotations,
23
+ },
24
+ }, async (args, extra) => {
25
+ const mappedArgs = parameterMapping(args);
26
+ return targetHandler(mappedArgs, extra);
27
+ });
28
+ toolHelpRegistry.set(oldName, {
29
+ ...targetEntry,
30
+ title: `${targetEntry.title} (deprecated alias)`,
31
+ description: `Alias for ${targetName}. ${deprecationMessage} ${targetEntry.description}`,
32
+ annotations: {
33
+ ...targetEntry.annotations,
34
+ },
35
+ });
36
+ }
@@ -0,0 +1,40 @@
1
+ export interface CompositeStepResult {
2
+ step: string;
3
+ status: 'success' | 'failure' | 'skipped';
4
+ message?: string;
5
+ data?: Record<string, unknown>;
6
+ diagnostics?: Array<{
7
+ severity?: string;
8
+ code?: string;
9
+ message?: string;
10
+ path?: string;
11
+ }>;
12
+ }
13
+ export interface CompositeToolResult {
14
+ success: boolean;
15
+ operation: string;
16
+ steps: CompositeStepResult[];
17
+ partial_state?: {
18
+ completed_steps: string[];
19
+ failed_step: string;
20
+ editor_state: string;
21
+ };
22
+ execution: {
23
+ mode: 'immediate' | 'task_aware';
24
+ task_support: 'optional' | 'required' | 'forbidden';
25
+ status?: string;
26
+ progress_message?: string;
27
+ };
28
+ }
29
+ type Result<T, E> = {
30
+ ok: true;
31
+ value: T;
32
+ } | {
33
+ ok: false;
34
+ error: E;
35
+ };
36
+ export declare function safeCall<T>(fn: () => Promise<T>): Promise<Result<T, Error>>;
37
+ export declare function compositeSuccess(operation: string, steps: CompositeStepResult[], execution: CompositeToolResult['execution']): CompositeToolResult;
38
+ export declare function compositeError(operation: string, steps: CompositeStepResult[], failedStep: string, execution: CompositeToolResult['execution']): CompositeToolResult;
39
+ export declare function compositePartialFailure(operation: string, steps: CompositeStepResult[], failedStep: string, partialState: CompositeToolResult['partial_state'], execution: CompositeToolResult['execution']): CompositeToolResult;
40
+ export {};
@@ -0,0 +1,28 @@
1
+ export async function safeCall(fn) {
2
+ try {
3
+ const value = await fn();
4
+ return { ok: true, value };
5
+ }
6
+ catch (e) {
7
+ return { ok: false, error: e instanceof Error ? e : new Error(String(e)) };
8
+ }
9
+ }
10
+ export function compositeSuccess(operation, steps, execution) {
11
+ return { success: true, operation, steps, execution };
12
+ }
13
+ export function compositeError(operation, steps, failedStep, execution) {
14
+ return {
15
+ success: false,
16
+ operation,
17
+ steps,
18
+ partial_state: {
19
+ completed_steps: steps.filter(s => s.status === 'success').map(s => s.step),
20
+ failed_step: failedStep,
21
+ editor_state: 'No mutations performed; editor state unchanged',
22
+ },
23
+ execution,
24
+ };
25
+ }
26
+ export function compositePartialFailure(operation, steps, failedStep, partialState, execution) {
27
+ return { success: false, operation, steps, partial_state: partialState, execution };
28
+ }
@@ -36,6 +36,10 @@ export function enrichLiveCodingResult(result, changedPaths = [], lastExternalBu
36
36
  warnings.push('Live Coding cannot add, remove, or reorder UPROPERTYs or change class layouts. '
37
37
  + 'Use compile_project_code + restart_editor for class layout changes.');
38
38
  }
39
+ if (result.noOp && typeof result.compileResult === 'string' && result.compileResult.toLowerCase() === 'nochanges') {
40
+ warnings.push('Live Coding cannot compile newly added source files — it only detects changes to already-compiled .obj files. '
41
+ + 'Use compile_project_code for new files, then restart_editor to load the new module.');
42
+ }
39
43
  const fallbackRecommended = canFallbackFromLiveCoding(result);
40
44
  const reason = deriveLiveCodingFallbackReason(result);
41
45
  return {
@@ -47,13 +47,40 @@ export async function callSubsystemJson(client, method, params, options) {
47
47
  }
48
48
  return parsed;
49
49
  }
50
+ /**
51
+ * Extracts the best available error message from a UE failure response,
52
+ * checking message, errorMessage, error, diagnostics[], and errors[] fields
53
+ * before falling back to listing the available response keys.
54
+ */
55
+ function extractFailureMessage(parsed) {
56
+ if (typeof parsed.message === 'string' && parsed.message.length > 0)
57
+ return parsed.message;
58
+ if (typeof parsed.errorMessage === 'string' && parsed.errorMessage.length > 0)
59
+ return parsed.errorMessage;
60
+ if (typeof parsed.error === 'string' && parsed.error.length > 0)
61
+ return parsed.error;
62
+ if (Array.isArray(parsed.diagnostics) && parsed.diagnostics.length > 0) {
63
+ const messages = parsed.diagnostics
64
+ .filter((d) => typeof d === 'object' && d !== null && typeof d.message === 'string')
65
+ .map((d) => d.message);
66
+ if (messages.length > 0)
67
+ return messages.join('; ');
68
+ }
69
+ if (Array.isArray(parsed.errors) && parsed.errors.length > 0) {
70
+ const first = parsed.errors[0];
71
+ return typeof first === 'string' ? first : JSON.stringify(first);
72
+ }
73
+ const keys = Object.keys(parsed).join(', ');
74
+ return `Operation returned success:false with no diagnostic details. Response keys: [${keys}]`;
75
+ }
50
76
  export function jsonToolSuccess(parsed, options = {}) {
51
77
  const structuredContent = isRecord(parsed) ? parsed : { data: parsed };
52
78
  // Guard: if the UE response indicates failure, route through error path.
53
79
  // This prevents tool handlers from accidentally passing error payloads as successes.
54
80
  if (isRecord(parsed) && parsed.success === false) {
81
+ const errorText = extractFailureMessage(parsed);
55
82
  return {
56
- content: [{ type: 'text', text: `Error: ${typeof parsed.message === 'string' ? parsed.message : 'Operation failed'}` }],
83
+ content: [{ type: 'text', text: `Error: ${errorText}` }],
57
84
  structuredContent,
58
85
  isError: true,
59
86
  };
@@ -1,13 +1,14 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1
+ import { McpServer, type RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { z } from 'zod';
3
3
  import type { ToolHelpEntry } from './tool-help.js';
4
4
  type ToolNormalizer = (...args: any[]) => unknown;
5
5
  type InstallNormalizedToolRegistrationOptions = {
6
6
  server: McpServer;
7
7
  toolHelpRegistry: Map<string, ToolHelpEntry>;
8
+ registeredToolMap: Map<string, RegisteredTool>;
8
9
  defaultOutputSchema: z.ZodTypeAny;
9
10
  normalizeToolError: ToolNormalizer;
10
11
  normalizeToolSuccess: ToolNormalizer;
11
12
  };
12
- export declare function installNormalizedToolRegistration({ server, toolHelpRegistry, defaultOutputSchema, normalizeToolError, normalizeToolSuccess, }: InstallNormalizedToolRegistrationOptions): void;
13
+ export declare function installNormalizedToolRegistration({ server, toolHelpRegistry, registeredToolMap, defaultOutputSchema, normalizeToolError, normalizeToolSuccess, }: InstallNormalizedToolRegistrationOptions): void;
13
14
  export {};
@@ -1,8 +1,10 @@
1
1
  import { extractExtraContent, extractToolPayload, isRecord } from './formatting.js';
2
- export function installNormalizedToolRegistration({ server, toolHelpRegistry, defaultOutputSchema, normalizeToolError, normalizeToolSuccess, }) {
2
+ import { rawHandlerRegistry } from './alias-registration.js';
3
+ export function installNormalizedToolRegistration({ server, toolHelpRegistry, registeredToolMap, defaultOutputSchema, normalizeToolError, normalizeToolSuccess, }) {
3
4
  const rawRegisterTool = server.registerTool.bind(server);
4
5
  server.registerTool = ((name, config, cb) => {
5
6
  const outputSchema = (config.outputSchema ?? defaultOutputSchema);
7
+ rawHandlerRegistry.set(name, cb);
6
8
  toolHelpRegistry.set(name, {
7
9
  title: config.title ?? name,
8
10
  description: config.description ?? '',
@@ -10,7 +12,7 @@ export function installNormalizedToolRegistration({ server, toolHelpRegistry, de
10
12
  outputSchema,
11
13
  annotations: config.annotations,
12
14
  });
13
- return rawRegisterTool(name, {
15
+ const registered = rawRegisterTool(name, {
14
16
  ...config,
15
17
  outputSchema,
16
18
  }, async (args, extra) => {
@@ -25,5 +27,7 @@ export function installNormalizedToolRegistration({ server, toolHelpRegistry, de
25
27
  return normalizeToolError(name, error);
26
28
  }
27
29
  });
30
+ registeredToolMap.set(name, registered);
31
+ return registered;
28
32
  });
29
33
  }
@@ -1,3 +1,4 @@
1
+ import { aliasMap } from './alias-registration.js';
1
2
  import { isRecord } from './formatting.js';
2
3
  export function createToolResultNormalizers({ taskAwareTools, classifyRecoverableToolFailure, }) {
3
4
  function extractNonTextContent(existingResult) {
@@ -9,20 +10,21 @@ export function createToolResultNormalizers({ taskAwareTools, classifyRecoverabl
9
10
  && entry.type !== 'text'));
10
11
  }
11
12
  function defaultNextSteps(toolName, payload) {
12
- if (toolName === 'wait_for_editor') {
13
+ const resolvedName = aliasMap.get(toolName) ?? toolName;
14
+ if (resolvedName === 'wait_for_editor') {
13
15
  return [
14
16
  'Retry wait_for_editor if the editor is still restarting.',
15
17
  'Once connected=true, rerun the blocked editor-backed tool.',
16
18
  ];
17
19
  }
18
- if (toolName === 'compile_widget_blueprint') {
20
+ if (resolvedName === 'compile_widget_blueprint') {
19
21
  return [
20
22
  'Inspect compile.messages and diagnostics for the first failing widget or property.',
21
23
  'Re-extract the widget blueprint before applying the next structural patch.',
22
24
  'Check BindWidget names/types and any abstract classes referenced by the widget tree.',
23
25
  ];
24
26
  }
25
- if (taskAwareTools.has(toolName)) {
27
+ if (taskAwareTools.has(resolvedName)) {
26
28
  return [
27
29
  'Inspect the returned execution.status and diagnostics before retrying.',
28
30
  'Poll the task-oriented status tool again if the operation is still running.',
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ export { createBlueprintExtractorServer } from './server-factory.js';
6
6
  export { exampleCatalog } from './catalogs/example-catalog.js';
7
7
  export { promptCatalog } from './prompts/prompt-catalog.js';
8
8
  async function main() {
9
- const server = createBlueprintExtractorServer();
9
+ const { server } = createBlueprintExtractorServer();
10
10
  const transport = new StdioServerTransport();
11
11
  await server.connect(transport);
12
12
  }
@@ -51,6 +51,7 @@ export interface CompileProjectCodeResult {
51
51
  stdout?: string;
52
52
  stderr?: string;
53
53
  uhtCacheFilesDeleted?: string[];
54
+ compilationSucceeded: boolean;
54
55
  errorCategory?: BuildErrorCategory;
55
56
  errorSummary?: string;
56
57
  lockedFiles?: string[];
@@ -104,6 +105,10 @@ export interface ProjectControllerLike {
104
105
  readonly liveCodingSupported: boolean;
105
106
  classifyChangedPaths(changedPaths: string[], forceRebuild?: boolean): SyncStrategyPlan;
106
107
  compileProjectCode(request: CompileProjectCodeRequest): Promise<CompileProjectCodeResult>;
108
+ killEditorProcess(): Promise<{
109
+ killed: boolean;
110
+ error?: string;
111
+ }>;
107
112
  launchEditor(request: LaunchEditorRequest): Promise<LaunchEditorResult>;
108
113
  waitForEditorRestart(probeConnection: ProbeConnection, options?: {
109
114
  disconnectTimeoutMs?: number;
@@ -131,6 +136,10 @@ export declare class ProjectController implements ProjectControllerLike {
131
136
  get liveCodingSupported(): boolean;
132
137
  classifyChangedPaths(changedPaths: string[], forceRebuild?: boolean): SyncStrategyPlan;
133
138
  compileProjectCode(request: CompileProjectCodeRequest): Promise<CompileProjectCodeResult>;
139
+ killEditorProcess(): Promise<{
140
+ killed: boolean;
141
+ error?: string;
142
+ }>;
134
143
  launchEditor(request: LaunchEditorRequest): Promise<LaunchEditorResult>;
135
144
  waitForEditorRestart(probeConnection: ProbeConnection, options?: {
136
145
  disconnectTimeoutMs?: number;
@@ -1,4 +1,4 @@
1
- import { spawn } from 'node:child_process';
1
+ import { execSync, spawn } from 'node:child_process';
2
2
  import { access, readdir, unlink } from 'node:fs/promises';
3
3
  import { constants as fsConstants } from 'node:fs';
4
4
  import { dirname, resolve } from 'node:path';
@@ -358,6 +358,7 @@ export class ProjectController {
358
358
  },
359
359
  durationMs: Date.now() - startedAt,
360
360
  exitCode: completed.exitCode,
361
+ compilationSucceeded: completed.exitCode === 0,
361
362
  restartRequired: true,
362
363
  restartReasons: ['external_build_completed'],
363
364
  outputIncluded: includeOutput,
@@ -380,9 +381,26 @@ export class ProjectController {
380
381
  if (classification.lockedFiles.length > 0) {
381
382
  result.lockedFiles = classification.lockedFiles;
382
383
  }
384
+ // Compilation itself succeeded if the failure is only at the link/lock stage
385
+ result.compilationSucceeded = classification.errorCategory === 'locked_file'
386
+ || classification.errorCategory === 'link';
383
387
  }
384
388
  return result;
385
389
  }
390
+ async killEditorProcess() {
391
+ try {
392
+ if (this.platform === 'win32') {
393
+ execSync('taskkill /F /IM "UnrealEditor.exe"', { timeout: 10000 });
394
+ }
395
+ else {
396
+ execSync('pkill -9 -f UnrealEditor', { timeout: 10000 });
397
+ }
398
+ return { killed: true };
399
+ }
400
+ catch (err) {
401
+ return { killed: false, error: String(err) };
402
+ }
403
+ }
386
404
  async launchEditor(request) {
387
405
  const engineRoot = request.engineRoot ?? this.env.UE_ENGINE_ROOT;
388
406
  const projectPath = request.projectPath ?? this.env.UE_PROJECT_PATH;
@@ -218,7 +218,7 @@ export const promptCatalog = {
218
218
  `Author widget motion for ${widget_asset_path} using animation '${animation_name}'.`,
219
219
  formatPromptBlock('design_spec_json', design_spec_json, 'A design_spec_json with motion data is required.'),
220
220
  formatPromptList('Compare reference paths', compare_reference_paths, 'No compare reference paths were supplied. Use checkpoint frames from the design spec if they exist.'),
221
- 'Use create_widget_animation or modify_widget_animation instead of overloading modify_widget_blueprint.',
221
+ 'Use create_widget_animation or modify_widget_animation instead of overloading widget tools. Use patch_widget for property changes and replace_widget_tree for full tree replacement.',
222
222
  'Supported track subset: render_opacity, render_transform_translation, render_transform_scale, render_transform_angle, color_and_opacity.',
223
223
  'Prefer widget_path selectors for bindings and tracks. Accept widget_name only as a compatibility fallback when unique.',
224
224
  'Use replace_timeline as the canonical write path. patch_metadata is only for display labels, checkpoints, playback metadata, and other non-track updates.',
@@ -263,7 +263,7 @@ export const promptCatalog = {
263
263
  `Target widget class: ${widget_class_path}.`,
264
264
  `Class default property: ${class_default_property}.`,
265
265
  'Inspect the current Blueprint members and class defaults first.',
266
- 'Return the smallest set of modify_blueprint_members or modify_widget_blueprint.patch_class_defaults calls needed to complete the wiring.',
266
+ 'Return the smallest set of modify_blueprint_members or patch_widget_class_defaults calls needed to complete the wiring.',
267
267
  ].join('\n'),
268
268
  },
269
269
  debug_widget_compile_errors: {
@@ -26,7 +26,8 @@ type RegisterServerToolsOptions = {
26
26
  getLastExternalBuildContext: () => Record<string, unknown> | null;
27
27
  clearProjectAutomationContext: () => void;
28
28
  getToolHelpEntry: (toolName: string) => ToolHelpEntry | undefined;
29
+ toolHelpRegistry: Map<string, ToolHelpEntry>;
29
30
  editorPollIntervalMs: number;
30
31
  };
31
- export declare function registerServerTools({ server, client, projectController, automationController, callSubsystemJson, resolveProjectInputs, getProjectAutomationContext, rememberExternalBuild, getLastExternalBuildContext, clearProjectAutomationContext, getToolHelpEntry, editorPollIntervalMs, }: RegisterServerToolsOptions): void;
32
+ export declare function registerServerTools({ server, client, projectController, automationController, callSubsystemJson, resolveProjectInputs, getProjectAutomationContext, rememberExternalBuild, getLastExternalBuildContext, clearProjectAutomationContext, getToolHelpEntry, toolHelpRegistry, editorPollIntervalMs, }: RegisterServerToolsOptions): void;
32
33
  export {};
@@ -1,11 +1,12 @@
1
1
  import { z } from 'zod';
2
2
  import { exampleCatalog } from './catalogs/example-catalog.js';
3
3
  import { collectRelatedResources, collectToolExampleFamilies as collectToolExampleFamiliesFromCatalog, summarizeOutputSchema, summarizeSchemaFields, } from './helpers/tool-help.js';
4
- import { AnimMontageMutationOperationSchema, AnimationNotifySelectorSchema, AnimSequenceMutationOperationSchema, BehaviorTreeMutationOperationSchema, BehaviorTreeNodeSelectorSchema, BlackboardKeySchema, BlackboardMutationOperationSchema, BlendParameterSchema, BlendSpaceMutationOperationSchema, BlendSpaceSampleSchema, BlueprintGraphMutationOperationSchema, BlueprintMemberMutationOperationSchema, BuildConfigurationSchema, BuildPlatformSchema, CurveChannelSchema, CurveKeyDeleteSchema, CurveKeyUpsertSchema, CurveTableModeSchema, CurveTableRowSchema, CurveTypeSchema, DataTableRowSchema, ExtractAssetTypeSchema, EnhancedInputValueTypeSchema, FontImportItemSchema, ImportJobListSchema, ImportJobSchema, ImportPayloadSchema, InputMappingSchema, JsonObjectSchema, MaterialConnectionSelectorFieldsSchema, MaterialFontParameterSchema, MaterialFunctionAssetKindSchema, MaterialGraphOperationKindSchema, MaterialGraphOperationSchema, MaterialGraphPayloadSchema, MaterialLayerStackSchema, MaterialNodePositionSchema, MaterialScalarParameterSchema, MaterialStaticSwitchParameterSchema, MaterialTextureParameterSchema, MaterialVectorParameterSchema, MeshImportPayloadSchema, StateTreeEditorNodeSelectorSchema, StateTreeMutationOperationSchema, StateTreeStateSelectorSchema, StateTreeTransitionSelectorSchema, StateTreeBindingSchema, TextureImportPayloadSchema, UserDefinedEnumEntrySchema, UserDefinedEnumMutationOperationSchema, UserDefinedStructFieldSchema, UserDefinedStructMutationOperationSchema, WidgetBlueprintMutationOperationSchema, WidgetNodeSchema, WidgetSelectorFieldsSchema, WindowFontApplicationSchema, } from './schemas/tool-inputs.js';
4
+ import { AnimMontageMutationOperationSchema, AnimationNotifySelectorSchema, AnimSequenceMutationOperationSchema, BehaviorTreeMutationOperationSchema, BehaviorTreeNodeSelectorSchema, BlackboardKeySchema, BlackboardMutationOperationSchema, BlendParameterSchema, BlendSpaceMutationOperationSchema, BlendSpaceSampleSchema, BlueprintGraphMutationOperationSchema, BlueprintMemberMutationOperationSchema, BuildConfigurationSchema, BuildPlatformSchema, CurveChannelSchema, CurveKeyDeleteSchema, CurveKeyUpsertSchema, CurveTableModeSchema, CurveTableRowSchema, CurveTypeSchema, DataTableRowSchema, ExtractAssetTypeSchema, EnhancedInputValueTypeSchema, FontImportItemSchema, ImportJobListSchema, ImportJobSchema, ImportPayloadSchema, InputMappingSchema, JsonObjectSchema, MaterialConnectionSelectorFieldsSchema, MaterialFontParameterSchema, MaterialFunctionAssetKindSchema, MaterialGraphOperationKindSchema, MaterialGraphOperationSchema, MaterialGraphPayloadSchema, MaterialLayerStackSchema, MaterialNodePositionSchema, MaterialScalarParameterSchema, MaterialStaticSwitchParameterSchema, MaterialTextureParameterSchema, MaterialVectorParameterSchema, MeshImportOptionsSchema, MeshImportPayloadSchema, StateTreeEditorNodeSelectorSchema, StateTreeMutationOperationSchema, StateTreeStateSelectorSchema, StateTreeTransitionSelectorSchema, StateTreeBindingsObjectSchema, TextureImportOptionsSchema, TextureImportPayloadSchema, UserDefinedEnumEntrySchema, UserDefinedEnumMutationOperationSchema, UserDefinedStructFieldSchema, UserDefinedStructMutationOperationSchema, WidgetBlueprintMutationOperationSchema, WidgetNodeSchema, WidgetSelectorFieldsSchema, WindowFontApplicationSchema, } from './schemas/tool-inputs.js';
5
5
  import { applyWindowUiChangesResultSchema, AutomationRunListSchema, automationRunSchema, CaptureResultSchema, CascadeResultSchema, CleanupCapturesResultSchema, CompareCaptureResultSchema, CompareMotionCaptureBundleResultSchema, CreateModifyWidgetAnimationResultSchema, ExtractWidgetAnimationResultSchema, ListCapturesResultSchema, motionCaptureModeSchema, MotionCaptureBundleResultSchema, widgetAnimationCheckpointSchema, } from './schemas/tool-results.js';
6
6
  import { registerAnimationAuthoringTools } from './tools/animation-authoring.js';
7
7
  import { registerAutomationRunTools } from './tools/automation-runs.js';
8
8
  import { registerBlueprintAuthoringTools } from './tools/blueprint-authoring.js';
9
+ import { registerCompositeTools } from './tools/composite-tools.js';
9
10
  import { registerCommonUIButtonStyleTools } from './tools/commonui-button-style.js';
10
11
  import { registerDataAndInputTools } from './tools/data-and-input.js';
11
12
  import { registerExtractionTools } from './tools/extraction.js';
@@ -29,7 +30,7 @@ const scopeEnum = z.enum([
29
30
  'Full',
30
31
  'FullWithBytecode',
31
32
  ]);
32
- export function registerServerTools({ server, client, projectController, automationController, callSubsystemJson, resolveProjectInputs, getProjectAutomationContext, rememberExternalBuild, getLastExternalBuildContext, clearProjectAutomationContext, getToolHelpEntry, editorPollIntervalMs, }) {
33
+ export function registerServerTools({ server, client, projectController, automationController, callSubsystemJson, resolveProjectInputs, getProjectAutomationContext, rememberExternalBuild, getLastExternalBuildContext, clearProjectAutomationContext, getToolHelpEntry, toolHelpRegistry, editorPollIntervalMs, }) {
33
34
  const collectToolExampleFamilies = (toolName) => (collectToolExampleFamiliesFromCatalog(exampleCatalog, toolName));
34
35
  registerExtractionTools({
35
36
  server,
@@ -37,6 +38,7 @@ export function registerServerTools({ server, client, projectController, automat
37
38
  scopeEnum,
38
39
  extractAssetTypeSchema: ExtractAssetTypeSchema,
39
40
  cascadeResultSchema: CascadeResultSchema,
41
+ toolHelpRegistry,
40
42
  });
41
43
  registerWidgetStructureTools({
42
44
  server,
@@ -112,6 +114,7 @@ export function registerServerTools({ server, client, projectController, automat
112
114
  materialGraphOperationKindSchema: MaterialGraphOperationKindSchema,
113
115
  materialGraphOperationSchema: MaterialGraphOperationSchema,
114
116
  materialFunctionAssetKindSchema: MaterialFunctionAssetKindSchema,
117
+ toolHelpRegistry,
115
118
  });
116
119
  registerAutomationRunTools({
117
120
  server,
@@ -166,7 +169,7 @@ export function registerServerTools({ server, client, projectController, automat
166
169
  stateTreeStateSelectorSchema: StateTreeStateSelectorSchema,
167
170
  stateTreeEditorNodeSelectorSchema: StateTreeEditorNodeSelectorSchema,
168
171
  stateTreeTransitionSelectorSchema: StateTreeTransitionSelectorSchema,
169
- stateTreeBindingSchema: StateTreeBindingSchema,
172
+ stateTreeBindingsObjectSchema: StateTreeBindingsObjectSchema,
170
173
  });
171
174
  registerAnimationAuthoringTools({
172
175
  server,
@@ -194,6 +197,14 @@ export function registerServerTools({ server, client, projectController, automat
194
197
  importJobListSchema: ImportJobListSchema,
195
198
  textureImportPayloadSchema: TextureImportPayloadSchema,
196
199
  meshImportPayloadSchema: MeshImportPayloadSchema,
200
+ textureImportOptionsSchema: TextureImportOptionsSchema,
201
+ meshImportOptionsSchema: MeshImportOptionsSchema,
202
+ toolHelpRegistry,
203
+ });
204
+ registerCompositeTools({
205
+ server,
206
+ callSubsystemJson,
207
+ toolHelpRegistry,
197
208
  });
198
209
  registerUtilityTools({
199
210
  server,
@@ -64,7 +64,8 @@ export function registerStaticDocResources(server) {
64
64
  '- UserDefinedEnum: entry selector by name; operations replace_entries, rename_entry, remove_entry, reorder_entries.',
65
65
  '- Blackboard: key selector by entryName; operations replace_keys, patch_key, remove_key, set_parent.',
66
66
  '- BehaviorTree: node selector by nodePath; operations replace_tree, patch_node, patch_attachment, set_blackboard.',
67
- '- StateTree: selectors by stateId/statePath, editorNodeId, or transitionId; operations replace_tree, patch_state, patch_editor_node, patch_transition, set_schema.',
67
+ '- StateTree: selectors by stateId/statePath, editorNodeId, or transitionId; operations replace_tree, patch_state, patch_editor_node, patch_transition, set_schema, set_bindings, add_binding, remove_binding. Blueprint-wrapped nodes (StateTreeBlueprintTaskWrapper / StateTreeBlueprintConditionWrapper) require instanceObjectClass for the backing instance to exist at runtime.',
68
+ '- StateTree property bindings wire task/evaluator outputs to task inputs. Use extract_asset to discover structIds and property names. Each binding has sourcePath and targetPath with segments: [{name, arrayIndex?, instanceStruct?}] and optional structId. Operations: set_bindings (replace all), add_binding (append), remove_binding (by targetPath). In replace_tree/create: include as { bindings: { propertyBindings: [...] } }.',
68
69
  '- AnimSequence: notify selector by notifyId/notifyGuid with notifyIndex or track metadata as fallback; operations replace_notifies, patch_notify, replace_sync_markers, replace_curve_metadata.',
69
70
  '- AnimMontage: notify selector by notifyId/notifyGuid with notifyIndex or track metadata as fallback; operations replace_notifies, patch_notify, replace_sections, replace_slots.',
70
71
  '- BlendSpace: sample selector by sampleIndex; operations replace_samples, patch_sample, set_axes.',