blueprint-extractor-mcp 7.0.8 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -7
- package/dist/active-editor-session.d.ts +0 -0
- package/dist/active-editor-session.js +0 -0
- package/dist/automation-controller.d.ts +0 -0
- package/dist/automation-controller.js +0 -0
- package/dist/catalogs/example-catalog.d.ts +0 -0
- package/dist/catalogs/example-catalog.js +0 -0
- package/dist/compactor.d.ts +0 -0
- package/dist/compactor.js +0 -0
- package/dist/editor-instance-registry.d.ts +0 -0
- package/dist/editor-instance-registry.js +0 -0
- package/dist/editor-instance-types.d.ts +0 -0
- package/dist/editor-instance-types.js +0 -0
- package/dist/execution/adapters/commandlet-adapter.d.ts +0 -0
- package/dist/execution/adapters/commandlet-adapter.js +0 -0
- package/dist/execution/adapters/editor-adapter.d.ts +0 -0
- package/dist/execution/adapters/editor-adapter.js +0 -0
- package/dist/execution/adapters/lazy-commandlet-adapter.d.ts +0 -0
- package/dist/execution/adapters/lazy-commandlet-adapter.js +0 -0
- package/dist/execution/adaptive-executor.d.ts +0 -0
- package/dist/execution/adaptive-executor.js +49 -1
- package/dist/execution/execution-adapter.d.ts +0 -0
- package/dist/execution/execution-adapter.js +0 -0
- package/dist/execution/execution-mode-detector.d.ts +0 -0
- package/dist/execution/execution-mode-detector.js +0 -0
- package/dist/execution/index.d.ts +0 -0
- package/dist/execution/index.js +0 -0
- package/dist/helpers/active-editor-utils.d.ts +0 -0
- package/dist/helpers/active-editor-utils.js +0 -0
- package/dist/helpers/alias-registration.d.ts +0 -0
- package/dist/helpers/alias-registration.js +0 -0
- package/dist/helpers/blueprint-dsl-parser.d.ts +0 -0
- package/dist/helpers/blueprint-dsl-parser.js +0 -0
- package/dist/helpers/blueprint-validation.d.ts +0 -0
- package/dist/helpers/blueprint-validation.js +0 -0
- package/dist/helpers/capture.d.ts +0 -0
- package/dist/helpers/capture.js +0 -0
- package/dist/helpers/commonui-button-style.d.ts +0 -0
- package/dist/helpers/commonui-button-style.js +0 -0
- package/dist/helpers/composite-patterns.d.ts +0 -0
- package/dist/helpers/composite-patterns.js +0 -0
- package/dist/helpers/formatting.d.ts +0 -0
- package/dist/helpers/formatting.js +0 -0
- package/dist/helpers/live-coding.d.ts +0 -0
- package/dist/helpers/live-coding.js +0 -0
- package/dist/helpers/material-dsl-parser.d.ts +0 -0
- package/dist/helpers/material-dsl-parser.js +0 -0
- package/dist/helpers/mutation-filter.d.ts +0 -0
- package/dist/helpers/mutation-filter.js +0 -0
- package/dist/helpers/next-step-hints.d.ts +0 -0
- package/dist/helpers/next-step-hints.js +7 -45
- package/dist/helpers/operation-deny-list.d.ts +0 -0
- package/dist/helpers/operation-deny-list.js +0 -0
- package/dist/helpers/package-metadata.d.ts +0 -0
- package/dist/helpers/package-metadata.js +0 -0
- package/dist/helpers/phantom-filter.d.ts +0 -0
- package/dist/helpers/phantom-filter.js +0 -0
- package/dist/helpers/project-resolution.d.ts +0 -0
- package/dist/helpers/project-resolution.js +40 -17
- package/dist/helpers/project-utils.d.ts +0 -0
- package/dist/helpers/project-utils.js +0 -0
- package/dist/helpers/property-path-parser.d.ts +0 -0
- package/dist/helpers/property-path-parser.js +0 -0
- package/dist/helpers/property-shorthand.d.ts +0 -0
- package/dist/helpers/property-shorthand.js +0 -0
- package/dist/helpers/response-summarizer.d.ts +0 -0
- package/dist/helpers/response-summarizer.js +0 -0
- package/dist/helpers/slot-presets.d.ts +0 -0
- package/dist/helpers/slot-presets.js +0 -0
- package/dist/helpers/subsystem.d.ts +0 -0
- package/dist/helpers/subsystem.js +0 -0
- package/dist/helpers/token-budget.d.ts +0 -0
- package/dist/helpers/token-budget.js +0 -0
- package/dist/helpers/tool-help.d.ts +0 -0
- package/dist/helpers/tool-help.js +4 -18
- package/dist/helpers/tool-registration.d.ts +0 -0
- package/dist/helpers/tool-registration.js +0 -0
- package/dist/helpers/tool-results.d.ts +0 -0
- package/dist/helpers/tool-results.js +0 -0
- package/dist/helpers/verification.d.ts +0 -0
- package/dist/helpers/verification.js +0 -0
- package/dist/helpers/widget-class-aliases.d.ts +0 -0
- package/dist/helpers/widget-class-aliases.js +0 -0
- package/dist/helpers/widget-diff-parser.d.ts +0 -0
- package/dist/helpers/widget-diff-parser.js +0 -0
- package/dist/helpers/widget-dsl-parser.d.ts +0 -0
- package/dist/helpers/widget-dsl-parser.js +0 -0
- package/dist/helpers/widget-recipe-formatter.d.ts +0 -0
- package/dist/helpers/widget-recipe-formatter.js +0 -0
- package/dist/helpers/widget-recipe-parser.d.ts +0 -0
- package/dist/helpers/widget-recipe-parser.js +0 -0
- package/dist/helpers/widget-utils.d.ts +0 -0
- package/dist/helpers/widget-utils.js +0 -0
- package/dist/helpers/workspace-project.d.ts +4 -0
- package/dist/helpers/workspace-project.js +33 -1
- package/dist/index.d.ts +0 -0
- package/dist/index.js +0 -0
- package/dist/project-controller.d.ts +4 -2
- package/dist/project-controller.js +62 -29
- package/dist/prompts/prompt-catalog.d.ts +0 -0
- package/dist/prompts/prompt-catalog.js +0 -0
- package/dist/register-server-resources.d.ts +0 -0
- package/dist/register-server-resources.js +0 -0
- package/dist/register-server-tools.d.ts +0 -0
- package/dist/register-server-tools.js +1 -2
- package/dist/resources/example-and-capture-resources.d.ts +0 -0
- package/dist/resources/example-and-capture-resources.js +0 -0
- package/dist/resources/static-doc-resources.d.ts +0 -0
- package/dist/resources/static-doc-resources.js +10 -5
- package/dist/schemas/tool-inputs.d.ts +24 -25
- package/dist/schemas/tool-inputs.js +1 -13
- package/dist/schemas/tool-results.d.ts +623 -2
- package/dist/schemas/tool-results.js +69 -0
- package/dist/server-config.d.ts +0 -0
- package/dist/server-config.js +13 -11
- package/dist/server-factory.d.ts +0 -0
- package/dist/server-factory.js +38 -3
- package/dist/tool-context.d.ts +0 -0
- package/dist/tool-context.js +0 -0
- package/dist/tool-surface-manager.d.ts +5 -1
- package/dist/tool-surface-manager.js +42 -22
- package/dist/tools/analysis-tools.d.ts +0 -0
- package/dist/tools/analysis-tools.js +0 -0
- package/dist/tools/animation-authoring.d.ts +0 -0
- package/dist/tools/animation-authoring.js +0 -0
- package/dist/tools/automation-runs.d.ts +0 -0
- package/dist/tools/automation-runs.js +0 -0
- package/dist/tools/blueprint-authoring.d.ts +0 -0
- package/dist/tools/blueprint-authoring.js +0 -0
- package/dist/tools/commonui-button-style.d.ts +0 -0
- package/dist/tools/commonui-button-style.js +0 -0
- package/dist/tools/composite-tools.d.ts +0 -0
- package/dist/tools/composite-tools.js +0 -0
- package/dist/tools/composite-workflows.d.ts +0 -0
- package/dist/tools/composite-workflows.js +0 -0
- package/dist/tools/data-and-input.d.ts +0 -0
- package/dist/tools/data-and-input.js +0 -0
- package/dist/tools/extraction.d.ts +0 -0
- package/dist/tools/extraction.js +0 -0
- package/dist/tools/import-jobs.d.ts +0 -0
- package/dist/tools/import-jobs.js +0 -0
- package/dist/tools/material-authoring.d.ts +0 -0
- package/dist/tools/material-authoring.js +0 -0
- package/dist/tools/material-instance.d.ts +0 -0
- package/dist/tools/material-instance.js +0 -0
- package/dist/tools/project-control.d.ts +0 -0
- package/dist/tools/project-control.js +112 -1
- package/dist/tools/project-intelligence.d.ts +0 -0
- package/dist/tools/project-intelligence.js +2 -1
- package/dist/tools/recipe-tools.d.ts +0 -0
- package/dist/tools/recipe-tools.js +0 -0
- package/dist/tools/schema-and-ai-authoring.d.ts +0 -0
- package/dist/tools/schema-and-ai-authoring.js +0 -0
- package/dist/tools/tables-and-curves.d.ts +0 -0
- package/dist/tools/tables-and-curves.js +0 -0
- package/dist/tools/utility-tools.d.ts +0 -0
- package/dist/tools/utility-tools.js +0 -0
- package/dist/tools/widget-animation-authoring.d.ts +0 -0
- package/dist/tools/widget-animation-authoring.js +0 -0
- package/dist/tools/widget-extraction.d.ts +0 -0
- package/dist/tools/widget-extraction.js +0 -0
- package/dist/tools/widget-structure.d.ts +1 -2
- package/dist/tools/widget-structure.js +23 -267
- package/dist/tools/widget-verification.d.ts +0 -0
- package/dist/tools/widget-verification.js +0 -0
- package/dist/tools/window-ui.d.ts +0 -0
- package/dist/tools/window-ui.js +3 -3
- package/dist/types.d.ts +0 -0
- package/dist/types.js +0 -0
- package/dist/ue-client.d.ts +0 -0
- package/dist/ue-client.js +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Blueprint Extractor MCP is a [Model Context Protocol](https://modelcontextprotoc
|
|
|
23
23
|
AI Assistant stdio MCP Server HTTP :30010 Unreal Editor
|
|
24
24
|
───────────── ◄────────────► ───────────────── ◄──────────────────► ─────────────────
|
|
25
25
|
Claude Code Node.js process Remote Control API
|
|
26
|
-
Codex / OpenCode
|
|
26
|
+
Codex / OpenCode 112 tools BlueprintExtractor
|
|
27
27
|
... 38 resources plugin
|
|
28
28
|
4 resource templates
|
|
29
29
|
12 prompts
|
|
@@ -112,22 +112,23 @@ codex mcp add --env UE_REMOTE_CONTROL_PORT=30010 \
|
|
|
112
112
|
|
|
113
113
|
## Tool Surface
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
Use `activate_tool_profile` to switch between the compact `default` surface and the full `expert` surface. The default profile keeps the context window lean and loads specialized families on demand via `activate_workflow_scope`.
|
|
116
116
|
|
|
117
117
|
| Scope | What It Unlocks |
|
|
118
118
|
|:------|:----------------|
|
|
119
|
-
| **Core** *(always on)* | Search, extraction, list/save/help,
|
|
119
|
+
| **Core** *(always on in `default` profile)* | Search, extraction, `find_and_extract`, list/save/help, and the profile/scope switches such as `extract_asset`, `search_assets`, `save_assets`, `get_tool_help`, `activate_tool_profile`, and `activate_workflow_scope` |
|
|
120
120
|
| `widget_authoring` | Parent scope that loads `widget_authoring_structure`, `widget_authoring_visual`, and `widget_verification` together |
|
|
121
|
-
| `widget_authoring_structure` |
|
|
121
|
+
| `widget_authoring_structure` | Recipe-first widget authoring, tree replacement, unified-diff patching, and focused structure edits without the deprecated widget aliases |
|
|
122
122
|
| `widget_authoring_visual` | Widget compile flows, CommonUI styles, widget animations, and widget preview capture |
|
|
123
123
|
| `widget_verification` | Widget capture, checkpoint bundles, capture listing, cleanup, and reference comparison |
|
|
124
|
-
| `material_authoring` |
|
|
125
|
-
| `blueprint_authoring` |
|
|
124
|
+
| `material_authoring` | `create_material_setup`, `modify_material`, `material_graph_operation`, compile, and material-instance edits |
|
|
125
|
+
| `blueprint_authoring` | `scaffold_blueprint`, graph/member edits, Blueprint creation, and Live Coding trigger |
|
|
126
126
|
| `schema_ai_authoring` | Structs, enums, Blackboards, Behavior Trees, and State Trees |
|
|
127
127
|
| `animation_authoring` | Anim sequences, montages, blend spaces, and widget motion authoring |
|
|
128
128
|
| `data_tables` | Data assets, data tables, curves, Input Actions, and Input Mapping Contexts |
|
|
129
129
|
| `import` | Async asset import and import-job polling |
|
|
130
|
-
| `
|
|
130
|
+
| `project_control` | Editor-session binding, launch/wait, project automation context, Output Log and Message Log inspection, PIE lifecycle control, host build/restart/sync, and `apply_window_ui_changes` |
|
|
131
|
+
| `automation_testing` | Host-side automation runs and automation-run polling |
|
|
131
132
|
| `analysis` | Deterministic Blueprint review and low-noise project asset audits |
|
|
132
133
|
| `project_intelligence` | Bounded editor context, project indexing, freshness status, and snippet-first context search |
|
|
133
134
|
| `verification` | Editor/runtime screenshots, capture comparison, motion verification, and artifact inspection |
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/compactor.d.ts
CHANGED
|
File without changes
|
package/dist/compactor.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
* AdaptiveExecutor routes tool calls to the best available adapter.
|
|
3
3
|
* Falls back from editor to commandlet for compatible operations.
|
|
4
4
|
*/
|
|
5
|
+
const EDITOR_FALLBACK_ERROR_FRAGMENTS = [
|
|
6
|
+
'UE Editor not running or Remote Control not available',
|
|
7
|
+
'BlueprintExtractor subsystem not found',
|
|
8
|
+
'No active editor is selected for this MCP session',
|
|
9
|
+
'Multiple running editors match the workspace project',
|
|
10
|
+
'Active editor mismatch',
|
|
11
|
+
'previously selected active editor',
|
|
12
|
+
'The selected active editor is currently unavailable on its registered Remote Control endpoint.',
|
|
13
|
+
];
|
|
5
14
|
export class AdaptiveExecutor {
|
|
6
15
|
editorAdapter;
|
|
7
16
|
commandletAdapter;
|
|
@@ -47,10 +56,42 @@ export class AdaptiveExecutor {
|
|
|
47
56
|
async executeRouted(editorFallback, method, params, options) {
|
|
48
57
|
const toolName = this._activeToolName;
|
|
49
58
|
const detection = await this.detector.detect();
|
|
59
|
+
const tryCommandletFallback = async (error, requiredCapability) => {
|
|
60
|
+
if (!toolName || !this.commandletAdapter || !shouldFallbackToCommandlet(error)) {
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
const commandletCapabilities = this.commandletAdapter.getCapabilities();
|
|
64
|
+
if (!commandletCapabilities.has(requiredCapability) && requiredCapability !== 'write_simple') {
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
const available = await this.commandletAdapter.isAvailable();
|
|
68
|
+
if (!available) {
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
this.detector.invalidateCache();
|
|
72
|
+
return this.commandletAdapter.execute('BlueprintExtractor', method, params);
|
|
73
|
+
};
|
|
50
74
|
// If no active tool context or editor mode, use the original path
|
|
51
75
|
// (preserves callSubsystemJson error-checking layer)
|
|
52
76
|
if (!toolName || detection.mode === 'editor') {
|
|
53
|
-
|
|
77
|
+
if (!toolName) {
|
|
78
|
+
return editorFallback(method, params, options);
|
|
79
|
+
}
|
|
80
|
+
const toolMode = this.getToolMode(toolName);
|
|
81
|
+
const requiredCapability = toolMode === 'read_only'
|
|
82
|
+
? 'read'
|
|
83
|
+
: toolMode === 'both'
|
|
84
|
+
? 'write_simple'
|
|
85
|
+
: 'write_complex';
|
|
86
|
+
try {
|
|
87
|
+
return await editorFallback(method, params, options);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (toolMode === 'editor_only') {
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
return tryCommandletFallback(error, requiredCapability);
|
|
94
|
+
}
|
|
54
95
|
}
|
|
55
96
|
const toolMode = this.getToolMode(toolName);
|
|
56
97
|
const requiredCapability = toolMode === 'read_only'
|
|
@@ -100,6 +141,13 @@ export class AdaptiveExecutor {
|
|
|
100
141
|
throw new ExecutorError('MODE_UNAVAILABLE', `No execution mode available for tool '${toolName}'. ${detection.reason}`, toolName, detection.mode, requiredCapability);
|
|
101
142
|
}
|
|
102
143
|
}
|
|
144
|
+
function shouldFallbackToCommandlet(error) {
|
|
145
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
146
|
+
if (message.startsWith('Failed to call ')) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
return EDITOR_FALLBACK_ERROR_FRAGMENTS.some((fragment) => message.includes(fragment));
|
|
150
|
+
}
|
|
103
151
|
export class ExecutorError extends Error {
|
|
104
152
|
code;
|
|
105
153
|
toolName;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/execution/index.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/helpers/capture.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -254,7 +254,7 @@ export const NEXT_STEP_HINTS_REGISTRY = new Map([
|
|
|
254
254
|
['extract_widget_blueprint', extractionHints('extract_widget_blueprint', {
|
|
255
255
|
on_success: [
|
|
256
256
|
'Use patch_widget or replace_widget_tree to modify the widget.',
|
|
257
|
-
'Use
|
|
257
|
+
'Use compile_widget to check for errors.',
|
|
258
258
|
'Use capture_widget_preview for visual verification.',
|
|
259
259
|
],
|
|
260
260
|
scope_suggestion: 'widget_authoring',
|
|
@@ -276,25 +276,17 @@ export const NEXT_STEP_HINTS_REGISTRY = new Map([
|
|
|
276
276
|
// =========================================================================
|
|
277
277
|
// Widget structure tools
|
|
278
278
|
// =========================================================================
|
|
279
|
-
['create_widget_blueprint', creationHints('extract_widget_blueprint', '
|
|
279
|
+
['create_widget_blueprint', creationHints('extract_widget_blueprint', 'replace_widget_tree', {
|
|
280
280
|
on_success: [
|
|
281
|
-
'Use
|
|
281
|
+
'Use replace_widget_tree to populate the widget tree.',
|
|
282
282
|
'Use extract_widget_blueprint to verify.',
|
|
283
283
|
'Use save_assets to persist.',
|
|
284
284
|
],
|
|
285
285
|
scope_suggestion: 'widget_authoring',
|
|
286
286
|
})],
|
|
287
|
-
['build_widget_tree', modificationHints('extract_widget_blueprint', {
|
|
288
|
-
on_success: [
|
|
289
|
-
'Use compile_widget_blueprint to verify the tree compiles.',
|
|
290
|
-
'Use extract_widget_blueprint to inspect the result.',
|
|
291
|
-
'Use save_assets to persist.',
|
|
292
|
-
],
|
|
293
|
-
scope_suggestion: 'widget_authoring',
|
|
294
|
-
})],
|
|
295
287
|
['replace_widget_tree', modificationHints('extract_widget_blueprint', {
|
|
296
288
|
on_success: [
|
|
297
|
-
'Use
|
|
289
|
+
'Use compile_widget to verify the new tree.',
|
|
298
290
|
'Use extract_widget_blueprint to inspect the result.',
|
|
299
291
|
'Use save_assets to persist.',
|
|
300
292
|
],
|
|
@@ -344,7 +336,7 @@ export const NEXT_STEP_HINTS_REGISTRY = new Map([
|
|
|
344
336
|
})],
|
|
345
337
|
['replace_widget_class', modificationHints('extract_widget_blueprint', {
|
|
346
338
|
on_success: [
|
|
347
|
-
'Use
|
|
339
|
+
'Use compile_widget to verify the class change.',
|
|
348
340
|
'Use extract_widget_blueprint to inspect the result.',
|
|
349
341
|
'Use save_assets to persist.',
|
|
350
342
|
],
|
|
@@ -352,7 +344,7 @@ export const NEXT_STEP_HINTS_REGISTRY = new Map([
|
|
|
352
344
|
})],
|
|
353
345
|
['batch_widget_operations', modificationHints('extract_widget_blueprint', {
|
|
354
346
|
on_success: [
|
|
355
|
-
'Use
|
|
347
|
+
'Use compile_widget to verify the batch result.',
|
|
356
348
|
'Use extract_widget_blueprint to inspect changes.',
|
|
357
349
|
'Use save_assets to persist.',
|
|
358
350
|
],
|
|
@@ -370,36 +362,6 @@ export const NEXT_STEP_HINTS_REGISTRY = new Map([
|
|
|
370
362
|
],
|
|
371
363
|
scope_suggestion: 'widget_authoring',
|
|
372
364
|
}],
|
|
373
|
-
['modify_widget_blueprint', modificationHints('extract_widget_blueprint', {
|
|
374
|
-
on_success: [
|
|
375
|
-
'Use operation-specific tools (patch_widget, replace_widget_tree, etc.) instead.',
|
|
376
|
-
'Use save_assets to persist changes.',
|
|
377
|
-
],
|
|
378
|
-
on_error: [
|
|
379
|
-
'Use extract_widget_blueprint to inspect current state.',
|
|
380
|
-
'Consider using operation-specific tools for clearer errors.',
|
|
381
|
-
],
|
|
382
|
-
scope_suggestion: 'widget_authoring',
|
|
383
|
-
})],
|
|
384
|
-
['modify_widget', modificationHints('extract_widget_blueprint', {
|
|
385
|
-
on_success: [
|
|
386
|
-
'Use save_assets to persist changes.',
|
|
387
|
-
'Use extract_widget_blueprint to verify.',
|
|
388
|
-
],
|
|
389
|
-
scope_suggestion: 'widget_authoring',
|
|
390
|
-
})],
|
|
391
|
-
['compile_widget_blueprint', {
|
|
392
|
-
on_success: [
|
|
393
|
-
'Inspect compile.messages and diagnostics for warnings.',
|
|
394
|
-
'Re-extract the widget blueprint before applying the next patch.',
|
|
395
|
-
'Check BindWidget names/types if there are abstract class references.',
|
|
396
|
-
],
|
|
397
|
-
on_error: [
|
|
398
|
-
'Use extract_widget_blueprint to inspect the current state.',
|
|
399
|
-
'Fix reported issues and recompile.',
|
|
400
|
-
],
|
|
401
|
-
scope_suggestion: 'widget_authoring',
|
|
402
|
-
}],
|
|
403
365
|
// =========================================================================
|
|
404
366
|
// Widget verification tools
|
|
405
367
|
// =========================================================================
|
|
@@ -464,7 +426,7 @@ export const NEXT_STEP_HINTS_REGISTRY = new Map([
|
|
|
464
426
|
['apply_commonui_button_style', {
|
|
465
427
|
on_success: [
|
|
466
428
|
'Use extract_widget_blueprint to verify the style was applied.',
|
|
467
|
-
'Use
|
|
429
|
+
'Use compile_widget to verify compilation.',
|
|
468
430
|
'Use save_assets to persist.',
|
|
469
431
|
],
|
|
470
432
|
on_error: [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { access } from 'node:fs/promises';
|
|
2
2
|
import { constants as fsConstants } from 'node:fs';
|
|
3
|
-
import path, {
|
|
4
|
-
import { buildEngineAssociationCandidates, readProjectEngineAssociation } from './workspace-project.js';
|
|
3
|
+
import path, { posix as posixPath, win32 as win32Path } from 'node:path';
|
|
4
|
+
import { buildEngineAssociationCandidates, isWindowsStylePath, isWslMountedWindowsPath, readProjectEngineAssociation, toHostFilesystemPath, toWindowsStylePath, } from './workspace-project.js';
|
|
5
5
|
export function rememberExternalBuild(result) {
|
|
6
6
|
return {
|
|
7
7
|
success: result.success === true,
|
|
@@ -32,6 +32,9 @@ export async function getProjectAutomationContext(deps) {
|
|
|
32
32
|
return nextContext;
|
|
33
33
|
}
|
|
34
34
|
const cachedHeuristicEngineRoots = new Map();
|
|
35
|
+
function getPathModule(platform) {
|
|
36
|
+
return platform === 'win32' ? win32Path : posixPath;
|
|
37
|
+
}
|
|
35
38
|
export function getHeuristicEngineCandidates(platform = process.platform) {
|
|
36
39
|
if (platform === 'win32') {
|
|
37
40
|
return [
|
|
@@ -74,10 +77,13 @@ function getEngineMarkers(platform) {
|
|
|
74
77
|
'Engine/Build/BatchFiles/Build.sh',
|
|
75
78
|
];
|
|
76
79
|
}
|
|
77
|
-
async function accessFirstMatchingMarker(root, markers) {
|
|
80
|
+
async function accessFirstMatchingMarker(root, markers, targetPlatform, hostPlatform) {
|
|
81
|
+
const pathModule = getPathModule(targetPlatform);
|
|
82
|
+
const normalizedRoot = targetPlatform === 'win32' ? toWindowsStylePath(root) : root;
|
|
78
83
|
for (const marker of markers) {
|
|
79
84
|
try {
|
|
80
|
-
|
|
85
|
+
const candidate = pathModule.resolve(normalizedRoot, marker);
|
|
86
|
+
await access(toHostFilesystemPath(candidate, targetPlatform, hostPlatform), fsConstants.F_OK);
|
|
81
87
|
return true;
|
|
82
88
|
}
|
|
83
89
|
catch {
|
|
@@ -86,24 +92,24 @@ async function accessFirstMatchingMarker(root, markers) {
|
|
|
86
92
|
}
|
|
87
93
|
return false;
|
|
88
94
|
}
|
|
89
|
-
async function probeEngineRootHeuristic(
|
|
90
|
-
|
|
91
|
-
|
|
95
|
+
async function probeEngineRootHeuristic(targetPlatform, hostPlatform) {
|
|
96
|
+
const cacheKey = `${hostPlatform}:${targetPlatform}`;
|
|
97
|
+
if (cachedHeuristicEngineRoots.has(cacheKey)) {
|
|
98
|
+
return cachedHeuristicEngineRoots.get(cacheKey) || undefined;
|
|
92
99
|
}
|
|
93
|
-
for (const candidate of getHeuristicEngineCandidates(
|
|
94
|
-
if (await accessFirstMatchingMarker(candidate, getEngineMarkers(
|
|
95
|
-
cachedHeuristicEngineRoots.set(
|
|
100
|
+
for (const candidate of getHeuristicEngineCandidates(targetPlatform)) {
|
|
101
|
+
if (await accessFirstMatchingMarker(candidate, getEngineMarkers(targetPlatform), targetPlatform, hostPlatform)) {
|
|
102
|
+
cachedHeuristicEngineRoots.set(cacheKey, candidate);
|
|
96
103
|
return candidate;
|
|
97
104
|
}
|
|
98
105
|
}
|
|
99
|
-
cachedHeuristicEngineRoots.set(
|
|
106
|
+
cachedHeuristicEngineRoots.set(cacheKey, '');
|
|
100
107
|
return undefined;
|
|
101
108
|
}
|
|
102
|
-
async function probePreferredEngineRoot(candidates,
|
|
103
|
-
const markers = getEngineMarkers(platform);
|
|
109
|
+
async function probePreferredEngineRoot(candidates, hostPlatform) {
|
|
104
110
|
for (const candidate of candidates) {
|
|
105
|
-
if (await accessFirstMatchingMarker(candidate,
|
|
106
|
-
return candidate;
|
|
111
|
+
if (await accessFirstMatchingMarker(candidate.path, getEngineMarkers(candidate.platform), candidate.platform, hostPlatform)) {
|
|
112
|
+
return candidate.path;
|
|
107
113
|
}
|
|
108
114
|
}
|
|
109
115
|
return undefined;
|
|
@@ -133,7 +139,16 @@ export async function resolveProjectInputs(request, deps) {
|
|
|
133
139
|
const projectPath = firstDefinedString(request.project_path, projectPathFromContext, projectPathFromWorkspace, projectPathFromEnv);
|
|
134
140
|
const target = firstDefinedString(request.target, targetFromContext, targetFromWorkspace, targetFromEnv);
|
|
135
141
|
const engineAssociation = projectPath ? await readProjectEngineAssociation(projectPath) : undefined;
|
|
136
|
-
const
|
|
142
|
+
const windowsWorkspaceHint = [request.engine_root, request.project_path, projectPathFromWorkspace, projectPathFromEnv]
|
|
143
|
+
.filter((value) => typeof value === 'string' && value.length > 0)
|
|
144
|
+
.some((value) => isWindowsStylePath(value) || isWslMountedWindowsPath(value));
|
|
145
|
+
const heuristicPlatforms = windowsWorkspaceHint && platform !== 'win32'
|
|
146
|
+
? ['win32', platform]
|
|
147
|
+
: [platform];
|
|
148
|
+
const associationCandidates = heuristicPlatforms.flatMap((candidatePlatform) => (buildEngineAssociationCandidates(engineAssociation, candidatePlatform).map((candidate) => ({
|
|
149
|
+
path: candidate,
|
|
150
|
+
platform: candidatePlatform,
|
|
151
|
+
}))));
|
|
137
152
|
let engineRoot = firstDefinedString(request.engine_root, engineRootFromContext, engineRootFromEnv);
|
|
138
153
|
let engineRootSource;
|
|
139
154
|
if (request.engine_root) {
|
|
@@ -147,7 +162,15 @@ export async function resolveProjectInputs(request, deps) {
|
|
|
147
162
|
}
|
|
148
163
|
else {
|
|
149
164
|
const preferredCandidate = await probePreferredEngineRoot(associationCandidates, platform);
|
|
150
|
-
|
|
165
|
+
let heuristicRoot = preferredCandidate;
|
|
166
|
+
if (!heuristicRoot) {
|
|
167
|
+
for (const candidatePlatform of heuristicPlatforms) {
|
|
168
|
+
heuristicRoot = await probeEngineRootHeuristic(candidatePlatform, platform);
|
|
169
|
+
if (heuristicRoot) {
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
151
174
|
if (heuristicRoot) {
|
|
152
175
|
engineRoot = heuristicRoot;
|
|
153
176
|
engineRootSource = 'filesystem_heuristic';
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -102,22 +102,6 @@ export function summarizeOutputSchema(schema) {
|
|
|
102
102
|
}
|
|
103
103
|
export function collectToolExampleFamilies(exampleCatalog, toolName) {
|
|
104
104
|
const equivalentToolNames = new Set([toolName]);
|
|
105
|
-
if (toolName === 'modify_widget_blueprint') {
|
|
106
|
-
[
|
|
107
|
-
'patch_widget',
|
|
108
|
-
'patch_widget_class_defaults',
|
|
109
|
-
'insert_widget_child',
|
|
110
|
-
'remove_widget',
|
|
111
|
-
'move_widget',
|
|
112
|
-
'wrap_widget',
|
|
113
|
-
'replace_widget_class',
|
|
114
|
-
'replace_widget_tree',
|
|
115
|
-
'batch_widget_operations',
|
|
116
|
-
].forEach((name) => equivalentToolNames.add(name));
|
|
117
|
-
}
|
|
118
|
-
if (toolName === 'compile_widget_blueprint') {
|
|
119
|
-
equivalentToolNames.add('compile_widget');
|
|
120
|
-
}
|
|
121
105
|
return Object.entries(exampleCatalog)
|
|
122
106
|
.flatMap(([family, entry]) => {
|
|
123
107
|
const exampleTitles = entry.examples
|
|
@@ -143,7 +127,6 @@ export function collectRelatedResources(toolName) {
|
|
|
143
127
|
if (toolName.startsWith('create_')
|
|
144
128
|
|| toolName.startsWith('modify_')
|
|
145
129
|
|| toolName.startsWith('apply_')
|
|
146
|
-
|| toolName === 'build_widget_tree'
|
|
147
130
|
|| toolName === 'save_assets') {
|
|
148
131
|
resources.add('blueprint://write-capabilities');
|
|
149
132
|
resources.add('blueprint://authoring-conventions');
|
|
@@ -175,7 +158,10 @@ export function collectRelatedResources(toolName) {
|
|
|
175
158
|
|| toolName === 'sync_project_code'
|
|
176
159
|
|| toolName === 'start_pie'
|
|
177
160
|
|| toolName === 'stop_pie'
|
|
178
|
-
|| toolName === 'relaunch_pie'
|
|
161
|
+
|| toolName === 'relaunch_pie'
|
|
162
|
+
|| toolName === 'read_output_log'
|
|
163
|
+
|| toolName === 'list_message_log_listings'
|
|
164
|
+
|| toolName === 'read_message_log') {
|
|
179
165
|
resources.add('blueprint://project-automation');
|
|
180
166
|
}
|
|
181
167
|
if (toolName === 'review_blueprint' || toolName === 'audit_project_assets') {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -3,6 +3,10 @@ export type WorkspaceProjectResolution = {
|
|
|
3
3
|
ambiguous: boolean;
|
|
4
4
|
searchedFrom: string;
|
|
5
5
|
};
|
|
6
|
+
export declare function isWindowsStylePath(input: string): boolean;
|
|
7
|
+
export declare function isWslMountedWindowsPath(input: string): boolean;
|
|
8
|
+
export declare function toWindowsStylePath(input: string): string;
|
|
9
|
+
export declare function toHostFilesystemPath(input: string, targetPlatform: NodeJS.Platform, hostPlatform?: NodeJS.Platform): string;
|
|
6
10
|
export declare function normalizeFilesystemPath(input: string | undefined): string | undefined;
|
|
7
11
|
export declare function filesystemPathsEqual(left: string | undefined, right: string | undefined): boolean;
|
|
8
12
|
export declare function findNearestWorkspaceProject(startDir?: string): Promise<WorkspaceProjectResolution>;
|