[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699XRJX78G2FGBTCR7CSH2S":3,"skill-same:01M699XRJX78G2FGBTCR7CSH2S":48},{"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":20,"linkOnly":21,"markdownContent":22,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":28,"repositoryHtmlUrl":29,"repositoryHomepageUrl":6,"ownerHtmlUrl":30,"ownerBlogUrl":31,"ownerDescription":32,"updatedAt":33,"install":34,"resources":47},"01M699XRJX78G2FGBTCR7CSH2S","app-validation",null,"Run focused checks while implementing and one final static, browser, and persistence validation sequence before calling a Universal App complete.","microsoft\u002Frayfin","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M699VK9NEV8GH0Y5JKT1G8XG",662,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frayfin\u002Fblob\u002Fmain\u002Fsamples\u002Funiversal-app\u002Ftemplate\u002F.agents\u002Fskills\u002Fapp-validation\u002FSKILL.md",[],[19],"app validation","2026-11-10 10:12:30",false,"---\nname: app-validation\ndescription: >\n  Run focused checks while implementing and one final static, browser, and\n  persistence validation sequence before calling a Universal App complete.\n---\n\n# App Validation\n\nStatic checks and browser checks prove different things.\nThe build can succeed while a chart is empty, a number is scaled incorrectly, a date shifts by a day, or a saved row disappears after reload.\n\n## Efficient cadence\n\nDuring implementation, run the smallest check that covers the behavior you changed.\nExamples include one utility spec, one query invocation, one pack validator, or one focused browser path.\nDo not restart the full validation campaign after every edit.\n\nAt completion, run each applicable gate once and in this order:\n\n1. `npm run typecheck`\n2. `npm run build`\n3. `npm run lint`\n4. `npm test`\n5. Pack validators such as `npm run validate:functions` and\n   `npm run validate:visual`\n6. Browser validation\n7. Persistence create, reload, update, and delete checks for app-owned records\n\nPack validators can distinguish a failure from an incomplete static check.\nWhen `validate:visual` reports `status: \"incomplete\"` and `ok: false`, inspect\nits `coverage` field and counts.\nIf zero schemas were checked, run `npm run validate:visual:preview` only to\npermit deployment for browser validation.\nIf some schemas were checked, the partial-coverage result already exits zero and\nneeds no preview flag.\nNeither result is a completed visual-validation gate.\nMissing or broken Vega-Lite\u002FAJV tooling and actual spec errors report `failed`\nand exit nonzero even through the preview script.\nComplete the alternate browser route only after the final report records the\nFabric route or URL checked, the runtime-built charts exercised, whether their\nloading states settled, and whether relevant console or render errors remained.\nDo not infer browser validation from a successful build, deployment, or\nvalidator exit code.\n\nFor a first deployment, run steps 1 through 5 before the remote write.\nUse the preview escape hatch only when step 5 reports `incomplete` with zero\nschemas checked, never for partial coverage or `failed`.\nDeploy after the user confirms the target, then run steps 6 and 7 against the\nFabric URL produced by that deployment.\nPre-deploy runtime checks are useful only when the installed guide and current\nenvironment already support a local or deployed app.\nThey do not replace validation of the newly deployed result.\n\n`npm run build` uses `tsc -b --noCheck`.\nIt produces the deployable frontend quickly, but it does not prove type safety.\nKeep `npm run typecheck` as a separate required gate.\nDo not race typecheck and build because both use the TypeScript build outputs.\n\nIf a gate fails, fix the cause and rerun that gate.\nAlso rerun later gates only when the fix could invalidate their result.\n\n## Where to validate the app\n\nValidate the deployed app through the direct static-hosting URL emitted by the Rayfin CLI, in a fresh standalone browser session.\nAlso check the actual Fabric or external host when the app uses embedded capabilities.\nKeep `assetAccess: protected` for the default deployment.\nSigned-out users must not reach app content, including the welcome page, and authentication or configuration failures must remain gated.\n\nChoose additional checks for the configured posture:\n\n- A public site must show its signed-out Microsoft sign-in screen in a clean\n  browser session, then establish an authenticated app session after sign-in.\n- A protected site must restore or establish the current Fabric user's session\n  without rendering authenticated content for a stale persisted identity.\n- An embedded site must complete the current host handoff before trusting a\n  persisted session.\n\nUse the documented local path only when the installed guide and environment support it.\nDo not replace a required deployed check with an HTML fetch or a successful build.\nLocal `autoLogin` intentionally skips the public signed-out screen, so it\ncannot substitute for that deployed check.\n\n## Browser checks\n\n- Confirm every region renders and all loading states settle.\n- Check the app's own console errors.\n  Ignore unrelated portal noise.\n- Trace one representative displayed value to its real source.\n  For a semantic model, invoke the exact query file through the connector and explain any transformation between source and display.\n- Check dates, currency, percentages, grids, and custom cards independently.\n- Confirm keyboard access, visible focus, readable contrast, responsive layout, and reduced-motion behavior where animation exists.\n- Exercise important interactions and verify permanent auth, permission, configuration, or query failures appear as errors rather than endless loading.\n- Keep `AuthGate` in place for public and protected hosting. Public asset access\n  does not weaken API, data, connector, or Functions authorization.\n\n## Authentication checks\n\nRun the paths applicable to the configured host posture:\n\n1. Public standalone: start signed out, verify the sign-in screen, sign in, and\n   confirm authenticated data loads.\n2. Protected standalone: reload with a valid stored session and confirm it is\n   restored; repeat with a stale session and confirm the current identity wins.\n3. Fabric or external embed: load through the real host and confirm the handoff\n   completes before authenticated content renders.\n4. Local development: confirm `rayfin login` state can establish a session,\n   stop or misconfigure the backend to verify an actionable failure, then\n   restore it and confirm recovery without weakening the gate.\n\n## Layout failures static checks miss\n\n- A chart title renders while the chart body is empty.\n- A chart container collapses because it has no definite height.\n- Spacing tokens resolve to zero or an invalid class.\n- Marks have insufficient contrast with their card background.\n- Axis and data-label styling differs accidentally between neighboring charts.\n\n## Specs\n\nWrite specs for utility functions, query factories, hooks, and components with logic worth protecting.\nUse fixtures shaped like verified query or service results.\nDo not add tests only to increase coverage.\n\n## Persistence checks\n\nSkip this section when the app reads existing data and owns no records.\n\nFor an app-owned entity:\n\n1. Create a row that should pass the default filters.\n2. Reload the page and confirm the row remains visible.\n3. Update it and confirm the returned values render safely.\n4. Delete it and confirm it stays deleted after reload.\n\nThe reload distinguishes a backend write from optimistic React state.\nStatic access-policy validation remains separate from this browser exercise.\n","# App Validation\n\nStatic checks and browser checks prove different things.\nThe build can succeed while a chart is empty, a number is scaled incorrectly, a date shifts by a day, or a saved row disappears after reload.\n\n## Efficient cadence\n\nDuring implementation, run the smallest check that covers the behavior you changed.\nExamples include one utility spec, one query invocation, one pack validator, or one focused browser path.\nDo not restart the full validation campaign after every edit.\n\nAt completion, run each applicable gate once and in this order:\n\n1. `npm run typecheck`\n2. `npm run build`\n3. `npm run lint`\n4. `npm test`\n5. Pack validators such as `npm run validate:functions` and\n   `npm run validate:visual`\n6. Browser validation\n7. Persistence create, reload, update, and delete checks for app-owned records\n\nPack validators can distinguish a failure from an incomplete static check.\nWhen `validate:visual` reports `status: \"incomplete\"` and `ok: false`, inspect\nits `coverage` field and counts.\nIf zero schemas were checked, run `npm run validate:visual:preview` only to\npermit deployment for browser validation.\nIf some schemas were checked, the partial-coverage result already exits zero and\nneeds no preview flag.\nNeither result is a completed visual-validation gate.\nMissing or broken Vega-Lite\u002FAJV tooling and actual spec errors report `failed`\nand exit nonzero even through the preview script.\nComplete the alternate browser route only after the final report records the\nFabric route or URL checked, the runtime-built charts exercised, whether their\nloading states settled, and whether relevant console or render errors remained.\nDo not infer browser validation from a successful build, deployment, or\nvalidator exit code.\n\nFor a first deployment, run steps 1 through 5 before the remote write.\nUse the preview escape hatch only when step 5 reports `incomplete` with zero\nschemas checked, never for partial coverage or `failed`.\nDeploy after the user confirms the target, then run steps 6 and 7 against the\nFabric URL produced by that deployment.\nPre-deploy runtime checks are useful only when the installed guide and current\nenvironment already support a local or deployed app.\nThey do not replace validation of the newly deployed result.\n\n`npm run build` uses `tsc -b --noCheck`.\nIt produces the deployable frontend quickly, but it does not prove type safety.\nKeep `npm run typecheck` as a separate required gate.\nDo not race typecheck and build because both use the TypeScript build outputs.\n\nIf a gate fails, fix the cause and rerun that gate.\nAlso rerun later gates only when the fix could invalidate their result.\n\n## Where to validate the app\n\nValidate the deployed app through the direct static-hosting URL emitted by the Rayfin CLI, in a fresh standalone browser session.\nAlso check the actual Fabric or external host when the app uses embedded capabilities.\nKeep `assetAccess: protected` for the default deployment.\nSigned-out users must not reach app content, including the welcome page, and authentication or configuration failures must remain gated.\n\nChoose additional checks for the configured posture:\n\n- A public site must show its signed-out Microsoft sign-in screen in a clean\n  browser session, then establish an authenticated app session after sign-in.\n- A protected site must restore or establish the current Fabric user's session\n  without rendering authenticated content for a stale persisted identity.\n- An embedded site must complete the current host handoff before trusting a\n  persisted session.\n\nUse the documented local path only when the installed guide and environment support it.\nDo not replace a required deployed check with an HTML fetch or a successful build.\nLocal `autoLogin` intentionally skips the public signed-out screen, so it\ncannot substitute for that deployed check.\n\n## Browser checks\n\n- Confirm every region renders and all loading states settle.\n- Check the app's own console errors.\n  Ignore unrelated portal noise.\n- Trace one representative displayed value to its real source.\n  For a semantic model, invoke the exact query file through the connector and explain any transformation between source and display.\n- Check dates, currency, percentages, grids, and custom cards independently.\n- Confirm keyboard access, visible focus, readable contrast, responsive layout, and reduced-motion behavior where animation exists.\n- Exercise important interactions and verify permanent auth, permission, configuration, or query failures appear as errors rather than endless loading.\n- Keep `AuthGate` in place for public and protected hosting. Public asset access\n  does not weaken API, data, connector, or Functions authorization.\n\n## Authentication checks\n\nRun the paths applicable to the configured host posture:\n\n1. Public standalone: start signed out, verify the sign-in screen, sign in, and\n   confirm authenticated data loads.\n2. Protected standalone: reload with a valid stored session and confirm it is\n   restored; repeat with a stale session and confirm the current identity wins.\n3. Fabric or external embed: load through the real host and confirm the handoff\n   completes before authenticated content renders.\n4. Local development: confirm `rayfin login` state can establish a session,\n   stop or misconfigure the backend to verify an actionable failure, then\n   restore it and confirm recovery without weakening the gate.\n\n## Layout failures static checks miss\n\n- A chart title renders while the chart body is empty.\n- A chart container collapses because it has no definite height.\n- Spacing tokens resolve to zero or an invalid class.\n- Marks have insufficient contrast with their card background.\n- Axis and data-label styling differs accidentally between neighboring charts.\n\n## Specs\n\nWrite specs for utility functions, query factories, hooks, and components with logic worth protecting.\nUse fixtures shaped like verified query or service results.\nDo not add tests only to increase coverage.\n\n## Persistence checks\n\nSkip this section when the app reads existing data and owns no records.\n\nFor an app-owned entity:\n\n1. Create a row that should pass the default filters.\n2. Reload the page and confirm the row remains visible.\n3. Update it and confirm the returned values render safely.\n4. Delete it and confirm it stays deleted after reload.\n\nThe reload distinguishes a backend write from optimistic React state.\nStatic access-policy validation remains separate from this browser exercise.\n",{"name":5,"description":7},"main","0979439a7a0806abd0ee48c2619b37f297ae1324","samples\u002Funiversal-app\u002Ftemplate\u002F.agents\u002Fskills\u002Fapp-validation",77,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frayfin","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-12 01:21:10",{"source":8,"skillName":5,"commands":35,"prompt":45,"zipAvailable":46},[36,39,42],{"tool":37,"command":38},"npx","npx skills add microsoft\u002Frayfin --skill app-validation",{"tool":40,"command":41},"bunx","bunx skills add microsoft\u002Frayfin --skill app-validation",{"tool":43,"command":44},"pnpm","pnpm dlx skills add microsoft\u002Frayfin --skill app-validation","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frayfin\u002Fblob\u002Fmain\u002Fsamples\u002Funiversal-app\u002Ftemplate\u002F.agents\u002Fskills\u002Fapp-validation\u002FSKILL.md",true,[],[49,62,82,91,110,118],{"skillNo":50,"name":51,"nameZh":6,"description":52,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":53,"categories":54,"keywords":55,"publishedAt":20},"01M699YEY2QDVPKTZS3HR9AX84","rayfin-getting-started","Use when starting or creating a NEW Rayfin app, or when a Rayfin task comes up and you are not yet inside a Rayfin project. Gets you into a project with the Rayfin CLI, then hands off to the authoritative, version-locked in-project rayfin skill\u002Fdocs that own all in-project work. Triggers: build a Rayfin app, start a Rayfin project, create a new Rayfin app, create-rayfin, npm create @microsoft\u002Frayfin, rayfin init, scaffold rayfin, rayfin CLI, rayfin template, universal app, awesome-rayfin gallery, get started with Rayfin","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frayfin\u002Fblob\u002Fmain\u002Fskills\u002Frayfin-getting-started\u002FSKILL.md",[],[56,57,58,59,9,60,61],"rayfin getting started","rayfin","scaffold","init","docs","cli",{"skillNo":63,"name":64,"nameZh":6,"description":65,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":66,"categories":67,"keywords":78,"publishedAt":20},"01M699YCN4ZDW2AMDP4NVJ2QGC","visuals","Use when user wants to incorporate charts, graphs, data grid,  or other visual representations of data into their project. Use VegaVisual and DataGrid components to create these visuals,  utilizing the shared DataTable input, formatting, theme, and interactivity. Covers the onInteraction selection\u002Fclick events host apps consume, named multi-table data input for layered overlays and reference lines, and Vega-Lite native selections. Triggers: chart, graph, plot, dashboard, KPI, metric, trend, scorecard, data grid, visualize.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frayfin\u002Fblob\u002Fmain\u002Fsamples\u002Funiversal-app\u002Ftemplate\u002F.agents\u002Fskills\u002Fvisuals\u002FSKILL.md",[68,73],{"categoryNo":69,"categoryName":70,"taxonomyType":71,"taxonomyTypeDesc":72},"01JBSEEDCAT000000000000013","分析与可视化","SCENARIO","使用场景",{"categoryNo":74,"categoryName":75,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[64,79,80,81],"components","dashboard","visualize",{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":20},"01M699YBEP146MJZJNN8YEBZ2G","schema-discovery","Explore Power BI semantic model schemas using DAX INFO functions. Progressive metadata discovery strategy, scope estimation, and narrowing techniques for tables, columns, measures, and relationships.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frayfin\u002Fblob\u002Fmain\u002Fsamples\u002Funiversal-app\u002Ftemplate\u002F.agents\u002Fskills\u002Fschema-discovery\u002FSKILL.md",[],[89,90],"schema discovery","dax",{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":106,"publishedAt":20},"01M699Y9E80WYFKD1S4MT4B1CS","query-design","Separates DAX data-fetching from TypeScript presentation. Guides when to use  DAX vs. TypeScript vs. Vega-Lite for aggregation, total rows, FORMAT(), SELECTCOLUMNS,  BLANK handling, filtering, multi-grain queries, cross-filtering and cross-highlight subset\u002Foverlay queries, and format strings.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frayfin\u002Fblob\u002Fmain\u002Fsamples\u002Funiversal-app\u002Ftemplate\u002F.agents\u002Fskills\u002Fquery-design\u002FSKILL.md",[97,100,103],{"categoryNo":98,"categoryName":99,"taxonomyType":71,"taxonomyTypeDesc":72},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":101,"categoryName":102,"taxonomyType":71,"taxonomyTypeDesc":72},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":104,"categoryName":105,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000032","设计师",[107,108,90,109],"query design","design","typescript",{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":116,"publishedAt":20},"01M699Y7CKZ55QSYFE827RRVJE","functions-capability","Apply and build the Universal App functions capability. Use for trusted server-side logic, secrets, external APIs, custom model endpoints, published Fabric data agents, webhooks, or privileged operations.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frayfin\u002Fblob\u002Fmain\u002Fsamples\u002Funiversal-app\u002Ftemplate\u002F.agents\u002Fskills\u002Ffunctions-capability\u002FSKILL.md",[],[117],"functions capability",{"skillNo":119,"name":120,"nameZh":6,"description":121,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":20},"01M699Y5R87YE620T78Z30KQSA","fabric-sdk","How to query Fabric data from a running app through the Rayfin connectors client. Use getRayfinClient().connectors.\u003Cname>.executeQuery to run DAX against a semantic model, and toQueryResult to normalize the response.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frayfin\u002Fblob\u002Fmain\u002Fsamples\u002Funiversal-app\u002Ftemplate\u002F.agents\u002Fskills\u002Ffabric-sdk\u002FSKILL.md",[],[125,126,90,127,57,128],"sdk","fabric sdk","rayfin connectors","connectors"]