[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C0SZ4EZHJD468PDVBQBYT3":3,"skill-same:01M6C0SZ4EZHJD468PDVBQBYT3":116},{"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":29,"linkOnly":30,"markdownContent":31,"markdownBody":32,"frontMatter":33,"refName":34,"commitSha":35,"skillDirectory":36,"forksCount":14,"repositoryHtmlUrl":37,"repositoryHomepageUrl":6,"ownerHtmlUrl":38,"ownerBlogUrl":39,"ownerDescription":40,"updatedAt":41,"install":42,"resources":55},"01M6C0SZ4EZHJD468PDVBQBYT3","test-driven-development",null,"Use when implementing any feature or bugfix, before writing implementation code","marcosdh1987\u002Fml-python-base","marcosdh1987","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F31476977?v=4","01M6C0RHZYKQDC51CRAMD70QPA","Marcos Soto","01M6C0RJ4MBBJ4YHRE79QFGDXZ",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Ftest-driven-development\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28],"test","test driven development","development","writing","code","2026-11-10 10:12:30",false,"---\nname: test-driven-development\ndescription: Use when implementing any feature or bugfix, before writing implementation code\n---\n\n# Test-Driven Development (TDD)\n\n## Overview\n\nWrite the test first. Watch it fail. Write minimal code to pass.\n\n**Core principle:** If you didn't watch the test fail, you don't know if it tests the right thing.\n\n**Violating the letter of the rules is violating the spirit of the rules.**\n\n## When to Use\n\n**Always:**\n- New features\n- Bug fixes\n- Refactoring\n- Behavior changes\n\n**Exceptions (ask your human partner):**\n- Throwaway prototypes\n- Generated code\n- Configuration files\n\nThinking \"skip TDD just this once\"? Stop. That's rationalization.\n\n## The Iron Law\n\n```\nNO PRODUCTION CODE WITHOUT A FAILING TEST FIRST\n```\n\nWrite code before the test? Delete it. Start over.\n\n**No exceptions:**\n- Don't keep it as \"reference\"\n- Don't \"adapt\" it while writing tests\n- Don't look at it\n- Delete means delete\n\nImplement fresh from tests. Period.\n\n## Red-Green-Refactor\n\n```dot\ndigraph tdd_cycle {\n    rankdir=LR;\n    red [label=\"RED\\nWrite failing test\", shape=box, style=filled, fillcolor=\"#ffcccc\"];\n    verify_red [label=\"Verify fails\\ncorrectly\", shape=diamond];\n    green [label=\"GREEN\\nMinimal code\", shape=box, style=filled, fillcolor=\"#ccffcc\"];\n    verify_green [label=\"Verify passes\\nAll green\", shape=diamond];\n    refactor [label=\"REFACTOR\\nClean up\", shape=box, style=filled, fillcolor=\"#ccccff\"];\n    next [label=\"Next\", shape=ellipse];\n\n    red -> verify_red;\n    verify_red -> green [label=\"yes\"];\n    verify_red -> red [label=\"wrong\\nfailure\"];\n    green -> verify_green;\n    verify_green -> refactor [label=\"yes\"];\n    verify_green -> green [label=\"no\"];\n    refactor -> verify_green [label=\"stay\\ngreen\"];\n    verify_green -> next;\n    next -> red;\n}\n```\n\n### RED - Write Failing Test\n\nWrite one minimal test showing what should happen.\n\n\u003CGood>\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 retryOperation(operation);\n\n  expect(result).toBe('success');\n  expect(attempts).toBe(3);\n});\n```\nClear name, tests real behavior, one thing\n\u003C\u002FGood>\n\n\u003CBad>\n```typescript\ntest('retry works', async () => {\n  const mock = jest.fn()\n    .mockRejectedValueOnce(new Error())\n    .mockRejectedValueOnce(new Error())\n    .mockResolvedValueOnce('success');\n  await retryOperation(mock);\n  expect(mock).toHaveBeenCalledTimes(3);\n});\n```\nVague name, tests mock not code\n\u003C\u002FBad>\n\n**Requirements:**\n- One behavior\n- Clear name\n- Real code (no mocks unless unavoidable)\n\n### Verify RED - Watch It Fail\n\n**MANDATORY. Never skip.**\n\n```bash\nnpm test path\u002Fto\u002Ftest.test.ts\n```\n\nConfirm:\n- Test fails (not errors)\n- Failure message is expected\n- Fails because feature missing (not typos)\n\n**Test passes?** You're testing existing behavior. Fix test.\n\n**Test errors?** Fix error, re-run until it fails correctly.\n\n### GREEN - Minimal Code\n\nWrite simplest code to pass the test.\n\n\u003CGood>\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>\n\n\u003CBad>\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>\n\nDon't add features, refactor other code, or \"improve\" beyond the test.\n\n### Verify GREEN - Watch It Pass\n\n**MANDATORY.**\n\n```bash\nnpm test path\u002Fto\u002Ftest.test.ts\n```\n\nConfirm:\n- Test passes\n- Other tests still pass\n- Output pristine (no errors, warnings)\n\n**Test fails?** Fix code, not test.\n\n**Other tests fail?** Fix now.\n\n### REFACTOR - Clean Up\n\nAfter green only:\n- Remove duplication\n- Improve names\n- Extract helpers\n\nKeep tests green. Don't add behavior.\n\n### Repeat\n\nNext failing test for next feature.\n\n## Good Tests\n\n| Quality | Good | Bad |\n|---------|------|-----|\n| **Minimal** | One thing. \"and\" in name? Split it. | `test('validates email and domain and whitespace')` |\n| **Clear** | Name describes behavior | `test('test1')` |\n| **Shows intent** | Demonstrates desired API | Obscures what code should do |\n\n## Why Order Matters\n\n**\"I'll write tests after to verify it works\"**\n\nTests written after code pass immediately. Passing immediately proves nothing:\n- Might test wrong thing\n- Might test implementation, not behavior\n- Might miss edge cases you forgot\n- You never saw it catch the bug\n\nTest-first forces you to see the test fail, proving it actually tests something.\n\n**\"I already manually tested all the edge cases\"**\n\nManual testing is ad-hoc. You think you tested everything but:\n- No record of what you tested\n- Can't re-run when code changes\n- Easy to forget cases under pressure\n- \"It worked when I tried it\" ≠ comprehensive\n\nAutomated tests are systematic. They run the same way every time.\n\n**\"Deleting X hours of work is wasteful\"**\n\nSunk cost fallacy. The time is already gone. Your choice now:\n- Delete and rewrite with TDD (X more hours, high confidence)\n- Keep it and add tests after (30 min, low confidence, likely bugs)\n\nThe \"waste\" is keeping code you can't trust. Working code without real tests is technical debt.\n\n**\"TDD is dogmatic, being pragmatic means adapting\"**\n\nTDD IS pragmatic:\n- Finds bugs before commit (faster than debugging after)\n- Prevents regressions (tests catch breaks immediately)\n- Documents behavior (tests show how to use code)\n- Enables refactoring (change freely, tests catch breaks)\n\n\"Pragmatic\" shortcuts = debugging in production = slower.\n\n**\"Tests after achieve the same goals - it's spirit not ritual\"**\n\nNo. Tests-after answer \"What does this do?\" Tests-first answer \"What should this do?\"\n\nTests-after are biased by your implementation. You test what you built, not what's required. You verify remembered edge cases, not discovered ones.\n\nTests-first force edge case discovery before implementing. Tests-after verify you remembered everything (you didn't).\n\n30 minutes of tests after ≠ TDD. You get coverage, lose proof tests work.\n\n## Common Rationalizations\n\n| Excuse | Reality |\n|--------|---------|\n| \"Too simple to test\" | Simple code breaks. Test takes 30 seconds. |\n| \"I'll test after\" | Tests passing immediately prove nothing. |\n| \"Tests after achieve same goals\" | Tests-after = \"what does this do?\" Tests-first = \"what should this do?\" |\n| \"Already manually tested\" | Ad-hoc ≠ systematic. No record, can't re-run. |\n| \"Deleting X hours is wasteful\" | Sunk cost fallacy. Keeping unverified code is technical debt. |\n| \"Keep as reference, write tests first\" | You'll adapt it. That's testing after. Delete means delete. |\n| \"Need to explore first\" | Fine. Throw away exploration, start with TDD. |\n| \"Test hard = design unclear\" | Listen to test. Hard to test = hard to use. |\n| \"TDD will slow me down\" | TDD faster than debugging. Pragmatic = test-first. |\n| \"Manual test faster\" | Manual doesn't prove edge cases. You'll re-test every change. |\n| \"Existing code has no tests\" | You're improving it. Add tests for existing code. |\n\n## Red Flags - STOP and Start Over\n\n- Code before test\n- Test after implementation\n- Test passes immediately\n- Can't explain why test failed\n- Tests added \"later\"\n- Rationalizing \"just this once\"\n- \"I already manually tested it\"\n- \"Tests after achieve the same purpose\"\n- \"It's about spirit not ritual\"\n- \"Keep as reference\" or \"adapt existing code\"\n- \"Already spent X hours, deleting is wasteful\"\n- \"TDD is dogmatic, I'm being pragmatic\"\n- \"This is different because...\"\n\n**All of these mean: Delete code. Start over with TDD.**\n\n## Example: Bug Fix\n\n**Bug:** Empty email accepted\n\n**RED**\n```typescript\ntest('rejects empty email', async () => {\n  const result = await submitForm({ email: '' });\n  expect(result.error).toBe('Email required');\n});\n```\n\n**Verify RED**\n```bash\n$ npm test\nFAIL: expected 'Email required', got undefined\n```\n\n**GREEN**\n```typescript\nfunction submitForm(data: FormData) {\n  if (!data.email?.trim()) {\n    return { error: 'Email required' };\n  }\n  \u002F\u002F ...\n}\n```\n\n**Verify GREEN**\n```bash\n$ npm test\nPASS\n```\n\n**REFACTOR**\nExtract validation for multiple fields if needed.\n\n## Verification Checklist\n\nBefore marking work complete:\n\n- [ ] Every new function\u002Fmethod has a test\n- [ ] Watched each test fail before implementing\n- [ ] Each test failed for expected reason (feature missing, not typo)\n- [ ] Wrote minimal code to pass each test\n- [ ] All tests pass\n- [ ] Output pristine (no errors, warnings)\n- [ ] Tests use real code (mocks only if unavoidable)\n- [ ] Edge cases and errors covered\n\nCan't check all boxes? You skipped TDD. Start over.\n\n## When Stuck\n\n| Problem | Solution |\n|---------|----------|\n| Don't know how to test | Write wished-for API. Write assertion first. Ask your human partner. |\n| Test too complicated | Design too complicated. Simplify interface. |\n| Must mock everything | Code too coupled. Use dependency injection. |\n| Test setup huge | Extract helpers. Still complex? Simplify design. |\n\n## Debugging Integration\n\nBug found? Write failing test reproducing it. Follow TDD cycle. Test proves fix and prevents regression.\n\nNever fix bugs without a test.\n\n## Testing Anti-Patterns\n\nWhen adding mocks or test utilities, read @testing-anti-patterns.md to avoid common pitfalls:\n- Testing mock behavior instead of real behavior\n- Adding test-only methods to production classes\n- Mocking without understanding dependencies\n\n## Final Rule\n\n```\nProduction code → test exists and failed first\nOtherwise → not TDD\n```\n\nNo exceptions without your human partner's permission.\n","# Test-Driven Development (TDD)\n\n## Overview\n\nWrite the test first. Watch it fail. Write minimal code to pass.\n\n**Core principle:** If you didn't watch the test fail, you don't know if it tests the right thing.\n\n**Violating the letter of the rules is violating the spirit of the rules.**\n\n## When to Use\n\n**Always:**\n- New features\n- Bug fixes\n- Refactoring\n- Behavior changes\n\n**Exceptions (ask your human partner):**\n- Throwaway prototypes\n- Generated code\n- Configuration files\n\nThinking \"skip TDD just this once\"? Stop. That's rationalization.\n\n## The Iron Law\n\n```\nNO PRODUCTION CODE WITHOUT A FAILING TEST FIRST\n```\n\nWrite code before the test? Delete it. Start over.\n\n**No exceptions:**\n- Don't keep it as \"reference\"\n- Don't \"adapt\" it while writing tests\n- Don't look at it\n- Delete means delete\n\nImplement fresh from tests. Period.\n\n## Red-Green-Refactor\n\n```dot\ndigraph tdd_cycle {\n    rankdir=LR;\n    red [label=\"RED\\nWrite failing test\", shape=box, style=filled, fillcolor=\"#ffcccc\"];\n    verify_red [label=\"Verify fails\\ncorrectly\", shape=diamond];\n    green [label=\"GREEN\\nMinimal code\", shape=box, style=filled, fillcolor=\"#ccffcc\"];\n    verify_green [label=\"Verify passes\\nAll green\", shape=diamond];\n    refactor [label=\"REFACTOR\\nClean up\", shape=box, style=filled, fillcolor=\"#ccccff\"];\n    next [label=\"Next\", shape=ellipse];\n\n    red -> verify_red;\n    verify_red -> green [label=\"yes\"];\n    verify_red -> red [label=\"wrong\\nfailure\"];\n    green -> verify_green;\n    verify_green -> refactor [label=\"yes\"];\n    verify_green -> green [label=\"no\"];\n    refactor -> verify_green [label=\"stay\\ngreen\"];\n    verify_green -> next;\n    next -> red;\n}\n```\n\n### RED - Write Failing Test\n\nWrite one minimal test showing what should happen.\n\n\u003CGood>\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 retryOperation(operation);\n\n  expect(result).toBe('success');\n  expect(attempts).toBe(3);\n});\n```\nClear name, tests real behavior, one thing\n\u003C\u002FGood>\n\n\u003CBad>\n```typescript\ntest('retry works', async () => {\n  const mock = jest.fn()\n    .mockRejectedValueOnce(new Error())\n    .mockRejectedValueOnce(new Error())\n    .mockResolvedValueOnce('success');\n  await retryOperation(mock);\n  expect(mock).toHaveBeenCalledTimes(3);\n});\n```\nVague name, tests mock not code\n\u003C\u002FBad>\n\n**Requirements:**\n- One behavior\n- Clear name\n- Real code (no mocks unless unavoidable)\n\n### Verify RED - Watch It Fail\n\n**MANDATORY. Never skip.**\n\n```bash\nnpm test path\u002Fto\u002Ftest.test.ts\n```\n\nConfirm:\n- Test fails (not errors)\n- Failure message is expected\n- Fails because feature missing (not typos)\n\n**Test passes?** You're testing existing behavior. Fix test.\n\n**Test errors?** Fix error, re-run until it fails correctly.\n\n### GREEN - Minimal Code\n\nWrite simplest code to pass the test.\n\n\u003CGood>\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>\n\n\u003CBad>\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>\n\nDon't add features, refactor other code, or \"improve\" beyond the test.\n\n### Verify GREEN - Watch It Pass\n\n**MANDATORY.**\n\n```bash\nnpm test path\u002Fto\u002Ftest.test.ts\n```\n\nConfirm:\n- Test passes\n- Other tests still pass\n- Output pristine (no errors, warnings)\n\n**Test fails?** Fix code, not test.\n\n**Other tests fail?** Fix now.\n\n### REFACTOR - Clean Up\n\nAfter green only:\n- Remove duplication\n- Improve names\n- Extract helpers\n\nKeep tests green. Don't add behavior.\n\n### Repeat\n\nNext failing test for next feature.\n\n## Good Tests\n\n| Quality | Good | Bad |\n|---------|------|-----|\n| **Minimal** | One thing. \"and\" in name? Split it. | `test('validates email and domain and whitespace')` |\n| **Clear** | Name describes behavior | `test('test1')` |\n| **Shows intent** | Demonstrates desired API | Obscures what code should do |\n\n## Why Order Matters\n\n**\"I'll write tests after to verify it works\"**\n\nTests written after code pass immediately. Passing immediately proves nothing:\n- Might test wrong thing\n- Might test implementation, not behavior\n- Might miss edge cases you forgot\n- You never saw it catch the bug\n\nTest-first forces you to see the test fail, proving it actually tests something.\n\n**\"I already manually tested all the edge cases\"**\n\nManual testing is ad-hoc. You think you tested everything but:\n- No record of what you tested\n- Can't re-run when code changes\n- Easy to forget cases under pressure\n- \"It worked when I tried it\" ≠ comprehensive\n\nAutomated tests are systematic. They run the same way every time.\n\n**\"Deleting X hours of work is wasteful\"**\n\nSunk cost fallacy. The time is already gone. Your choice now:\n- Delete and rewrite with TDD (X more hours, high confidence)\n- Keep it and add tests after (30 min, low confidence, likely bugs)\n\nThe \"waste\" is keeping code you can't trust. Working code without real tests is technical debt.\n\n**\"TDD is dogmatic, being pragmatic means adapting\"**\n\nTDD IS pragmatic:\n- Finds bugs before commit (faster than debugging after)\n- Prevents regressions (tests catch breaks immediately)\n- Documents behavior (tests show how to use code)\n- Enables refactoring (change freely, tests catch breaks)\n\n\"Pragmatic\" shortcuts = debugging in production = slower.\n\n**\"Tests after achieve the same goals - it's spirit not ritual\"**\n\nNo. Tests-after answer \"What does this do?\" Tests-first answer \"What should this do?\"\n\nTests-after are biased by your implementation. You test what you built, not what's required. You verify remembered edge cases, not discovered ones.\n\nTests-first force edge case discovery before implementing. Tests-after verify you remembered everything (you didn't).\n\n30 minutes of tests after ≠ TDD. You get coverage, lose proof tests work.\n\n## Common Rationalizations\n\n| Excuse | Reality |\n|--------|---------|\n| \"Too simple to test\" | Simple code breaks. Test takes 30 seconds. |\n| \"I'll test after\" | Tests passing immediately prove nothing. |\n| \"Tests after achieve same goals\" | Tests-after = \"what does this do?\" Tests-first = \"what should this do?\" |\n| \"Already manually tested\" | Ad-hoc ≠ systematic. No record, can't re-run. |\n| \"Deleting X hours is wasteful\" | Sunk cost fallacy. Keeping unverified code is technical debt. |\n| \"Keep as reference, write tests first\" | You'll adapt it. That's testing after. Delete means delete. |\n| \"Need to explore first\" | Fine. Throw away exploration, start with TDD. |\n| \"Test hard = design unclear\" | Listen to test. Hard to test = hard to use. |\n| \"TDD will slow me down\" | TDD faster than debugging. Pragmatic = test-first. |\n| \"Manual test faster\" | Manual doesn't prove edge cases. You'll re-test every change. |\n| \"Existing code has no tests\" | You're improving it. Add tests for existing code. |\n\n## Red Flags - STOP and Start Over\n\n- Code before test\n- Test after implementation\n- Test passes immediately\n- Can't explain why test failed\n- Tests added \"later\"\n- Rationalizing \"just this once\"\n- \"I already manually tested it\"\n- \"Tests after achieve the same purpose\"\n- \"It's about spirit not ritual\"\n- \"Keep as reference\" or \"adapt existing code\"\n- \"Already spent X hours, deleting is wasteful\"\n- \"TDD is dogmatic, I'm being pragmatic\"\n- \"This is different because...\"\n\n**All of these mean: Delete code. Start over with TDD.**\n\n## Example: Bug Fix\n\n**Bug:** Empty email accepted\n\n**RED**\n```typescript\ntest('rejects empty email', async () => {\n  const result = await submitForm({ email: '' });\n  expect(result.error).toBe('Email required');\n});\n```\n\n**Verify RED**\n```bash\n$ npm test\nFAIL: expected 'Email required', got undefined\n```\n\n**GREEN**\n```typescript\nfunction submitForm(data: FormData) {\n  if (!data.email?.trim()) {\n    return { error: 'Email required' };\n  }\n  \u002F\u002F ...\n}\n```\n\n**Verify GREEN**\n```bash\n$ npm test\nPASS\n```\n\n**REFACTOR**\nExtract validation for multiple fields if needed.\n\n## Verification Checklist\n\nBefore marking work complete:\n\n- [ ] Every new function\u002Fmethod has a test\n- [ ] Watched each test fail before implementing\n- [ ] Each test failed for expected reason (feature missing, not typo)\n- [ ] Wrote minimal code to pass each test\n- [ ] All tests pass\n- [ ] Output pristine (no errors, warnings)\n- [ ] Tests use real code (mocks only if unavoidable)\n- [ ] Edge cases and errors covered\n\nCan't check all boxes? You skipped TDD. Start over.\n\n## When Stuck\n\n| Problem | Solution |\n|---------|----------|\n| Don't know how to test | Write wished-for API. Write assertion first. Ask your human partner. |\n| Test too complicated | Design too complicated. Simplify interface. |\n| Must mock everything | Code too coupled. Use dependency injection. |\n| Test setup huge | Extract helpers. Still complex? Simplify design. |\n\n## Debugging Integration\n\nBug found? Write failing test reproducing it. Follow TDD cycle. Test proves fix and prevents regression.\n\nNever fix bugs without a test.\n\n## Testing Anti-Patterns\n\nWhen adding mocks or test utilities, read @testing-anti-patterns.md to avoid common pitfalls:\n- Testing mock behavior instead of real behavior\n- Adding test-only methods to production classes\n- Mocking without understanding dependencies\n\n## Final Rule\n\n```\nProduction code → test exists and failed first\nOtherwise → not TDD\n```\n\nNo exceptions without your human partner's permission.\n",{"name":5,"description":7},"main","a13a7ba3a107d6810ee15f05851acd873cfdf316",".agents\u002Fskills\u002Ftest-driven-development","https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base","https:\u002F\u002Fgithub.com\u002Fmarcosdh1987","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fmarcosesoto\u002F","I'm a System Engineer, a big fan of technology and travels ","2026-09-12 21:08:50",{"source":8,"skillName":5,"commands":43,"prompt":53,"zipAvailable":54},[44,47,50],{"tool":45,"command":46},"npx","npx skills add marcosdh1987\u002Fml-python-base --skill test-driven-development",{"tool":48,"command":49},"bunx","bunx skills add marcosdh1987\u002Fml-python-base --skill test-driven-development",{"tool":51,"command":52},"pnpm","pnpm dlx skills add marcosdh1987\u002Fml-python-base --skill test-driven-development","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Ftest-driven-development\u002FSKILL.md",true,[56,62,68,72,76,80,84,88,92,96,100,104,108,112],{"path":57,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":60,"sourceHtmlUrl":61},"architecture-decision-template.md","REFERENCE","参考文档",337,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Farchitecture-decision-template.md",{"path":63,"resourceType":64,"resourceTypeDesc":65,"sizeBytes":66,"sourceHtmlUrl":67},"data\u002Fdomain-complexity.csv","ASSET","资产文件",2187,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fdata\u002Fdomain-complexity.csv",{"path":69,"resourceType":64,"resourceTypeDesc":65,"sizeBytes":70,"sourceHtmlUrl":71},"data\u002Fproject-types.csv",758,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fdata\u002Fproject-types.csv",{"path":73,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":74,"sourceHtmlUrl":75},"steps\u002Fstep-01-init.md",6584,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fsteps\u002Fstep-01-init.md",{"path":77,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":78,"sourceHtmlUrl":79},"steps\u002Fstep-01b-continue.md",6232,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fsteps\u002Fstep-01b-continue.md",{"path":81,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":82,"sourceHtmlUrl":83},"steps\u002Fstep-02-context.md",8621,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fsteps\u002Fstep-02-context.md",{"path":85,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":86,"sourceHtmlUrl":87},"steps\u002Fstep-03-starter.md",11976,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fsteps\u002Fstep-03-starter.md",{"path":89,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":90,"sourceHtmlUrl":91},"steps\u002Fstep-04-decisions.md",10269,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fsteps\u002Fstep-04-decisions.md",{"path":93,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":94,"sourceHtmlUrl":95},"steps\u002Fstep-05-patterns.md",10918,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fsteps\u002Fstep-05-patterns.md",{"path":97,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":98,"sourceHtmlUrl":99},"steps\u002Fstep-06-structure.md",11177,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fsteps\u002Fstep-06-structure.md",{"path":101,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":102,"sourceHtmlUrl":103},"steps\u002Fstep-07-validation.md",11636,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fsteps\u002Fstep-07-validation.md",{"path":105,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":106,"sourceHtmlUrl":107},"steps\u002Fstep-08-complete.md",3133,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fsteps\u002Fstep-08-complete.md",{"path":109,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":110,"sourceHtmlUrl":111},"testing-anti-patterns.md",8251,"https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Ftest-driven-development\u002Ftesting-anti-patterns.md",{"path":113,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":114,"sourceHtmlUrl":115},"workflow.md",1547,"https:\u002F\u002Fgithub.com\u002FStarksJohn\u002FCursorUserDir\u002Fblob\u002Fmain\u002Fskills\u002Fbmad-create-architecture\u002Fworkflow.md",[117,134,143,151,159,174],{"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":131,"publishedAt":29},"01M6C0Z2ZS9H5CGZ29BMP9CER3","writing-plans","Use when you have a spec or requirements for a multi-step task, before touching code","https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fwriting-plans\u002FSKILL.md",[123,126],{"categoryNo":124,"categoryName":125,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":127,"categoryName":128,"taxonomyType":129,"taxonomyTypeDesc":130},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[132,27,133,28],"writing plans","spec",{"skillNo":135,"name":136,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":141,"publishedAt":29},"01M6C0Z14PK451BXB8CYM7FX90","writing-clearly-and-concisely","https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fwriting-clearly-and-concisely\u002FSKILL.md",[139,140],{"categoryNo":124,"categoryName":125,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":127,"categoryName":128,"taxonomyType":129,"taxonomyTypeDesc":130},[142,27],"writing clearly and concisely",{"skillNo":144,"name":145,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":148,"publishedAt":29},"01M6C0YZY8TWH2Y4N3SK6YRDWP","verify_changes","https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fverify_changes\u002FSKILL.md",[],[149,150],"verify","Verify Changes",{"skillNo":152,"name":153,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":156,"publishedAt":29},"01M6C0YYMB7BRK96VWDNCWGRK6","validate_module_structure","https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fvalidate_module_structure\u002FSKILL.md",[],[157,158],"validate module structure","validate",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":165,"publishedAt":29},"01M6C0YVRTE83GBHRA90YP6AYT","using-git-worktrees","Use when starting feature work that needs isolation from current workspace or before executing implementation plans - ensures an isolated workspace exists via native tools or git worktree fallback","https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fusing-git-worktrees\u002FSKILL.md",[],[166,167,168,169,170,171,172,173],"git worktrees","git","using git worktrees","work","workspace","git worktree","Tools","worktree",{"skillNo":175,"name":176,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":177,"categories":178,"keywords":182,"publishedAt":29},"01M6C0YTB8BHES6KTV29SKDTFA","ui-ux-pro-max","https:\u002F\u002Fgithub.com\u002Fmarcosdh1987\u002Fml-python-base\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fui-ux-pro-max\u002FSKILL.md",[179],{"categoryNo":180,"categoryName":181,"taxonomyType":129,"taxonomyTypeDesc":130},"01JBSEEDCAT000000000000032","设计师",[183,184,185],"ui","ui ux pro max","ux"]