UI Composer 工具
UI Composer 工具用於本機 Composer extension pack 與 blueprint 輸入。它們不檢查正在執行的 WPF target,應在 catalog、validation、rendering、preview compile 或 apply workflow 前使用。
Contract Compatibility
Composer 目前支援下列 v1 contracts;schemaVersion 缺失或不同時會 fail closed:
| Contract | Supported version | Compatibility policy |
|---|---|---|
| UI pack | wpfdevtools.ui-pack.v1 |
原樣讀取 artifact;install/import workflow 只複製 pack files,不改寫內容。 |
| UI block | wpfdevtools.ui-block.v1 |
只從 enabled packs 解析 pack-qualified block kinds。 |
| UI recipe | wpfdevtools.ui-recipe.v1 |
只有 declared required packs 可用後才展開 recipes。 |
| UI blueprint | wpfdevtools.ui-blueprint.v1 |
必須提供 packs[]、primaryPack 與 pack-qualified block kinds;可用 resourceVariants 選擇 pack-owned resource variants。 |
| Source lock | wpfdevtools.source-lock.v1 |
保留 loaded packs 的 provenance metadata。 |
| Pack install manifest | wpfdevtools.pack-install-manifest.v1 |
記錄 copied pack installation metadata,不改變 pack artifact。 |
| Composer project | wpfdevtools.composer-project.v1 |
保留給 project-local Composer configuration。 |
目前 contract 仍在 pre-release。Beta 版本可以刻意修正 v1 shape 而不保留 legacy aliases;packs、validators、文件與 extension-pack creator 必須一起更新。第一個 public stable contract 發布後才開始套用 stable compatibility policy。
資料驅動的視覺基礎
- Native WPF layout 與 media 由明確的
core@0.1.0pack 提供,並使用role="layout-pack"。請使用core.stack、core.grid、core.rowDefinition、core.columnDefinition、core.gridCell、core.scrollViewer、core.border、core.image、core.text與core.template等 qualified kinds。 core.scrollViewer可承載一個通用 child,並分別設定 WPF 水平與垂直 scrollbar policy。需要實際捲動時,請把它放在有界的 grid row 或 column,並透過 MCP 驗證最終 runtime offset 或可見項目確實改變,不要只從靜態截圖推測。core.image透過 application-local pack URI 或 simple binding 顯示專案擁有的圖片。使用 literal file 時請先建立檔案;經審查的projectIntegrationPlan與apply_ui_project_integration流程會把它宣告為 WPF Resource。此 block 要求可存取性的 automation name,並拒絕外部、檔案系統、UNC 與 traversal URI。core.grid支援真實 rows、columns、grid cells、spanning、alignment 與 WPFgridLength。Layout 行為來自 pack data,不是 engine primitive 或 WPF UI 特例。- Built-in WPF UI visual set 包含
wpfui.autoSuggestBox、wpfui.numberBox、wpfui.toggleSwitch、wpfui.progressBar、wpfui.progressRing,也提供可設定的 typography、margin、padding、alignment、width 與 window content constraints。Title bar actions 可放入搜尋框或按鈕。對於有界進度、階段流程或並列比較,請使用線性的progressBar;若只需在緊湊空間表示持續活動,不需要長軌道,則使用progressRing。 - Pack 自有的
wpfui.editorialCardblock 提供含媒體、文案、任意內容與操作 slots 的橫向 editorial surface。其 optionalmediaSource可使用專案自有的 application-local pack URI 或 WPF binding;外部與檔案系統 URI 仍會被阻擋。不設定它並填入 optional media slot,即可建立具 accessibility 資訊的 symbol fallback。這仍是 pack data,具有 no Composer engine special case 的特性,因此第三方 pack 可用自己的 contracts 與 renderers 提供同等媒體模式。 - Property contract 可宣告
minimum、maximum、integer、thickness與gridLengthconstraints。SlotallowedKinds接受 exact qualified kind、*或<pack-id>.*;optional non-negative integerminItems與maxItems宣告 child-count bounds,省略時代表最少零項且不設上限。xamlItemTemplate會對每個 child 套用宣告的 wrapper。 - Renderer template 可用不可巢狀的
{{?slot.name}}...{{/slot.name}}區段包住僅供 optional slot 使用的 XAML。當該已宣告 slot 沒有 child 時,Composer 會省略整個區段,避免留下空白 property element 或 layout container。 - Renderer template 可用不可巢狀的
{{?property.name}}...{{/property.name}}包住「已宣告 property 具有非空 effective value」時才輸出的 XAML;反向條件則使用{{^property.name}}...{{/property.name}}。控制項專屬的 property 優先序因此留在 extension-pack data,不會寫進 Composer 程式碼。 - Extension block 可宣告
authoringRoles,slot 則可用childRole、whenProperty、whenValues、必填的itemSpacingProperty與 optionalchildMarginProperty宣告一個純資料的adjacencyAdvisory。相鄰且角色相符的 children 沒有有效水平間距時,validation 會在第二個 child 的精確路徑回傳通用AdjacentContentWithoutSeparationwarning 與 repair paths,最多 32 筆;engine 不推測任何 pack、block kind、control library 或 property name。 - Pack 可提供具 default 與 pack-owned
appearance(light、dark或neutral)的 namedresourceVariants。Blueprint 依 pack id 選擇 variant,因此 Composer 不需要任何 library-specific theme logic。Block property 可將visualRole宣告為surface;當 explicit surface 與 selected theme-styled subtree 衝突時,validation 會在精確 property path 回傳SurfaceThemeContrastRisk。 - 會輸出 pack XML namespace 的第三方 renderer 必須在
pack.json宣告安全 structural preview metadata。Composer 依 metadata 產生 preview types;使用 custom namespace 卻缺少 contract 時回傳PreviewContractMissing。只輸出 native controls 的第三方 renderer 不需要 stub contract。Pack 不可提供 arbitrary preview C#。 - Preview metadata 保持 pack-neutral:語意子類別若套用以原生基底為 TargetType 的樣式,應使用
tabControl或tabItem。任何 selectedbaseKind已繼承的 member 都不可重複宣告;Window.Content、sizing、command、items 與 tab state 等 native properties 應直接用於 renderer XAML。Composer 會拒絕可能讓 authored value 與 native visual tree、command、style 或 template 脫節的 shadow declaration。只有整個值為 unset property token 的 renderer attribute 會被省略;明確空字串與 literal empty attribute 仍會保留。除非 blueprint 明確覆寫目前 theme,否則不要設定Foreground等可繼承 visual property。 - 任何 blueprint node 都可宣告穩定的
elementName與automationId。Composer 會驗證安全語法及整棵樹的唯一性,再將它們保留為 renderer root 上的 WPFx:Name與AutomationProperties.AutomationId。重複值會以DuplicateElementName或DuplicateAutomationId失敗;若與 pack-owned root identity 衝突,也會明確失敗而不會暗中改寫 renderer contract。
建立原創 app 時,先以 includeRecipes=false 呼叫 get_ui_block_catalog,依 available capabilities 決定 creative brief。稍後再把 recipes 當作 optional accelerator;不要讓第一個 recipe 決定 app concept。
Composer observability
Composer tool responses 會包含 observability object,提供本機 structured logs、per-call metrics、top diagnostic codes 與 privacy policy summary。這些資料只會回傳在 MCP response 或 pack import plan;預設不會 export 到 remote service。Hosted environment 若要明確停用 telemetry policy,可設定 WPFDEVTOOLS_COMPOSER_TELEMETRY_DISABLED=true。
Observability payload 不包含 blueprint JSON、generated XAML、完整使用者檔案內容、secrets 或 absolute local paths。Logs 只保留穩定 diagnostic codes 與短 remediation text,讓 agent 可在不複製 project content 的情況下除錯 validation、render dry-run、apply、security rejection、rollback、preview compile 與 pack import paths。
list_ui_block_packs
列出 built-in、project-local 與 user-global roots 中已安裝的 UI block packs。每個 entry 都包含 kind、themeTokens、resourceVariants、role、required、counts、provenance、readiness metadata 與可用 block kinds。resourceVariants.defaultVariant 及其有序 variant ids/appearances 是權威的 pack-neutral resource choices。role 是依 pack kind 推導的建議的 blueprint role;required=true 表示預設 required declaration,而 required=false 不代表 blueprint 可以省略其實際使用 block 的 pack。請以 top-level allowedPackRoles 作為 blueprint packs[].role 的權威 pack-neutral 值,不要從 pack id 猜測 role。
Request options:
projectRoot: optional WPF project root。提供時,會從<projectRoot>/.wpfdevtools/packs探索 project-local packs。localAppDataRoot: optional user-global discovery root。省略時,server 會使用目前使用者的 LocalApplicationData path。
此 tool 的公開 payload 不會回傳 absolute pack root paths。請以 structuredContent 作為 canonical result,content[0].text 只作為 compact fallback。
Caller-selected roots 必須解析至本機非網路儲存體;UNC、device 與其他 remote roots 會在 filesystem probing 前遭拒絕。在 Windows 上,directory discovery 前會逐一檢查每個既有 path component;任何 reparse-point ancestor 或 root 都會在 existence check 或 enumeration 可能跟隨它之前遭拒絕。Discovery 受 pack count、directory 與 file traversal limits 約束,因此仍應優先提供窄範圍 root。
import_ui_block_pack
驗證 normalized extension-pack ZIP,並只在明確核准後安裝至 <projectRoot>/.wpfdevtools/packs。預設 dry-run 會回傳 pack identity、archive SHA256、destination root 與 relative file plan,而且不寫入檔案。
Request options:
archivePath: 必填,經審查 normalized pack ZIP 的 absolute local path。projectRoot: 必填,absolute local WPF project root;這是唯一 write boundary。dryRun: 預設為true;先審查 archive hash 與完整 file plan。reviewedArchiveSha256:dryRun=false時必填;請從已審查的 dry-run response 原樣複製archiveSha256。若 archive 在審查與寫入之間變更,import 會失敗。confirmImport:dryRun=false時必須為true。allowOverwrite: 預設為false;只有在審查相同 pack id/version 的 replacement 後才啟用。
Non-dry-run import 還需要 WPFDEVTOOLS_MCP_ALLOW_DESTRUCTIVE_TOOLS=true、WPFDEVTOOLS_MCP_ALLOW_PROJECT_WRITES=true,以及 exact WPFDEVTOOLS_MCP_ALLOWED_PROJECT_ROOTS match。Compressed archive 在 hashing 前以 64 MiB 為上限,hashing 使用可取消的 asynchronous I/O。Importer 會使用同一個已開啟的 archive handle 綁定審查與 extraction,並拒絕 unsafe archive entries、invalid pack contracts、destination reparse points,以及 project-local registry 以外的 writes;它不會修改 project files、package references、resources、XAML、code-behind 或 ViewModels。
get_ui_block_catalog
從 enabled Composer packs 回傳 block catalog entries。Agent 需要在建立 blueprint 前理解具體 block kinds、properties、slot names、allowedKinds、declared child-count bounds、renderer availability 或 source hint summaries 時,先呼叫 list_ui_block_packs,再使用此 tool。
Request options:
packIds: optional pack id filter,例如["sample"]。category: optional block category filter。authoringRole: optional case-insensitive exact filter,用於查詢 pack-definedauthoringRoles。請先從預期視覺結構推導overlay-layout、carousel等角色,再選擇 convenience blocks。kindPrefix: optional pack-qualified kind prefix。composableOnly: true 時只回傳具備 renderer template 的 blocks。kind: optional exact pack-qualified block kind,用於 single-block detail。includeRecipes: true 時同時回傳可供expand_ui_recipe使用的 recipe catalog entries。compact: true 時回傳精簡 discovery projection,保留 identity、pack-authored block description、category、property names、required 或具有數值界線的propertyContracts、preview warnings、slot bounds、renderer availability、compositionSkeleton及 pack-definedauthoringRoles。每個 compact property contract 會保留 type、required flag、bounded allowed-value sample/count、numeric bounds、integer flag 與 format。省略maximum或maxItems仍表示不設上限。allowedValueQuery: optional case-insensitive substring search,用於搜尋 allowed string values。請搭配 exactkind與compact=false;省略kind時會回傳CatalogExactKindRequired,而不是完整 catalog。Query 最長 128 字元。
Catalog entries 只包含 source hint paths,不會把第三方 source code 複製進 tool output。
Broad discovery 請使用 compact=true;選定 block 後,在設定不熟悉的 properties 前,以 exact kind 及 compact=false 查詢完整契約。Full mode 仍為預設,並保留 descriptions、完整 property contracts、slots 與 source hints。
大型 pack-owned vocabulary 在 exact-kind detail 中也會維持 bounded。每個 property 都會回報完整 allowedValueCount、目前的 allowedValueMatchCount、最多 12 個符合條件的 allowedValues,以及這批 matches 是否 truncated。選值時,以 exact kind、compact=false 與簡短的概念或 icon 名稱作為 allowedValueQuery 再呼叫一次。Validation 仍會針對完整 pack vocabulary 做精確比對,並只回傳 bounded、相關性高的 repair values。
Pack author 可為 blocks、properties 與 slots 提供 inert description text。當 structural preview 的 measurement 或 styling 可能與 final package 不同時,property 也可提供 previewWarning。選擇值之前應先讀取這些 pack-defined fields;它們能說明 renderer 行為,而不需在 Composer 加入 library-specific logic。Renderer identity target 預設可由 runtime element tools 檢查;只有非 element WPF object 無法被這些 tools 找到時,pack 才設定 renderer.runtimeInspectable=false。
Response 也會包含 authoringGuidance。其中 strategy="brief-first" 與 creativeBriefRequired=true 會要求 Agent 先依 discovered capabilities 自行決定 product purpose 與 information architecture。includeRecipes 預設為 false;之後才把 recipes 當成 optional accelerators 或 fragments 使用。
每個 catalog item 都包含依該 block 自身 contract 產生的 pack-neutral
compositionSkeleton。其中會提供精確 kind、required properties 的值,以及
declared slots 的空陣列。Agent 可直接將此 compact node 放入 blueprint,再加入
children 或 optional properties,不必手動重打 pack-specific kind 與 slot names。
Optional blueprint draft transport
多步驟 workflow 若要避免重複傳輸及 double-serialize 同一份文件,可使用 create_ui_blueprint_draft。先建立最小且有效的 root 或 shell、立即存成 draft,再以 compose_ui_blueprint 加入 descendants;不要在一個 JSON 字串中手寫完整的深層 tree。工具會回傳 opaque draftRef,且不會 echo 原始文件。Bounded aliasInventory 最多列出 64 個由 node-level elementName 宣告的 copy-ready @ElementName aliases;metadata fields 不會建立 alias。Immutable、process-local store 最多保留 32 drafts,每份最多 65,536 字元,每筆存活 30 minutes。Reference 無法猜測、永不持久化;MCP server process 結束、到期或容量淘汰後就會失效。
使用 patch_ui_blueprint_draft 搭配 live reference,可建立新的 immutable derived reference。Broad object change 可傳入 JSON Merge Patch object:null 會移除 object property、nested object 會遞迴 merge、array 或 scalar 會取代 target。單一 edit 可傳入 exact jsonPath 與 native JSON value;若要刪除該 target,省略 value 並設定 remove=true。Bare @ElementName alias 會選取整個 named node 以進行 replace/remove;若要操作 nested target,則附加 @ElementName.properties.text 等 relative path。兩到 16 個相關 edits 可改傳 ordered operations;它們會對同一份 working copy 原子執行,並只產生一個 derived reference。每筆 atomic change 都會包含從零開始的 operationIndex。Source reference 永遠不變。每次成功衍生都會回傳 bounded changeSummary,列出 changed paths 與 compact before/after values,而不 echo 完整 blueprint。遺失、到期或遭淘汰的 reference 會回傳 BlueprintDraftNotFound 與 recovery guidance。
七個接受 blueprintJson 的 downstream tools 也接受 opaque draftRef:compose_ui_blueprint、validate_ui_blueprint、render_ui_blueprint、preview_ui_blueprint、repair_ui_blueprint、apply_ui_blueprint 與 apply_ui_project_integration。One-shot workflow 仍可直接使用 blueprintJson。
create_ui_blueprint_draft
建立一份 bounded ephemeral draft。Response 包含 draftRef、characterCount、expiresAt、immutable=true 與精確 retention metadata,並刻意省略 stored JSON。
patch_ui_blueprint_draft
以三種互斥模式之一衍生新 draft:
- Broad change:傳入
draftRef與patchJson,使用 JSON Merge Patch。 - Surgical change:傳入
draftRef、exact path(例如$.layout.slots.children[0].properties.text)與value;target node 若具有唯一的標準 blueprintelementName,可使用@ElementName選取整個 node,或以@ElementName.properties.text選取 descendant,不必重複巢狀 array path。Pack-defined property key 若不是 simple identifier,請使用 bracket-quoted segment,例如$.layout.properties["accent.color"]。若要刪除 target,省略value並設定remove=true。 - Atomic multi-path change:傳入
draftRef與一到 16 個 ordered objects 組成的operationsarray。每個 object 沿用 surgical mode 的jsonPath/value或remove=truecontract;path 與 stable alias 會針對同一 batch 內先前 operation 的結果解析。任一 operation 無效時,完整 batch 會以精確$.operations[index]request path 失敗,不保留 partial draft。此 all-or-nothing mode 只回傳一個 immutable reference 與 ordered per-path change summaries。
Response 會回傳新 reference、sourceDraftRef、retention metadata,以及 compact changeSummary;其中包含 changeCount、bounded changes 與 truncation metadata。每個 change 會列出 jsonPath、changeType 及 compact before/after values;atomic batch 也會包含從零開始的 operationIndex。Response 不會 echo 完整 blueprint。若目標是把 catalog block 插入 slot array,應改用 compose_ui_blueprint。
compose_ui_blueprint
將一個 pack-defined compositionSkeleton 插入既有 blueprint slot,並驗證結果文件。Agent 可用它逐步建立巢狀介面,不必手動重寫深層 JSON。此操作保持 pack-neutral,而且不會寫入檔案。
Request options:
blueprintJson: 目前完整的 blueprint JSON 文字或 opaquedraftRef。targetPath: 精確 slot path。Root slot 使用$.layout.slots.<slot>;每個 nested slot 前提供明確 child index,例如$.layout.slots.content[0].slots.actions;node 具有唯一的標準 blueprintelementName時,也可使用@ElementName.slots.actions。成功 response 仍會回傳解析後的精確insertedPath。kind: 來自get_ui_block_catalog搭配composableOnly=true的 exact pack-qualified block kind。elementName與automationId: optional standard identities,可在插入時直接指定。既有 blueprint validation 會驗證安全語法及 blueprint-wide uniqueness;兩者皆不依賴選用的 extension pack。properties: optional JSON object,可在插入時套用 pack-defined values。Installed block contract 會驗證 property name、type、range 與 allowed values。insertionIndex: optional zero-based position;省略時 append。projectRoot與localAppDataRoot: optional pack discovery roots。
需要在插入時設定 block 時,使用 properties 可避免再透過很長的 nested path 追加一次 edit,同時仍以 pack 的 compositionSkeleton 為權威。Raw JSON input 在 composed=true 時會回傳新的 blueprint、compact blueprintJson、精確 insertedPath 與 validation result。Draft input 則回傳新的 immutable draftRef 並省略完整文件,source draft 保持不變。所有未完成 composition 的 outcome 都會以 MCP error result 回傳 success=false。Invalid draft-derived candidate 仍會保留在 candidateDraftRef;raw input 則維持既有 invalidCandidate 與 candidateBlueprintJson recovery shape。兩者都不會寫入 project files。Ambiguous path 與 non-composable block 只回傳可採取行動的 errors,不提供 candidate。
每個成功 response 也會回傳 bounded insertedNodeSummary,讓 caller 不必 render 或取回完整 draft,就能驗證同呼叫的設定。內容包含解析後的精確 JSON path、kind、optional elementName 與 automationId、property total/reported counts、truncation state,以及最多 32 個 deterministic property entries。每個 entry 包含 name、JSON value kind、最多 160 字元的 compact value 與明確的 value-truncation flag。
Target 可解析到 installed block contract 時,targetSlotSummary 會回傳 exact path、parent kind、slot name、allowedKinds、minItems、maxItems、existing/resulting counts、remainingCapacity 與 capacity 是否超出。已宣告但省略的空 slot 會在第一次 compose 時建立。無上限的 maxItems 與 remainingCapacity 會明確回傳 JSON null,而不會省略 member。Invalid candidate 也會保留同一份 summary,讓 Agent 遇到 SlotMinimumItemsNotMet 或 SlotMaximumItemsExceeded 時不必再查一次 catalog。這些是 extension-declared child-count constraints,不是 pixel-width 預測。
validate_ui_blueprint
依照已安裝 Composer pack contracts 驗證 UI blueprint JSON。請在 list_ui_block_packs 與 get_ui_block_catalog 之後、rendering XAML 或 apply generated UI 之前使用。
Request options:
blueprintJson: required raw UI blueprint JSON,schemaVersion必須是wpfdevtools.ui-blueprint.v1;也可傳入 opaquedraftRef。targetPath: optional target XAML path,用於檢查 generated class/member collision;省略時使用Views/<blueprint-name>.xaml。projectRoot: optional WPF project root。提供時,會從<projectRoot>/.wpfdevtools/packs探索 project-local packs。localAppDataRoot: optional user-global discovery root。省略時,server 會使用目前使用者的 LocalApplicationData path。
完成 validation 呼叫時 response 會維持 success=true,並用 valid 表示 blueprint 是否有效。有效結果會包含 flattened compositionMap,其中有 total/reported counts、truncation 狀態,以及最多 64 個 copy-ready slot targets。每個 target 會回傳 exact targetPath、parent path/kind、slot name、目前與最小/最大數量,以及剩餘容量。有 element alias 時會優先使用;任意 extension-defined slot name 則會使用 bracket-quoted path。Validation issues 會包含 jsonPath、code、message、repairSuggestion,以及相關的 allowedKinds 或 allowedValues。語法有效但 field type 不相容的 JSON 會在 serializer exact path 回傳 InvalidBlueprintShape,附上 observedValueKind、copy-ready expectedJsonShape 與精確 replacement guidance;malformed JSON 仍會在 root 回傳 InvalidBlueprintJson。未知的 pack-owned resource selection 會以 UnknownResourceVariant 失敗;explicit surface/theme 衝突則會在 preview 或 apply 前回傳 bounded SurfaceThemeContrastRisk warning。Node-level identity 會在 render 前驗證安全語法、唯一性與 GeneratedClassMemberNameCollision。blueprintSize 會回傳 currentCharacters、maximumCharacters、remainingCharacters 與 utilizationPercent,讓 Agent 能在碰到 public input limit 前先精簡文件。
expand_ui_recipe
將 starter recipe 展開成完整 UI blueprint,並立即執行 blueprint validation。呼叫前可先使用 get_ui_block_catalog 搭配 includeRecipes=true 探索 recipe id 與 inputs。
Request options:
recipeId: required pack-qualified recipe id,例如sample.workspaceStarter。inputs: optional JSON object,提供 recipe input values。省略時會使用 recipe defaults。projectRoot: optional WPF project root。提供時,會從<projectRoot>/.wpfdevtools/packs探索 project-local packs。localAppDataRoot: optional user-global discovery root。省略時,server 會使用目前使用者的 LocalApplicationData path。
Response 包含 valid、recipeId、展開後的 blueprint 與 nested validation result。Built-in WPF UI starter recipes 覆蓋 navigation shell、dashboard card、data grid page 與 tabbed settings patterns。
Built-in catalog 會刻意排除 Snackbar 與 ContentDialog 這類需要 host 的控制項。這些控制項需要 presenter、host 或 runtime show behavior,不能安全地表示成獨立 layout node。請以 runtime catalog discovery 為準;第三方 pack 只有在 renderer 與 behavior contract 能涵蓋這些要求時才應提供同類控制項。
One-shot raw workflow 在下一個 Composer call 前,請將 structuredContent 的 blueprint object 序列化為 JSON 文字,再以 blueprintJson 參數名稱傳入。重複呼叫時,可先建立一次 draft,再透過同一個 blueprintJson 參數傳入其 draftRef。不要改用名為 blueprint 的參數。
每個 Composer blueprintJson 參數最多接受 65,536 字元。請使用 compact serializer,避免 formatting whitespace 消耗此上限。PowerShell 請以 $blueprint | ConvertTo-Json -Depth 100 -Compress 序列化 structured blueprint object;明確指定 depth 可保留 built-in recipes 的巢狀 properties。其他 client 在序列化展開後的 object 時應停用 indentation。
render_ui_blueprint
對有效的 UI blueprint 執行 dry-run XAML rendering。請在 validate_ui_blueprint 或 expand_ui_recipe 後使用,以便在任何寫檔 apply workflow 前檢查 generated XAML、required package references 與 application resource setup。
Request options:
blueprintJson: required raw UI blueprint JSON,schemaVersion必須是wpfdevtools.ui-blueprint.v1;也可傳入 opaquedraftRef。targetPath: optional target XAML path suggestion。Renderer 會在 file plan 回報此路徑,但不會寫入。projectRoot: optional WPF project root。提供時,會從<projectRoot>/.wpfdevtools/packs探索 project-local packs。localAppDataRoot: optional user-global discovery root。省略時,server 會使用目前使用者的 LocalApplicationData path。
完成 render 呼叫時 response 會維持 success=true,並用 valid 表示 render 是否有效。成功結果包含 xaml、requiredNuGetPackages、requiredResources、packageIntegrationGuidance,以及 wouldWriteFiles=false 的 filePlan。Package guidance 會依 target project 推導,而且不會編輯 project 或 central package files。無效結果會回傳 validation 或 render issues,包含 jsonPath、code、message 與 repairSuggestion。
preview_ui_blueprint
在 temporary WPF preview project 中 compile generated UI Composer XAML。Agent 需要在 apply generated UI 到真實 project 前取得符合 CI 的 compile、host-load,或 runtime scene/layout evidence 時,請在 render_ui_blueprint 後使用。
Request options:
blueprintJson: required raw UI blueprint JSON,schemaVersion必須是wpfdevtools.ui-blueprint.v1;也可傳入 opaquedraftRef。restoreEnabled: optional boolean,預設為 true。false 時 temporary project 會用--no-restorebuild,以便 deterministic 驗證 missing-restore diagnostics。startHost: optional boolean,預設為 false。true 時 successful build 後會啟動 temporary preview host,並回報 generated-view load status。includeRuntimeDiagnostics: optional boolean,預設為 false。搭配startHost=true時,會對 temporary host 重用connect、get_ui_summary(depthMode="semantic")、涵蓋 generated names 及 non-generated correlation names(authoredelementNamevalues 與 renderer-provided rootx:Namevalues)的 boundedfind_elementslookup plan、針對這些精確目標的 batchedget_clipping_info,以及get_layout_info。這需要WPFDEVTOOLS_MCP_ALLOW_SENSITIVE_READS=true。compactRuntimeDiagnostics: optional boolean,預設為 true。Compact mode 會省略成功產生的 XAML 與無風險 correlation details,但保留其 length/count、每個 tool outcome、失敗診斷 payload,以及調查 layout risk 所需的 correlations。成功的 screenshot 也會在兩種模式中重複放在 response 前段的一級previewScreenshotpayload,避免 verbose diagnostics 隱藏可重用的 resource handle。只有確實需要完整 XAML、correlation 與 raw diagnostic payloads 時才設為 false。includeScreenshotDiagnostics: optional boolean,預設為 false。搭配startHost=true時會啟用 runtime diagnostics,且只有在WPFDEVTOOLS_MCP_ALLOW_SENSITIVE_READS=true與WPFDEVTOOLS_MCP_ALLOW_SCREENSHOTS=true同時允許時才會要求 screenshot。screenshotOutputMode: optional closed value,預設為metadata;需要保留 server-owned PNG 時使用file,response 會回傳resourceUri與精確的resourceReadrequest。Temporary preview host 結束後、server session 結束前,必須在相同 MCP server session 以resourceRead.method(resources/read)和resourceRead.params讀取。其他值(包含base64)會在 preview work 開始前回傳InvalidArgument。screenshotMaxWidth與screenshotMaxHeight: optional positive bounds,預設為 1024。跨 constrained Agent image bridge 進行 visual consumption 時應保留預設值;只有 full rendered dimensions 是 archival evidence 的必要條件時,才明確傳入 null。viewportWidth與viewportHeight: optional previewWindow.Width與Window.Height,以 device-independent pixels 表示,每個值範圍為 1 到 8192。請配合預期的 target Window dimensions,以便在 apply 前找出 overflow。這兩個參數會影響 WPF layout;screenshot bounds 只縮放回傳的 pixel evidence。有 Window chrome 時,實際 client area 會較小。visualLayoutContractJson: optional pack-neutral JSON,包含 1 到 16 個具唯一 exactelementName的 regions。每個 region 宣告相對於 preview root 的 normalizedbounds(x、y、width、height)、0 到 0.25 的 optionaltolerance(預設 0.05),以及 optionalhorizontalScrollbarChrome/verticalScrollbarChrome;其值為any、hidden或visible。此功能需要startHost=true與 sensitive reads。runtimePackApprovalTokens: optional 已審查 content-bound tokens,只套用於這次 request;需要WPFDEVTOOLS_MCP_ALLOW_COMPOSER_RUNTIME_APPROVALS=true。correlationLookupLimit: runtime diagnostics 最多檢查的 exact non-generated correlation names(authoredelementNamevalues 與 renderer-provided rootx:Namevalues)數量。預設為 32,上限為 64;另有上限的 visual-contract names 不會占用此 lookup budget。只有unresolvedCorrelations回報reason="lookup-budget"時才提高;其他原因需要修復或 final-app check,不應增加 lookups。projectRoot: optional WPF project root。提供時,會從<projectRoot>/.wpfdevtools/packs探索 project-local packs。localAppDataRoot: optional user-global discovery root。省略時,server 會使用目前使用者的 LocalApplicationData path。
visualLayoutContractJson value 範例:
{
"regions": [{
"elementName": "PrimaryRegion",
"bounds": { "x": 0.05, "y": 0.05, "width": 0.9, "height": 0.5 },
"tolerance": 0.05,
"horizontalScrollbarChrome": "hidden"
}]
}
Preview 會執行 restore/build,且可能載入第三方程式碼,因此 preview_ui_blueprint 屬於 destructive tool;即使只做 compile,也需要 WPFDEVTOOLS_MCP_ALLOW_DESTRUCTIVE_TOOLS=true。
Window client 會視為 implicit viewport boundary,因此即使 WPF ClipToBounds 是 false,超出真實 host client 的內容仍可回報 clippingSource="window-client-viewport"。
此 tool 只寫入隔離的 temporary preview directory,compile smoke 後會刪除。Built-in runtime packs 由 release provenance 信任,且不會出現在這份 review 中。NuGet build targets、control constructors 與 resource markup 都是可執行的第三方相依套件,因此 project-local 與 user-global packs 預設維持 structural,直到對應的 runtimePackApprovalReviews entry 完成審查。每個 entry 都會結構化提供 pack identity、scope、fingerprint、所選 resources、含 hashes 的 exact package closure、approvalScope="content-bound-installed-pack"、approvalSource(none、request-token 或 environment-token)、approved、runtimeEligible,以及 nullable eligibilityCode/eligibilityMessage,不需要解析診斷文字。不符合資格的 entry 不會提供 approval token;應先修復回報的 package immutability 或 resource-safety 問題。當 WPFDEVTOOLS_MCP_ALLOW_COMPOSER_RUNTIME_APPROVALS=true 時,可把精確 token 放入 runtimePackApprovalTokens 重試,且只授權該次 request;由 operator 控制的 WPFDEVTOOLS_COMPOSER_TRUSTED_RUNTIME_PACKS 仍可用於 server-start approval。這個綁定內容的 approval token 綁定 pack scope、canonical installed root、id、version 與 fingerprint,不能授權另一個 project 或修改後的 pack。Runtime dependency closure 中的每個 package 都必須列出 exact [version] 與 NuGet SHA-512 contentHash;restore 使用 preview-local NuGet cache、拒絕未宣告的 transitive packages,並在 build 前核對所有 hashes。Selected preview inputs 會在產生 project 前執行 safety scan。通用 WPF framework safety rules 會拒絕外部或 rooted image、navigation、media、XML 與 resource-dictionary locations。Resource dictionary 只允許 pack 宣告的 application-local ResourceDictionary pack URI;preview 仍會封鎖 literal Image.Source 與 BitmapImage.UriSource。已核准 packs 會使用其 NuGet packages、XML namespaces、selected resource variants 與去重且維持順序的 application dictionaries。這裡沒有 pack 或 library-specific branching:framework safety checks 只分類可能啟動 I/O 的 WPF surfaces,不會辨識第三方 pack id、block kind、control type 或 resource name。
完成結果依序以 visualFidelity="resource-backed" 表示純 runtime output、"hybrid-resource-backed" 表示 runtime/stub 混合、"structural" 表示只有 stubs;invalid、cancelled 或 build failure 則回報 "not-available"。visualValidationGuidance 與 visualComparisonChecklist 仍要求在 apply、build 並 launch 後確認 final app。成功的 compact 結果包含 generatedXamlLength、elementCorrelationCount、buildOutput 與 previewHost summary;只有確實需要完整 generated xaml 與無風險 elementCorrelations 時才設 compactRuntimeDiagnostics=false。涉及 clipping、unresolved lookup、incomplete inspection 或 truncated inspection 的 correlations 在 compact mode 仍會保留。Runtime diagnostics 是 opt-in;失敗 payload 仍會保留,避免隱藏 recovery guidance。layoutRiskSummary.warnings 會把幾何上部分可見的 targets 排在完全離開 viewport 或尚未分類的 overflow 前面;geometricClippingSeverity 與 visibleRatio 只描述幾何,不會宣稱重要 pixels 一定遺失。成功的 screenshotOutputMode="file" resource 會直接出現在 previewScreenshot,仍受 SessionManager 的 24 小時與 100-resource 上限管理,並在 expiry、eviction 或 disposal 時移除。若 client 顯示缺漏或大片暗色,但 semantic evidence 完整,先依 screenshotVerificationGuidance 重讀 previewScreenshot.resourceUri 並核對 SHA-256,再決定是否重跑。相同 decoded bytes 仍 sparse 時,才以 screenshotMaxWidth=1024 與 screenshotMaxHeight=1024 重跑 preview_ui_blueprint;原呼叫回傳時 temporary host 已結束。Verified image 與 semantic summary 尚未一致前,不可回報 product visual failure。Build failure 會在可用時對應回 blueprint root 與 renderer template path。
提供 visualLayoutContractJson 時,visualLayoutContractSummary 會回報 matched、mismatched 與 unresolved named regions,包含 unresolvedCount、nullable unresolved reason、expected 與 measured normalized bounds、maximum bounds delta,以及 scrollbar-chrome mismatches。Scrollbar expectation 必須指向可提供 computed scrollbar visibility 的 runtime element;否則該值 unavailable,region 會判為 mismatch。Contract 只量測 caller 明確宣告的 names 與 geometry,不辨識 pack id、control library、product name 或 reference-image subject。它可在 apply 前把從任意參考圖提取的 composition check 轉成 machine-readable evidence;preview evidence 不是最終 visual approval,因此仍須驗證 final built application。
propertyWarnings array 只包含 submitted blueprint 明確使用之 properties 的 pack-defined warnings。每個 entry 都會回報精確的 jsonPath、blockKind、propertyName 與 message,讓 Agent 將 final-app validation 聚焦在受影響的 layout 或 styling decision,而不必把所有 preview limitation 視為同等相關。
elementCorrelations array 會將每個 runtime-inspectable renderer identity target 的 transient 或 safely preserved x:Name(elementName)對應到精確 blueprint jsonPath 與 blockKind。Generated names 會避開 active renderer templates 保留的所有 names。明確宣告 renderer.runtimeInspectable=false 的 block 仍會輸出 XAML,但因 element tools 無法找到其非 element root,所以不會納入 runtime correlation。Runtime diagnostics 只查詢一次 generated prefix,並依 bounded correlationLookupLimit 對 distinct non-generated correlation names(authored elementName values 與 renderer-provided root x:Name values)做 exact query。請保留預設值以避免不必要的 calls,只有在需要補齊已回報的 lookup-budget gaps 時才提高。Agent 可把結果與 get_ui_summary 配對,將 preview evidence 連回 authored node。Correlation metadata 不會寫入 blueprint 或由一般 render/apply 輸出;既有 renderer name 不會被改寫,因此 ElementName binding 仍可運作。
啟用 runtime diagnostics 時,layoutRiskSummary 會把遭裁切的 correlated elements 對應回精確 blueprint paths,不依賴 pack-specific kinds 或 slot names。Coverage 會明確回報:correlatedTargetCount 是 distinct renderer correlation names 數量、resolvedTargetCount 是與這些 names 關聯的 distinct runtime element IDs 數量、inspectedTargetCount 是其中由 get_clipping_info 成功檢查的 IDs 數量。任一 correlation 未解析或 ambiguous(同一 name 對應多個 exact records)、find_elements response 回報 searchComplete=false,或已解析 element 未受檢查時,inspectionTruncated=true;重複或無關 matches 無法掩蓋缺漏。若 name 未解析或 ambiguous,unresolvedCorrelationCount 會回報完整的 exact correlation record 數量,unresolvedCorrelations 則最多回傳 32 筆 jsonPath、blockKind、elementName、requiresActiveStateInspection 與穩定的 reason:ambiguous-authored-name、lookup-budget、runtime-match-ambiguous、runtime-not-realized 或 search-incomplete。runtime-not-realized 表示有效的 authored XAML 未出現在目前 active preview runtime state,常見原因是 container 尚未啟用、延後建立或已虛擬化;requiresActiveStateInspection=true 要求 Agent 啟用該狀態後執行 focused final-runtime inspection,不代表 authored element 遺失。若 runtime target 已解析但未受檢查,平行的 uninspectedCorrelationCount 與 uninspectedCorrelations 會回傳其精確 path、kind、name 與 elementId。兩份 bounded lists 各自具有 reportedUnresolvedCorrelationCount 或 reportedUninspectedCorrelationCount,以及 unresolvedCorrelationsTruncated 或 uninspectedCorrelationsTruncated metadata,讓 Agent 可直接檢查或精簡遺漏節點;warningsTruncated 則獨立代表另一個最多 32 筆 warnings 的輸出上限。attentionRequiredCount 會計算最多只剩 15% 可見的 sliver,以及 nearestScrollContainer.canBringTargetIntoView 不為 true 的 hidden targets;minimumVisibleRatio 是這些 attention-required warnings 中最低的比例。Warning 會帶有 visibilityClassification 與 nearestScrollContainer;後者的 nested object 包含 hasVisibleScrollBarChrome、isTargetClippedByViewport 與 canBringTargetIntoView。Summary 也會回報 clipped-element 總數、block kind、element identity、clipping source、各方向 overflow 與 runtime suggestedFix。Layout 與 ancestor-layout clip 會使用 RuntimeStructuralOverflowRisk、riskClassification="structural-overflow" 與 visibleContentRisk="unconfirmed-structural";其他未確認來源則使用 RuntimeClippingDetected、riskClassification="clipping" 與 visibleContentRisk="unconfirmed-clipping"。當 visibleContentImpact="not-determined"、severity="advisory" 且 requiresVisualConfirmation=true 時,兩者都是 evidence prompt,不是已確認的像素遺失 finding。請用 focused descendants 或 screenshot 驗證;像素與 final-app checks 都完整時,應記錄為 visually cleared,不必只為消除量測而修改 layout。由於 extension-package templates 的實際量測可能不同於 preview stubs,final built application 仍須重做 clipping checks。當第二個之後的 sibling 使用大型 leading margin 時,LargeFixedStackSpacing 只表示它可能正在 core.stack 內分配內容;若是分配用途,請優先使用 core.grid 的 Auto/star rows 或 columns。
Runtime diagnostics 也會使用 get_namescope。完成 exact lookup 後,已註冊但未出現在 active visual search 的 target 會分類為 reason="namescope-only",通常代表 inactive 或 lazy content,而不是 renderer 遺失。namescopeOnlyCorrelationCount 回報完整數量;namescopeOnlyCorrelations 最多回傳 32 筆精確 jsonPath、blockKind、elementName、elementId 與 reason,並以 reportedNamescopeOnlyCorrelationCount 和 namescopeOnlyCorrelationsTruncated 回報 bounded metadata。inspectedTargetCount 只計算 active-visual-search IDs;namescope-only targets 會納入 resolved coverage,但不會被誤稱為已完成 clipping inspection。這些已分類 exclusions 不會單獨令 inspectionTruncated=true;若其 pixels 或 behavior 重要,仍須在 final app 啟用並檢查。
repair_ui_blueprint
將 validation、render、compile 或 preview diagnostics 轉成 blueprint-first repair actions。當 validate_ui_blueprint、render_ui_blueprint 或 preview_ui_blueprint 回傳 issues 後使用。
Request options:
blueprintJson: required raw UI blueprint JSON,schemaVersion必須是wpfdevtools.ui-blueprint.v1;也可傳入 opaquedraftRef。diagnosticsJson: optional diagnostics JSON object 或 array,可使用 render 或 preview result 中的 diagnostics。targetPath: optional target XAML path suggestion,只用於 render diagnostics。此 tool 不會寫入。projectRoot: optional WPF project root。提供時,會從<projectRoot>/.wpfdevtools/packs探索 project-local packs。localAppDataRoot: optional user-global discovery root。省略時,server 會使用目前使用者的 LocalApplicationData path。
Response 包含 repairable、generatedXamlPatch=false、actionCount 與 actions。只有內容等價的重複 guidance 才會合併成一個 action;僅有相同 issueCode 與 jsonPath 不會合併不同 message、suggestion、value 或 renderer path。對於合併後的等價 guidance,source 保留第一個觀察來源,ordered sources[] 列出所有 validation、renderer 或 diagnostic contributors。Actions 會標示 repair 應落在 blueprint 或 pack renderer template contract。此 tool 不會直接 patch generated XAML。
apply_ui_blueprint
為 UI blueprint 產生 guarded apply plan。預設為 dry-run,讓 Agent 能在任何寫檔前檢查 generated view file path、required resources、package plan、authored binding requirements、targetWindowPlan 與 deterministic projectIntegrationPlan。
Request options:
blueprintJson: required raw UI blueprint JSON,schemaVersion必須是wpfdevtools.ui-blueprint.v1;也可傳入 opaquedraftRef。projectRoot: required local WPF project root,用於 path planning 與 write allowlist checks。targetPath: optionalprojectRoot相對路徑,例如MainWindow.xaml或Views/GeneratedView.xaml。即使指向projectRoot內,absolute paths 也會被拒絕。dryRun: optional boolean,預設為 true。confirmApply: optional boolean,non-dry-run 寫入前必須在檢查 dry-run plan 後設為 true。includeGeneratedXaml: optional boolean,預設為 false。Compact plan 應維持 false;只有同一份 response 必須包含完整 generated XAML 時才設 true。render_ui_blueprint仍是專用的 XAML review 路徑。targetWindowWidth與targetWindowHeight: optional target Window dimensions,以 device-independent pixels 表示,每個值範圍為 1 到 8192。需要精確維持 preview 與 final app 尺寸時,請複製已審查的preview_ui_blueprintviewportWidth與viewportHeight;省略任一值會保留該既有尺寸。localAppDataRoot: optional user-global discovery root。省略時,server 會使用目前使用者的 LocalApplicationData path。
Response 一律包含 generatedXamlLength;generatedXamlOmitted=true 代表 non-empty XAML 是刻意省略。非 dry-run 寫入需要 confirmApply=true、WPFDEVTOOLS_MCP_ALLOW_DESTRUCTIVE_TOOLS=true、WPFDEVTOOLS_MCP_ALLOW_PROJECT_WRITES=true,且 WPFDEVTOOLS_MCP_ALLOWED_PROJECT_ROOTS 必須 exact match。成功的 confirmed response 會保留依照寫入前 target 狀態執行的 file plan:新寫入檔案仍為 action="create",既有檔案仍為 action="update" 並回報 backup path。此 tool 會拒絕 projectRoot 外的路徑、更新既有 view 前建立 backup,並在重複 full-view apply 時維持唯一一個 WPFDEVTOOLS_BLUEPRINT_SOURCE header 與一組保留內容的 WPFDEVTOOLS_SAFE_SLOT envelope,且不會執行 NuGet restore。
targetPath 若是 existing App.xaml StartupUri 所指向、且 XAML root 為 Window,Composer 就能以 pack-neutral 方式 host generated non-Window root。Dry-run 會保留既有 Window shell,只以 generated content 取代原內容;pack-declared window root 仍維持 top-level。targetWindowPlan 會回報 dimensions 是已設定、保留既有值,或不適用。其他 targets 會保持 standalone views,不會宣稱已整合 startup。把 generated UI 視為 launched surface 前,請確認 application-XAML operation 包含 startup purpose。
Dry-run 的 projectIntegrationPlan 保持 pack-neutral。Operations 會列出 package references、application resources、startup selection 與 pack-declared code-behind base types 的 exact target paths、semantic purposes、current-file preconditions 與 proposed SHA-256。為避免 ungated dry-run 洩漏既有 project-file 內容,response 不會回傳完整 proposed content;plan hash 會把 reviewed semantic operations 綁定到 exact proposed content 與目前 file state。
apply_ui_project_integration
只套用最新 apply_ui_blueprint dry-run 回傳的 projectIntegrationPlan。呼叫時必須傳入相同的 raw blueprintJson 或 opaque draftRef、projectRoot、targetPath 與 pack discovery scope,再加上 reviewedPlanHash 及 confirmIntegration=true。
此 destructive tool 需要 WPFDEVTOOLS_MCP_ALLOW_DESTRUCTIVE_TOOLS=true、WPFDEVTOOLS_MCP_ALLOW_PROJECT_WRITES=true,且 WPFDEVTOOLS_MCP_ALLOWED_PROJECT_ROOTS 必須 exact match。它會在寫入前立即重新產生 plan;pack、blueprint、target 或 project file 只要有任何變更,就會回傳 IntegrationPlanChanged,且不會寫入。
只允許 plan-generated package-reference、central-package-version、project-resource、application-XAML 與 code-behind-base-type operations。Project-resource operation 可把 rendered XAML 所引用、已存在且由專案擁有的 application-local 圖片宣告為 WPF Resource。Package IDs、XAML namespaces、application dictionaries 與 base types 全部來自 selected packs,engine 不包含 control-library branch。既有檔案會使用 atomic replacement,每個 returned change 都會記錄 backupPath 與 rollbackAction。後續 operation 失敗時會 rollback 先前變更,response 也會回報 rollback 是否完成。
從 apply 到可執行應用程式
apply_ui_blueprint 只會寫入經審查的 view XAML;它不會暗中修改 project file、application resources、code-behind、ViewModel 或 startup flow。請把 response 內的 plans 當成 authoritative integration checklist:
先執行 dry apply,檢查
filePlan、requiredNuGetPackages、packageIntegrationGuidance、resourcePlan、viewModelBindingContract、behaviorIntegrationContract、targetWindowPlan與projectIntegrationPlan。只有在 project-root gates 已精確限制到目標專案後,才執行 confirmed apply。
projectIntegrationPlan.ready=true時,只有在檢查所有 operations 後,才以其 exactreviewedPlanHash呼叫apply_ui_project_integration。Stale hash 會以IntegrationPlanChanged失敗;成功的 changes 會包含backupPath與 rollback evidence。Applied plan 有變更 package references 時,response 也會回傳packageRestoreRequired=true與精簡的buildGuidance提醒。Machine-applicable plan 尚未 ready 時,才依
packageIntegrationGuidance手動處理每個 pack-declared package。偵測是 static XML best-effort;每個結果都會回報inspectionConfidence、inspectionReason、inspectedFiles與inspectionLimitations,並明確說明未 evaluate MSBuild imports 與 conditions。mode="project"時,把各projectPackageReference加入回報的 project file。因ManagePackageVersionsCentrally=true而得到mode="central"時,把 versionlessprojectPackageReference加入 project,並把對應centralPackageVersion加入Directory.Packages.props。若 central file 繼承自projectRoot外且此 project 應保持隔離,請在 project 內建立Directory.Packages.props,並使用這份完整最小 XML:<Project><PropertyGroup><ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally></PropertyGroup></Project>。接著重跑 dry-run plan;不可修改 inherited file。mode="unknown"時 package snippets 為 null;請先檢查 project,不可自行推測 integration shape。只有在 ready reviewed integration plan 未涵蓋時,才依每個 pack 的需求手動把
resourcePlanentries 加入 application resource location。該 plan 已反映 blueprint 的resourceVariantsselections 或各 pack default。請以回傳的 pack data 為準,不要假設特定 library namespace 或 dictionary。若
filePlan包含role="code-behind-integration"且 reviewed integration plan 尚未 ready,請依 action 與 pack renderer 驗證過的codeBehindBaseType,讓 generated XAMLx:Class與 code-behind 繼承相同 type。將
viewModelBindingContract.bindingRequirements.status="required"視為 implementation gate。Requirements 只會從實際 authored WPF binding expressions 擷取,不受 pack property type 影響,並依 normalized binding path 去重,同時保留每個 exact blueprint JSON usage path。Literal property value 不會建立 ViewModel requirement。請實作所有 resolved paths 並調查每個path-unresolvedentry;Composer 會明確回報composerWritesViewModelSource=false。將
behaviorIntegrationContract.status="required"視為 release gate。每個 interaction 都包含bindingStatus、rawcommandBinding與 nullable parsedcommandPath。即使 complex valid WPF binding 的 path 無法解析,它仍是 required interaction,必須在 final view 完成解析。Navigation command 會收到commandParameter,且必須更新 selected application state 與 destination content;action command 必須產生可觀察的應用程式行為,並提供合適的CanExecutepolicy。這些是 application contracts,不是自動生成的 business logic。分開執行 restore、build 與實際 application launch:
dotnet restore .\YourApp.csproj dotnet build .\YourApp.csproj --no-restore dotnet run --project .\YourApp.csproj --no-build驗證實際執行中的 app,而不只檢查 structural preview。使用
connect、get_ui_summary、focused element reads 與element_screenshot(outputMode="file")。逐一觸發behaviorIntegrationContract中的 interaction,確認 state 或 visible content 發生變化。任何 diagnostic mutation 都應搭配capture_state_snapshot、get_state_diff與restore_state_snapshot。
不要因為 generated application 可以 compile,或 button 顯示為 click-ready 就核准結果。Command-bound control 必須完成 DataContext command,且在 launched application 中驗證可觀察結果後,才算完整。