[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M69APVKEAZD650TFNCT9WMN1":3,"skill-same:01M69APVKEAZD650TFNCT9WMN1":58},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":29,"linkOnly":30,"markdownContent":31,"markdownBody":32,"frontMatter":33,"refName":34,"commitSha":35,"skillDirectory":36,"forksCount":37,"repositoryHtmlUrl":38,"repositoryHomepageUrl":39,"ownerHtmlUrl":40,"ownerBlogUrl":41,"ownerDescription":42,"updatedAt":43,"install":44,"resources":57},"01M69APVKEAZD650TFNCT9WMN1","perf",null,"Speed and memory performance rules for Rust crates, the Node addon, webui-framework, and webui-delivery.","microsoft\u002Fwebui","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M69APCAY31B400ERZA9BVA20",102,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fwebui\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fperf\u002FSKILL.md",[],[5,19,20,21,22,23,24,25,26,27,28],"memory","performance","rust","framework","Rules","node","webui","delivery","speed","for","2026-11-10 10:12:30",false,"---\nname: perf\ndescription: Speed and memory performance rules for Rust crates, the Node addon, webui-framework, and webui-delivery.\n---\n\n# Performance\n\nWebUI's value proposition is speed and low memory usage. Every change to core Rust crates, `@microsoft\u002Fwebui-framework`, or `@microsoft\u002Fwebui-delivery` must be evaluated through two lenses: **throughput** (how fast) and **memory** (how little).\n\nServer memory is not cheap. Client memory is not unlimited. Every allocation that can be avoided is a win on both sides.\n\nUse this skill when modifying any performance-sensitive code across the stack.\n\n## Rust - speed rules\n\nThese apply to `webui-handler`, `webui-state`, `webui-expressions`, `webui-parser`, `webui-protocol`, `webui-ffi`, and `webui-node`.\n\n1. **No `format!()` in writer output.** Use sequential `writer.write()` calls. `format!` allocates a temporary `String` every invocation.\n2. **No `.to_string()` on `Cow`.** Write `Cow\u003Cstr>` directly to avoid defeating zero-copy.\n3. **No `collect::\u003CVec\u003C_>>()` on splits.** Iterate `path.split('.')` directly. Collecting allocates a `Vec` for sequential access.\n4. **No redundant scans.** Use `first_part.len() == path.len()` instead of `path.contains('.')`.\n5. **No `String::from(ch)` in escape loops.** Use `ch.encode_utf8(&mut buf)` with a `[u8; 4]` stack buffer, or batch contiguous safe chars into a single write.\n6. **No `format!` in hex parsing.** Use direct arithmetic (`(hi_nibble \u003C\u003C 4) | lo_nibble`) instead of `u8::from_str_radix(&format!(...))`.\n7. **No per-request template re-parsing.** Pre-parse at protocol load time and reuse.\n8. **No silent `unwrap_or` defaults.** If `binding_stack.pop()` returns `None`, that's a protocol error - propagate it, don't mask it.\n9. **Keep cold error\u002Fdiagnostic construction off the hot path.** Mark error builders `#[cold]`\u002F`#[inline(never)]` so they don't inline into hot functions and perturb their code layout. Adding cold error code with **no** hot-path work has regressed parse benches ~4-5% purely via layout - keep per-element fast-paths inlinable and push the cold fallback out-of-line. See `skills\u002Fdiagnostics\u002FSKILL.md` §7.\n\n## Rust - memory rules\n\n1. **No cloning large state trees.** Use `evaluate_with_resolver` with a closure. Cloning duplicates the entire JSON tree in memory.\n2. **No cloning HashMaps for scope.** Save\u002Frestore only the overwritten key on loop iteration. A HashMap clone copies every entry.\n3. **No cloning `String` values for read-only access.** Use `s.as_str()` for `Value::String` branches; only create owned strings for `Number`\u002F`Bool` via a scratch buffer or `Cow`.\n4. **Pre-allocate buffers.** Use `Vec::with_capacity` \u002F `String::with_capacity` when size is known or estimable. For HTML output, 4096 bytes is a reasonable starting point.\n5. **Prefer `&str` and slices over owned types.** Pass by reference when the callee only reads. Move clone decisions to the caller.\n6. **Use `Cow\u003C'_, str>` when a value is sometimes borrowed, sometimes owned.** Avoids unconditional allocation.\n7. **No deep-cloning protocol or state per request.** Use `Arc\u003CT>` with clone-on-write or snapshot swapping.\n8. **Cap memory for untrusted inputs.** File reads during discovery must have size limits. A 100MB HTML file should not cause OOM.\n\n## TypeScript - `@microsoft\u002Fwebui-framework` rules\n\nThese apply to `packages\u002Fwebui-framework` (the client-side Web Component runtime).\n\n### Speed\n\n1. **Single-pass hydration.** The framework walks the DOM once to connect all bindings. No multi-pass scanning.\n2. **Path-indexed targeted updates.** When an `@observable` changes, only bindings referencing that property are visited - not the entire template.\n3. **DOM cloning over innerHTML.** Use `cloneNode(true)` from cached template fragments. Never use `innerHTML` for component creation.\n4. **Direct event listeners.** Attach `@event` bindings to the bound element, never a shared render root. `$wireEvents` runs once per block instance, so delegating stacks one listener per block on the same node and fires all of them per dispatch — O(N) for no reduction in listener count.\n5. **Microtask coalescing.** Multiple property changes within the same synchronous block batch into a single DOM update via `queueMicrotask`.\n6. **Cursor-based repeat reconciliation.** `\u003Cfor>` block updates use a diff algorithm that only calls `insertBefore` on nodes that actually moved. Append\u002Fprepend\u002Fremove are O(1).\n7. **No `for..in` on objects.** Use `Object.keys()` with an indexed `for` loop — faster and prototype-safe without needing `Object.hasOwn`. Applies to `setState`, `setInitialState`, and any code iterating user-provided objects.\n\n### Memory\n\n1. **No framework in the GC.** Minimize object allocations during reactive updates. Reuse binding objects, don't recreate them.\n2. **Template cache is `WeakMap`-keyed.** Parsed template DOMs are cached per metadata object. When metadata is released (e.g., via `Router.gc()`), the cache entry becomes GC-eligible.\n3. **No per-update array allocations.** Avoid `.filter()`, `.map()`, `.slice()` in the update hot path. Use index-based iteration.\n4. **Strip SSR markers after hydration.** Comment nodes used as markers are removed from the DOM once wiring is complete - they don't persist as memory overhead.\n5. **Scope frames are stack-allocated.** `\u003Cfor>` loop item variables use a linked-list scope chain, not cloned Maps or Objects.\n\n## TypeScript - `@microsoft\u002Fwebui-delivery` rules\n\nThese apply to `packages\u002Fwebui-delivery` (the client-side SPA router).\n\n### Speed\n\n1. **Server does route matching.** The client does not re-match routes. The server returns the matched `chain` array; the client diffs old vs new and mounts only changed components.\n2. **Lazy loading via dynamic import.** Route component JS is fetched only on first navigation to that route.\n3. **Chain diffing, not full remount.** Navigating between sibling routes preserves parent components. Only the changed level is remounted.\n4. **No `for..in` on objects.** Use `Object.keys()` with an indexed `for` loop. `for..in` walks the prototype chain (slow) and requires an `Object.hasOwn` guard to be safe — `Object.keys` is both faster and prototype-safe in one call:\n   ```typescript\n   \u002F\u002F ✗ Bad: slow, prototype-unsafe without guard\n   for (const key in obj) { ... }\n\n   \u002F\u002F ✗ Still bad: correct but slower than Object.keys\n   for (const key in obj) {\n     if (Object.hasOwn(obj, key)) { ... }\n   }\n\n   \u002F\u002F ✓ Good: fast, prototype-safe, no guard needed\n   const keys = Object.keys(obj);\n   for (let i = 0; i \u003C keys.length; i++) { ... }\n   ```\n\n### Memory\n\n1. **Release unused templates.** `Router.gc()` clears cached component templates for routes the user hasn't visited recently. Active route components are never released.\n2. **Inventory bitmask prevents duplicate downloads.** The server tracks which component templates the client already has via a bitmask. Re-navigation never re-sends templates.\n3. **Minimal state per navigation.** Route-scoped state means the JSON partial contains only what the active route needs, not the full app state.\n\n## Measuring\n\n### Server benchmarks\n\n```bash\ncargo bench -p microsoft-webui --bench contact_book_bench          # full run\ncargo bench -p microsoft-webui --bench contact_book_bench -- --test # quick validation\ncargo bench -p microsoft-webui --bench server_request_bench         # high-level request helper\ncargo xtask bench all                                               # all Rust crates\ncargo xtask bench node-addon                                        # Node\u002FV8\u002FN-API boundary\n```\n\nCompare **Render\u002F1000 P50** before and after. For Node changes, save with\n`--save-baseline before` and compare with `--baseline before`. Verify output\n**Bytes** is unchanged (same HTML = correct behavior).\n\n### Client performance\n\n```typescript\nwindow.addEventListener('webui:hydration-complete', () => {\n  for (const entry of performance.getEntriesByType('measure')) {\n    if (entry.name.startsWith('webui:hydrate:')) {\n      console.log(`${entry.name}: ${entry.duration.toFixed(1)}ms`);\n    }\n  }\n});\n```\n\n### What to report\n\nWhen making a performance-related change, report:\n- **Before\u002Fafter benchmark numbers** (P50 latency, throughput)\n- **Allocation count delta** if measurable\n- **Output size** unchanged (proves correctness)\n- **Memory profile** for memory-related changes (heap snapshots, RSS delta)\n","# Performance\n\nWebUI's value proposition is speed and low memory usage. Every change to core Rust crates, `@microsoft\u002Fwebui-framework`, or `@microsoft\u002Fwebui-delivery` must be evaluated through two lenses: **throughput** (how fast) and **memory** (how little).\n\nServer memory is not cheap. Client memory is not unlimited. Every allocation that can be avoided is a win on both sides.\n\nUse this skill when modifying any performance-sensitive code across the stack.\n\n## Rust - speed rules\n\nThese apply to `webui-handler`, `webui-state`, `webui-expressions`, `webui-parser`, `webui-protocol`, `webui-ffi`, and `webui-node`.\n\n1. **No `format!()` in writer output.** Use sequential `writer.write()` calls. `format!` allocates a temporary `String` every invocation.\n2. **No `.to_string()` on `Cow`.** Write `Cow\u003Cstr>` directly to avoid defeating zero-copy.\n3. **No `collect::\u003CVec\u003C_>>()` on splits.** Iterate `path.split('.')` directly. Collecting allocates a `Vec` for sequential access.\n4. **No redundant scans.** Use `first_part.len() == path.len()` instead of `path.contains('.')`.\n5. **No `String::from(ch)` in escape loops.** Use `ch.encode_utf8(&mut buf)` with a `[u8; 4]` stack buffer, or batch contiguous safe chars into a single write.\n6. **No `format!` in hex parsing.** Use direct arithmetic (`(hi_nibble \u003C\u003C 4) | lo_nibble`) instead of `u8::from_str_radix(&format!(...))`.\n7. **No per-request template re-parsing.** Pre-parse at protocol load time and reuse.\n8. **No silent `unwrap_or` defaults.** If `binding_stack.pop()` returns `None`, that's a protocol error - propagate it, don't mask it.\n9. **Keep cold error\u002Fdiagnostic construction off the hot path.** Mark error builders `#[cold]`\u002F`#[inline(never)]` so they don't inline into hot functions and perturb their code layout. Adding cold error code with **no** hot-path work has regressed parse benches ~4-5% purely via layout - keep per-element fast-paths inlinable and push the cold fallback out-of-line. See `skills\u002Fdiagnostics\u002FSKILL.md` §7.\n\n## Rust - memory rules\n\n1. **No cloning large state trees.** Use `evaluate_with_resolver` with a closure. Cloning duplicates the entire JSON tree in memory.\n2. **No cloning HashMaps for scope.** Save\u002Frestore only the overwritten key on loop iteration. A HashMap clone copies every entry.\n3. **No cloning `String` values for read-only access.** Use `s.as_str()` for `Value::String` branches; only create owned strings for `Number`\u002F`Bool` via a scratch buffer or `Cow`.\n4. **Pre-allocate buffers.** Use `Vec::with_capacity` \u002F `String::with_capacity` when size is known or estimable. For HTML output, 4096 bytes is a reasonable starting point.\n5. **Prefer `&str` and slices over owned types.** Pass by reference when the callee only reads. Move clone decisions to the caller.\n6. **Use `Cow\u003C'_, str>` when a value is sometimes borrowed, sometimes owned.** Avoids unconditional allocation.\n7. **No deep-cloning protocol or state per request.** Use `Arc\u003CT>` with clone-on-write or snapshot swapping.\n8. **Cap memory for untrusted inputs.** File reads during discovery must have size limits. A 100MB HTML file should not cause OOM.\n\n## TypeScript - `@microsoft\u002Fwebui-framework` rules\n\nThese apply to `packages\u002Fwebui-framework` (the client-side Web Component runtime).\n\n### Speed\n\n1. **Single-pass hydration.** The framework walks the DOM once to connect all bindings. No multi-pass scanning.\n2. **Path-indexed targeted updates.** When an `@observable` changes, only bindings referencing that property are visited - not the entire template.\n3. **DOM cloning over innerHTML.** Use `cloneNode(true)` from cached template fragments. Never use `innerHTML` for component creation.\n4. **Direct event listeners.** Attach `@event` bindings to the bound element, never a shared render root. `$wireEvents` runs once per block instance, so delegating stacks one listener per block on the same node and fires all of them per dispatch — O(N) for no reduction in listener count.\n5. **Microtask coalescing.** Multiple property changes within the same synchronous block batch into a single DOM update via `queueMicrotask`.\n6. **Cursor-based repeat reconciliation.** `\u003Cfor>` block updates use a diff algorithm that only calls `insertBefore` on nodes that actually moved. Append\u002Fprepend\u002Fremove are O(1).\n7. **No `for..in` on objects.** Use `Object.keys()` with an indexed `for` loop — faster and prototype-safe without needing `Object.hasOwn`. Applies to `setState`, `setInitialState`, and any code iterating user-provided objects.\n\n### Memory\n\n1. **No framework in the GC.** Minimize object allocations during reactive updates. Reuse binding objects, don't recreate them.\n2. **Template cache is `WeakMap`-keyed.** Parsed template DOMs are cached per metadata object. When metadata is released (e.g., via `Router.gc()`), the cache entry becomes GC-eligible.\n3. **No per-update array allocations.** Avoid `.filter()`, `.map()`, `.slice()` in the update hot path. Use index-based iteration.\n4. **Strip SSR markers after hydration.** Comment nodes used as markers are removed from the DOM once wiring is complete - they don't persist as memory overhead.\n5. **Scope frames are stack-allocated.** `\u003Cfor>` loop item variables use a linked-list scope chain, not cloned Maps or Objects.\n\n## TypeScript - `@microsoft\u002Fwebui-delivery` rules\n\nThese apply to `packages\u002Fwebui-delivery` (the client-side SPA router).\n\n### Speed\n\n1. **Server does route matching.** The client does not re-match routes. The server returns the matched `chain` array; the client diffs old vs new and mounts only changed components.\n2. **Lazy loading via dynamic import.** Route component JS is fetched only on first navigation to that route.\n3. **Chain diffing, not full remount.** Navigating between sibling routes preserves parent components. Only the changed level is remounted.\n4. **No `for..in` on objects.** Use `Object.keys()` with an indexed `for` loop. `for..in` walks the prototype chain (slow) and requires an `Object.hasOwn` guard to be safe — `Object.keys` is both faster and prototype-safe in one call:\n   ```typescript\n   \u002F\u002F ✗ Bad: slow, prototype-unsafe without guard\n   for (const key in obj) { ... }\n\n   \u002F\u002F ✗ Still bad: correct but slower than Object.keys\n   for (const key in obj) {\n     if (Object.hasOwn(obj, key)) { ... }\n   }\n\n   \u002F\u002F ✓ Good: fast, prototype-safe, no guard needed\n   const keys = Object.keys(obj);\n   for (let i = 0; i \u003C keys.length; i++) { ... }\n   ```\n\n### Memory\n\n1. **Release unused templates.** `Router.gc()` clears cached component templates for routes the user hasn't visited recently. Active route components are never released.\n2. **Inventory bitmask prevents duplicate downloads.** The server tracks which component templates the client already has via a bitmask. Re-navigation never re-sends templates.\n3. **Minimal state per navigation.** Route-scoped state means the JSON partial contains only what the active route needs, not the full app state.\n\n## Measuring\n\n### Server benchmarks\n\n```bash\ncargo bench -p microsoft-webui --bench contact_book_bench          # full run\ncargo bench -p microsoft-webui --bench contact_book_bench -- --test # quick validation\ncargo bench -p microsoft-webui --bench server_request_bench         # high-level request helper\ncargo xtask bench all                                               # all Rust crates\ncargo xtask bench node-addon                                        # Node\u002FV8\u002FN-API boundary\n```\n\nCompare **Render\u002F1000 P50** before and after. For Node changes, save with\n`--save-baseline before` and compare with `--baseline before`. Verify output\n**Bytes** is unchanged (same HTML = correct behavior).\n\n### Client performance\n\n```typescript\nwindow.addEventListener('webui:hydration-complete', () => {\n  for (const entry of performance.getEntriesByType('measure')) {\n    if (entry.name.startsWith('webui:hydrate:')) {\n      console.log(`${entry.name}: ${entry.duration.toFixed(1)}ms`);\n    }\n  }\n});\n```\n\n### What to report\n\nWhen making a performance-related change, report:\n- **Before\u002Fafter benchmark numbers** (P50 latency, throughput)\n- **Allocation count delta** if measurable\n- **Output size** unchanged (proves correctness)\n- **Memory profile** for memory-related changes (heap snapshots, RSS delta)\n",{"name":5,"description":7},"main","ce33e738b770d63c0e4144feb5072212d38ce1b9",".github\u002Fskills\u002Fperf",25,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fwebui","https:\u002F\u002Fmicrosoft.github.io\u002Fwebui\u002F","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-14 02:49:18",{"source":8,"skillName":5,"commands":45,"prompt":55,"zipAvailable":56},[46,49,52],{"tool":47,"command":48},"npx","npx skills add microsoft\u002Fwebui --skill perf",{"tool":50,"command":51},"bunx","bunx skills add microsoft\u002Fwebui --skill perf",{"tool":53,"command":54},"pnpm","pnpm dlx skills add microsoft\u002Fwebui --skill perf","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fwebui\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fperf\u002FSKILL.md",true,[],[59,77,96,117,134,146],{"skillNo":60,"name":61,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":65,"publishedAt":29},"01M69AQ6PSR5AXD1W7K822EJEJ","webui-reference","Use when writing or reviewing WebUI application or framework code. Load the application's installed reference or the WebUI source checkout's canonical reference.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fwebui\u002Fblob\u002Fmain\u002Fai\u002FSKILL.md",[],[66,25,67,68,69,70,71,72,73,74,75,76,22],"webui reference","reference","when","writing","checkout","canonical","use","load","source","code","application",{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":29},"01M69AQ4B9AXF52SB3A0NVW4QT","webui-dev","Build interactive WebUI apps with compiled-template hydration, template syntax, component patterns, and CLI usage.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fwebui\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fwebui-dev\u002FSKILL.md",[],[84,25,85,86,87,88,89,90,91,92,93,94,95],"dev","webui dev","cli","component","usage","apps","interactive","with","build","template","syntax","patterns",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":107,"publishedAt":29},"01M69AQ21S81FTXJF5716X3JPB","testing","Test patterns, fixture structure, and when to use E2E vs unit tests.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fwebui\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Ftesting\u002FSKILL.md",[102],{"categoryNo":103,"categoryName":104,"taxonomyType":105,"taxonomyTypeDesc":106},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[98,68,95,108,109,110,111,112,113,114,115,72,116],"when to use","test patterns","test","unit tests","unit","fixture","tests","e2e","structure",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"publishedAt":29},"01M69APZVHA8B3AM0S1WJ1T5BC","quality-gate","Run before every commit or push: formatting, linting, tests, dependency audits, builds, and docs.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fwebui\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fquality-gate\u002FSKILL.md",[],[124,125,126,127,128,129,130,131,132,114,133],"gate","quality","quality gate","push","docs","commit","linting","dependency","run","formatting",{"skillNo":135,"name":136,"nameZh":6,"description":137,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":138,"categories":139,"keywords":140,"publishedAt":29},"01M69APXXGESWZ75E8B5PKWC8H","pr","Guidance for branch naming, commit messages, and PR titles.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fwebui\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr\u002FSKILL.md",[],[136,129,141,28,142,143,144,145],"branch","messages","naming","guidance","commit messages",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":155,"publishedAt":29},"01M69APS2RQFC34SYZED5K2MHD","docs-sync","Keep user-facing docs current and DESIGN aligned with architectural changes.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fwebui\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fdocs-sync\u002FSKILL.md",[152],{"categoryNo":153,"categoryName":154,"taxonomyType":105,"taxonomyTypeDesc":106},"01JBSEEDCAT000000000000015","视觉设计",[128,156,157,158,159,91,160,161],"docs sync","sync","design","keep","changes","user"]