[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M69AH2VM3FMZAQMTS29SD9XT":3,"skill-same:01M69AH2VM3FMZAQMTS29SD9XT":74},{"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":23,"publishedAt":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":50,"commitSha":51,"skillDirectory":52,"forksCount":53,"repositoryHtmlUrl":54,"repositoryHomepageUrl":55,"ownerHtmlUrl":56,"ownerBlogUrl":57,"ownerDescription":58,"updatedAt":59,"install":60,"resources":73},"01M69AH2VM3FMZAQMTS29SD9XT","test-driven-development",null,"Use when implementing any feature or bugfix, before writing implementation code - write the test first, watch it fail, write minimal code to pass; ensures tests actually verify behavior by requiring failure first","microsoft\u002FFluidFramework","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M69AG0BQKNGBJQ5YNG09HXXW",4948,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FFluidFramework\u002Fblob\u002Fmain\u002F.agency\u002Fplugins\u002Fnori\u002Fskills\u002Ftest-driven-development\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"test","test driven development","development","driven","when","writing","implementing","it","bugfix","watch","feature","tests","implementation","minimal","use","behavior","write","verify behavior","verify","first","code","2026-11-10 10:12:30",false,"---\nname: test-driven-development\ndescription: Use when implementing any feature or bugfix, before writing implementation code - write the test first, watch it fail, write minimal code to pass; ensures tests actually verify behavior by requiring failure first\n---\n\n\u003Crequired>\n*CRITICAL* Add the following steps to your Todo list using TodoWrite:\n\n1. Write failing tests (RED phase)\n\n2. Create a subagent using the nori-task-runner to evaluate test quality.\n- Ensure that each test does not just test mocks. If it does, remove the test and try again.\n- Ensure each test does not test implementation detail. If it does, rewrite the test so that it tests boundary behavior.\n- Ensure each test does not test data structure format or types. If it does, remove the test and try again.\n- Ensure each test does not test for removed behavior. For example, if some behavior has been deprecated, do not write a test that simply confirms the behavior no longer works.\n- Evaluate if the test treats the interior of the test boundary as a blackbox. You should not know anything about interior variables, function calls, or control flow.\n\n3. Verify the test fails due to the behavior of the application, and NOT due to the test.\n\u003Csystem-reminder>If you have more than one test that you need to write, you should write all of them before moving to the GREEN phase.\u003C\u002Fsystem-reminder>\n4. Write the minimal amount of code necessary to make the test pass (GREEN phase)\n5. Verify the test now passes due to the behavior of the application.\n    - If you go through three loops without making progress, switch to running `.agency\u002Fplugins\u002Fnori\u002Fskills\u002Fcreating-debug-tests-and-iterating`\n6. Refactor the code to clean it up.\n7. Verify tests still pass.\n\u003C\u002Frequired>\n\n## RED - Write Failing Test\n\nWrite one minimal test showing what should happen.\n\n\u003Cgood-example>\n\n```typescript\ntest('retries failed operations 3 times', async () => {\n  let attempts = 0;\n  const operation = () => {\n    attempts++;\n    if (attempts \u003C 3) throw new Error('fail');\n    return 'success';\n  };\n\n  const result = await foobar.retryOperation(operation);\n\n  expect(result).toBe('success');\n  expect(attempts).toBe(3);\n});\n```\n\nClear name, tests real behavior, one thing. Note that the tested operation is\nimported -- this is a STRONG sign that this is testing something real.\n\n\u003C\u002Fgood-example>\n\n\u003Cbad-example>\n\n```typescript\ntest('retry works', async () => {\n  const mock = jest\n    .fn()\n    .mockRejectedValueOnce(new Error())\n    .mockRejectedValueOnce(new Error())\n    .mockResolvedValueOnce('success');\n  await retryOperation(mock);\n  expect(mock).toHaveBeenCalledTimes(3);\n});\n```\n\nVague name, tests mock not code\n\u003C\u002Fbad-example>\n\n## Verify RED - Watch It Fail\n\n```bash\nnpm test path\u002Fto\u002Ftest.test.ts\n```\n\nConfirm:\n\n- Test fails (not errors)\n- Failure message is expected\n- Fails because feature missing (not typos)\n\n## GREEN - Minimal Code\n\nWrite simplest code to pass the test.\n\n\u003Cgood-example>\n```typescript\nasync function retryOperation\u003CT>(fn: () => Promise\u003CT>): Promise\u003CT> {\n  for (let i = 0; i \u003C 3; i++) {\n    try {\n      return await fn();\n    } catch (e) {\n      if (i === 2) throw e;\n    }\n  }\n  throw new Error('unreachable');\n}\n```\nJust enough to pass\n\u003C\u002Fgood-example>\n\n\u003Cbad-example>\n```typescript\nasync function retryOperation\u003CT>(\n  fn: () => Promise\u003CT>,\n  options?: {\n    maxRetries?: number;\n    backoff?: 'linear' | 'exponential';\n    onRetry?: (attempt: number) => void;\n  }\n): Promise\u003CT> {\n  \u002F\u002F YAGNI\n}\n```\nOver-engineered\n\u003C\u002Fbad-example>\n\nDon't add features, refactor other code, or \"improve\" beyond the test.\n\n## Verify GREEN - Watch It Pass\n\n```bash\nnpm test path\u002Fto\u002Ftest.test.ts\n```\n\nConfirm:\n\n- Test passes\n- Other tests still pass\n- Output pristine (no errors, warnings)\n\n## REFACTOR - Clean Up\n\nAfter green only:\n\n- Remove duplication\n- Improve names\n- Extract helpers\n\nKeep tests green. Do not add behavior.\n","\u003Crequired>\n*CRITICAL* Add the following steps to your Todo list using TodoWrite:\n\n1. Write failing tests (RED phase)\n\n2. Create a subagent using the nori-task-runner to evaluate test quality.\n- Ensure that each test does not just test mocks. If it does, remove the test and try again.\n- Ensure each test does not test implementation detail. If it does, rewrite the test so that it tests boundary behavior.\n- Ensure each test does not test data structure format or types. If it does, remove the test and try again.\n- Ensure each test does not test for removed behavior. For example, if some behavior has been deprecated, do not write a test that simply confirms the behavior no longer works.\n- Evaluate if the test treats the interior of the test boundary as a blackbox. You should not know anything about interior variables, function calls, or control flow.\n\n3. Verify the test fails due to the behavior of the application, and NOT due to the test.\n\u003Csystem-reminder>If you have more than one test that you need to write, you should write all of them before moving to the GREEN phase.\u003C\u002Fsystem-reminder>\n4. Write the minimal amount of code necessary to make the test pass (GREEN phase)\n5. Verify the test now passes due to the behavior of the application.\n    - If you go through three loops without making progress, switch to running `.agency\u002Fplugins\u002Fnori\u002Fskills\u002Fcreating-debug-tests-and-iterating`\n6. Refactor the code to clean it up.\n7. Verify tests still pass.\n\u003C\u002Frequired>\n\n## RED - Write Failing Test\n\nWrite one minimal test showing what should happen.\n\n\u003Cgood-example>\n\n```typescript\ntest('retries failed operations 3 times', async () => {\n  let attempts = 0;\n  const operation = () => {\n    attempts++;\n    if (attempts \u003C 3) throw new Error('fail');\n    return 'success';\n  };\n\n  const result = await foobar.retryOperation(operation);\n\n  expect(result).toBe('success');\n  expect(attempts).toBe(3);\n});\n```\n\nClear name, tests real behavior, one thing. Note that the tested operation is\nimported -- this is a STRONG sign that this is testing something real.\n\n\u003C\u002Fgood-example>\n\n\u003Cbad-example>\n\n```typescript\ntest('retry works', async () => {\n  const mock = jest\n    .fn()\n    .mockRejectedValueOnce(new Error())\n    .mockRejectedValueOnce(new Error())\n    .mockResolvedValueOnce('success');\n  await retryOperation(mock);\n  expect(mock).toHaveBeenCalledTimes(3);\n});\n```\n\nVague name, tests mock not code\n\u003C\u002Fbad-example>\n\n## Verify RED - Watch It Fail\n\n```bash\nnpm test path\u002Fto\u002Ftest.test.ts\n```\n\nConfirm:\n\n- Test fails (not errors)\n- Failure message is expected\n- Fails because feature missing (not typos)\n\n## GREEN - Minimal Code\n\nWrite simplest code to pass the test.\n\n\u003Cgood-example>\n```typescript\nasync function retryOperation\u003CT>(fn: () => Promise\u003CT>): Promise\u003CT> {\n  for (let i = 0; i \u003C 3; i++) {\n    try {\n      return await fn();\n    } catch (e) {\n      if (i === 2) throw e;\n    }\n  }\n  throw new Error('unreachable');\n}\n```\nJust enough to pass\n\u003C\u002Fgood-example>\n\n\u003Cbad-example>\n```typescript\nasync function retryOperation\u003CT>(\n  fn: () => Promise\u003CT>,\n  options?: {\n    maxRetries?: number;\n    backoff?: 'linear' | 'exponential';\n    onRetry?: (attempt: number) => void;\n  }\n): Promise\u003CT> {\n  \u002F\u002F YAGNI\n}\n```\nOver-engineered\n\u003C\u002Fbad-example>\n\nDon't add features, refactor other code, or \"improve\" beyond the test.\n\n## Verify GREEN - Watch It Pass\n\n```bash\nnpm test path\u002Fto\u002Ftest.test.ts\n```\n\nConfirm:\n\n- Test passes\n- Other tests still pass\n- Output pristine (no errors, warnings)\n\n## REFACTOR - Clean Up\n\nAfter green only:\n\n- Remove duplication\n- Improve names\n- Extract helpers\n\nKeep tests green. Do not add behavior.\n",{"name":5,"description":7},"main","8809386f7af487f40be7dcbea5d0e4afc37efd0a",".agency\u002Fplugins\u002Fnori\u002Fskills\u002Ftest-driven-development",590,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FFluidFramework","https:\u002F\u002Ffluidframework.com","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-11 08:22:43",{"source":8,"skillName":5,"commands":61,"prompt":71,"zipAvailable":72},[62,65,68],{"tool":63,"command":64},"npx","npx skills add microsoft\u002FFluidFramework --skill test-driven-development",{"tool":66,"command":67},"bunx","bunx skills add microsoft\u002FFluidFramework --skill test-driven-development",{"tool":69,"command":70},"pnpm","pnpm dlx skills add microsoft\u002FFluidFramework --skill test-driven-development","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FFluidFramework\u002Fblob\u002Fmain\u002F.agency\u002Fplugins\u002Fnori\u002Fskills\u002Ftest-driven-development\u002FSKILL.md",true,[],[75,96,132,156,174,194],{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":45},"01M6PJ5SAHYFZFWDG5Y4RW56EP","trigger-pipelines-for-copilot-pr","Trigger ADO pipelines for a Copilot-created PR by posting \u002Fazp run comments. Use when the user asks to trigger CI pipelines for a specific PR.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FFluidFramework\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Ftrigger-pipelines-for-copilot-pr\u002FSKILL.md",[],[82,83,84,85,86,87,88,89,90,91,38,92,93,94,95,28],"pr","trigger pipelines for copilot pr","for","trigger","copilot","pipelines","ado","posting","run","ci","number","URL","comments","user",{"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":113,"publishedAt":45},"01M6PJ5M4ZG7E78C4GM4041HEP","review","Review changes relative to a prior state, such as a diff, pull request, branch, commit, or working-tree changes. Use for change-focused code review and regression analysis. Do not use to assess an existing file, API, design, implementation, or other artifact without a comparison; if the request is ambiguous, ask whether the user wants a change review and what prior state to compare against.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FFluidFramework\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Freview\u002FSKILL.md",[102,105,108],{"categoryNo":103,"categoryName":104,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":106,"categoryName":107,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":109,"categoryName":110,"taxonomyType":111,"taxonomyTypeDesc":112},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[98,114,115,116,117,118,119,44,120,121,122,123,124,125,126,127,128,129,84,130,131],"branch","regression","code review","design","ask","analysis","commit","api","change","artifact","request","pull","tree","as","do","diff","assess","ambiguous",{"skillNo":133,"name":134,"nameZh":6,"description":135,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":141,"publishedAt":45},"01M6PJ5E3PCBDS319FFMHPFACN","review-pr-local","The authority on pulling a pull request — Azure DevOps or GitHub — into an isolated local worktree so a human can review it in their editor, and on posting human-controlled review comments back to the PR (ADO via the ado PR-thread MCP tools or the Azure DevOps REST API, GitHub via the gh CLI). Auto-detects the platform and all identifiers from the PR URL; not tied to any specific repository. The AI assists an interactive human review and only ever posts comments the human explicitly requests. If you find yourself checking out a PR branch over the user's own working tree, or posting AI-authored review prose the human did not ask for, invoke this skill instead.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FFluidFramework\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Freview-pr-local\u002FSKILL.md",[138],{"categoryNo":139,"categoryName":140,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[142,98,82,143,144,145,114,146,147,148,149,150,151,152,93,153,118,121,154,155],"local","review pr local","review pr","back","posts","only","MCP","authority","auto","invoke","azure devops","you","cli","worktree",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":162,"publishedAt":45},"01M6PJ5AVZAS0AEBPCYJZ9ZMMD","policy-check","This skill should be used when the user asks to \"run policy check\", \"check policy\", \"policy-check\", or needs to validate package compliance. Provides guidance on running policy checks for specific packages or the entire repository.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FFluidFramework\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpolicy-check\u002FSKILL.md",[],[163,164,165,166,167,84,90,168,169,170,171,95,172,28,173],"policy check","policy","check","packages","compliance","repository","guidance","validate","package","running","entire",{"skillNo":175,"name":176,"nameZh":6,"description":177,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":178,"categories":179,"keywords":181,"publishedAt":45},"01M6PJ54H068MZF2WD2JDKCVDC","pipeline-test-triage","Triage test failures in an Azure DevOps pipeline run for Fluid Framework. Use when the user shares an ADO build\u002Fpipeline URL or build ID and wants failures analyzed, when they ask \"why did this pipeline fail\", \"summarize the test failures\", \"is this test flaky or a real bug\", \"compare these runs\", or wants bugs filed for genuine failures. Covers the Real Service End to End Tests pipeline as the worked example but applies to any FF test pipeline.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FFluidFramework\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpipeline-test-triage\u002FSKILL.md",[180],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[182,183,184,185,24,186,187,188,152,93,118,90,189,190,191,192,88,127,193,84,28],"pipeline","test triage","pipeline test triage","pipeline test","triage","end","test pipeline","why","bug","but","framework","bugs",{"skillNo":195,"name":196,"nameZh":6,"description":197,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":198,"categories":199,"keywords":200,"publishedAt":45},"01M6PJ4ZJASDV2CGQTG1JWKBFE","fluid-release","Fluid Framework client release group — minor releases, patch releases, and post-release type test updates. Covers release prep, branching, version bumps, changelogs, release notes, and type test baselines. In autonomous mode, auto-detects state from the repo, attempts to execute, and falls back to a GitHub issue on failure. Triggers on \"release\", \"do the release\", \"release status\", version bump, release notes, changelog, release branch, or release engineering.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FFluidFramework\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Ffluid-release\u002FSKILL.md",[],[201,202,203,145,114,204,205,206,207,208,150,209,210,211,212,213,214,215,216,217],"release","fluid release","fluid","bump","mode","autonomous","release notes","release status","updates","patch","notes","changelog","release prep","releases","status","issue","branching"]