{"id":"d4f6c62b-e3e9-451e-b2dc-996c64bd46af","shortId":"hj9Kvn","kind":"skill","title":"test-driven-development","tagline":"Use when implementing any feature or bugfix, before writing implementation code","description":"# Test-Driven Development (TDD)\n\n## Overview\n\n**Announce at start:** \"Test-Driven Development skill activated.\"\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<Good>\n```typescript\ntest('retries failed operations 3 times', async () => {\n  let attempts = 0;\n  const operation = () => {\n    attempts++;\n    if (attempts < 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</Good>\n\n<Bad>\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</Bad>\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/to/test.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<Good>\n```typescript\nasync function retryOperation<T>(fn: () => Promise<T>): Promise<T> {\n  for (let i = 0; i < 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</Good>\n\n<Bad>\n```typescript\nasync function retryOperation<T>(\n  fn: () => Promise<T>,\n  options?: {\n    maxRetries?: number;\n    backoff?: 'linear' | 'exponential';\n    onRetry?: (attempt: number) => void;\n  }\n): Promise<T> {\n  // YAGNI\n}\n```\nOver-engineered\n</Bad>\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/to/test.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  // ...\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/method 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.","tags":["test","driven","development","coco","rkz91","agent-skills","agents-md","ai-agents","claude-code","codex","cursor","developer-tools"],"capabilities":["skill","source-rkz91","skill-test-driven-development","topic-agent-skills","topic-agents-md","topic-ai-agents","topic-claude-code","topic-codex","topic-cursor","topic-developer-tools","topic-llm-tools","topic-mcp","topic-pm-tools","topic-product-management","topic-productivity"],"categories":["coco"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/rkz91/coco/test-driven-development","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add rkz91/coco","source_repo":"https://github.com/rkz91/coco","install_from":"skills.sh"}},"qualityScore":"0.453","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 7 github stars · SKILL.md body (9,791 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:14:09.618Z","embedding":null,"createdAt":"2026-05-18T13:21:43.089Z","updatedAt":"2026-05-18T19:14:09.618Z","lastSeenAt":"2026-05-18T19:14:09.618Z","tsv":"'0':282,422 '2':434 '3':277,288,307,337,424 '30':724,864,890 'accept':1118 'achiev':794,903,1067 'activ':30 'actual':629 'ad':644,924,1054,1317,1335 'ad-hoc':643,923 'adapt':138,753,956,1081 'add':468,528,721,1027 'alreadi':633,703,920,1061,1084 'alway':79 'announc':22 'answer':807,815 'anti':1314 'anti-pattern':1313 'api':567,1254 'ask':88,1258 'assert':1256 'async':279,319,413,446,1125 'attempt':281,285,287,305,458 'autom':679 'avoid':1325 'await':297,331,428,1128 'away':971 'backoff':454 'bad':541 'bash':363,484,1138,1162 'behavior':85,312,346,388,529,560,603,772,1330,1334 'beyond':475 'bias':824 'box':173,192,212,1234 'break':769,785,887 'bug':82,616,729,758,1113,1115,1290,1308 'bugfix':11 'built':832 'case':607,639,669,841,850,1010,1226 'catch':430,614,768,784 'ccccff':216 'ccffcc':196 'chang':86,665,781,1017 'check':1232 'checklist':1175 'choic':706 'class':1342 'clean':512 'clear':308,347,557 'code':15,40,95,113,120,190,343,350,404,407,472,503,570,588,664,734,740,778,886,944,1019,1031,1038,1083,1107,1204,1220,1273,1350 'commit':760 'common':877,1326 'complet':1179 'complex':1285 'complic':1264,1267 'comprehens':678 'confid':717,727 'configur':96 'confirm':367,488 'const':283,295,320,1126 'core':43 'correct':401 'cost':698,940 'coupl':1275 'cover':1229 'coverag':872 'cycl':163,1299 'data':1151 'data.email':1154 'debt':746,947 'debug':763,788,997,1288 'delet':124,148,150,690,708,934,962,964,1088,1106 'demonstr':565 'depend':1277,1346 'describ':559 'design':978,1265,1287 'desir':566 'develop':4,19,28 'diamond':185,205 'didn':47,862 'differ':1100 'digraph':161 'discov':843 'discoveri':851 'document':771 'doesn':1006 'dogmat':749,1093 'domain':554 'dot':160 'driven':3,18,27 'duplic':518 'e':431,436 'easi':666 'edg':606,638,840,849,1009,1225 'ellips':221 'email':552,1117,1124,1130,1134,1143,1158 'empti':1116,1123 'enabl':779 'engin':465 'enough':442 'error':291,325,328,371,392,394,439,498,1157,1215,1228 'everi':688,1016,1180 'everyth':650,860,1272 'exampl':1112 'except':87,129,1360 'excus':879 'exist':387,1018,1030,1082,1352 'expect':300,304,334,375,1131,1142,1196 'explain':1049 'explor':967,972 'exponenti':456 'extract':521,1167,1282 'fail':37,52,116,170,182,262,275,292,359,369,376,400,501,508,532,626,1052,1141,1189,1194,1293,1354 'failur':372 'fallaci':699,941 'faster':761,995,1004 'featur':9,81,378,469,536,1198 'ffcccc':177 'field':1171 'file':97 'fill':175,194,214 'fillcolor':176,195,215 'final':1347 'find':757 'fine':969 'first':34,118,619,814,847,915,953,968,1001,1257,1355 'fix':83,389,393,502,509,1114,1302,1307 'flag':1033 'fn':416,429,449 'follow':1297 'forc':620,848 'forget':668 'forgot':609 'formdata':1152 'found':1291 'freeli':782 'fresh':152 'function':414,447,1149 'function/method':1182 'generat':94 'get':871 'goal':797,905 'gone':704 'good':537,540 'got':1145 'green':158,186,188,198,203,227,236,238,240,245,246,251,256,402,479,515,525,1147,1161 'happen':271 'hard':977,983,986 'helper':522,1283 'high':716 'hoc':645,925 'hour':692,715,936,1087 'huge':1281 'human':90,1260,1363 'immedi':590,592,770,898,1046 'implement':7,14,151,601,827,853,1043,1191 'improv':474,519,1025 'inject':1278 'instead':1331 'integr':1289 'intent':564 'interfac':1269 'iron':109 'jest.fn':322 'keep':132,523,718,733,942,948,1077 'know':56,1246 'label':167,180,187,199,207,218,228,233,242,247,252 'later':1055 'law':110 'let':280,420 'letter':65 'like':728 'linear':455 'listen':980 'll':577,893,955,1012 'look':145 'lose':873 'low':726 'lr':165 'm':1095 'mandatori':360,483 'manual':634,640,921,1002,1005,1062 'mark':1177 'matter':575 'maxretri':452 'mean':149,752,963,1105 'messag':373 'method':1339 'might':595,599,604 'min':725 'minim':39,266,403,542,1203 'minut':865 'miss':379,605,1199 'mock':321,333,335,341,352,1221,1271,1318,1329,1343 'mockrejectedvalueonc':323,326 'mockresolvedvalueonc':329 'multipl':1170 'must':1270 'nall':202 'name':309,339,348,520,547,558 'nclean':209 'ncorrect':183 'need':965,1173 'never':361,611,1306 'new':80,290,324,327,438,1181 'next':217,219,257,258,531,535 'nfailur':235 'ngreen':254 'nminim':189 'noth':594,900 'npm':364,485,1139,1163 'number':453,459 'nwrite':169 'obscur':568 'one':265,313,345,543,844 'onretri':457 'oper':276,284,299 'option':451 'order':574 'otherwis':1356 'output':495,1212 'over-engin':463 'overview':21 'partner':91,1261,1364 'pass':42,201,383,409,444,482,490,494,589,591,897,1045,1165,1206,1211 'path/to/test.test.ts':366,487 'pattern':1315 'period':155 'permiss':1366 'pitfal':1327 'pragmat':751,756,786,998,1097 'pressur':671 'prevent':765,1304 'principl':44 'pristin':496,1213 'problem':1242 'product':112,790,1341,1349 'promis':417,418,450,461 'proof':874 'prototyp':93 'prove':593,627,899,1008,1301 'purpos':1070 'qualiti':539 'rankdir':164 'ration':107,878,1056 're':385,396,661,932,1014,1024 're-run':395,660,931 're-test':1013 'read':1322 'real':311,349,742,1219,1333 'realiti':880 'reason':1197 'record':653,928 'red':157,166,168,179,222,224,226,231,232,259,260,356,1032,1119,1137 'red-green-refactor':156 'refactor':84,159,206,208,241,249,470,511,780,1166 'refer':135,950,1079 'regress':766,1305 'reject':1122 'rememb':839,859 'remov':517 'repeat':530 'reproduc':1295 'requir':344,836,1135,1144,1159 'result':296,301,1127 'result.error':1132 'retri':274,317 'retryoper':298,332,415,448 'return':293,427,1156 'rewrit':710 'right':61 'ritual':802,1076 'rule':68,75,1348 'run':397,662,684,933 'saw':612 'second':891 'see':623 'setup':1280 'shape':172,184,191,204,211,220 'shortcut':787 'show':268,563,774 'simpl':882,885 'simplest':406 'simplifi':1268,1286 'skill':29 'skill-test-driven-development' 'skip':99,362,1236 'slow':991 'slower':791 'solut':1243 'someth':631 'source-rkz91' 'spent':1085 'spirit':72,800,1074 'split':548 'start':24,126,973,1036,1108,1238 'stay':253 'still':493,1284 'stop':104,1034 'stuck':1241 'style':174,193,213 'submitform':1129,1150 'success':294,303,330 'sunk':697,939 'systemat':682,926 'take':889 'tdd':20,100,162,712,747,754,869,975,989,994,1091,1111,1237,1298,1358 'technic':745,946 'test':2,17,26,33,51,59,117,123,142,154,171,263,267,273,310,316,340,365,368,382,386,390,391,411,477,486,489,492,500,505,507,524,533,538,550,561,579,585,596,600,618,625,630,635,641,649,657,680,722,743,767,773,783,792,805,813,821,829,846,855,867,875,884,888,894,896,901,907,914,922,952,960,976,982,985,1000,1003,1015,1022,1028,1040,1041,1044,1051,1053,1063,1065,1121,1140,1164,1185,1188,1193,1208,1210,1217,1249,1262,1279,1294,1300,1311,1312,1320,1328,1337,1351 'test-driven':16,25 'test-driven-develop':1 'test-first':617,999 'test-on':1336 'test1':562 'testing-anti-patterns.md':1323 'tests-aft':804,820,854,906 'tests-first':812,845,913 'thing':62,314,544,598 'think':98,647 'throw':289,435,437,970 'throwaway':92 'time':278,689,701 'tobe':302,306,1133 'tohavebeencalledtim':336 'topic-agent-skills' 'topic-agents-md' 'topic-ai-agents' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-developer-tools' 'topic-llm-tools' 'topic-mcp' 'topic-pm-tools' 'topic-product-management' 'topic-productivity' 'tri':426,676 'trim':1155 'trust':738 'typescript':272,315,412,445,1120,1148 'typo':381,1201 'unavoid':354,1224 'unclear':979 'undefin':1146 'understand':1345 'unless':353 'unreach':440 'unverifi':943 'use':5,78,777,988,1218,1276 'util':1321 'vagu':338 'valid':551,1168 'verif':1174 'verifi':178,181,197,200,223,225,230,237,239,244,250,255,355,478,582,838,857,1136,1160 'violat':63,70 'void':460 'warn':499,1216 'wast':696,731,938,1090 'watch':35,49,357,480,1186 'way':687 'whitespac':556 'wish':1252 'wished-for':1251 'without':114,741,1309,1344,1361 'work':318,584,673,694,739,876,1178 'write':13,31,38,119,141,261,264,405,578,951,1250,1255,1292 'written':586 'wrong':234,597 'wrote':1202 'x':691,713,935,1086 'yagni':462 'yes':229,243","prices":[{"id":"53b29743-1db3-4a8c-876f-f8094b30217e","listingId":"d4f6c62b-e3e9-451e-b2dc-996c64bd46af","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"rkz91","category":"coco","install_from":"skills.sh"},"createdAt":"2026-05-18T13:21:43.089Z"}],"sources":[{"listingId":"d4f6c62b-e3e9-451e-b2dc-996c64bd46af","source":"github","sourceId":"rkz91/coco/test-driven-development","sourceUrl":"https://github.com/rkz91/coco/tree/main/skills/test-driven-development","isPrimary":false,"firstSeenAt":"2026-05-18T13:21:43.089Z","lastSeenAt":"2026-05-18T19:14:09.618Z"}],"details":{"listingId":"d4f6c62b-e3e9-451e-b2dc-996c64bd46af","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"rkz91","slug":"test-driven-development","github":{"repo":"rkz91/coco","stars":7,"topics":["agent-skills","agents-md","ai","ai-agents","claude-code","codex","cursor","developer-tools","llm-tools","mcp","pm-tools","product-management","productivity","prompt-engineering","workflow-automation"],"license":"mit","html_url":"https://github.com/rkz91/coco","pushed_at":"2026-04-26T01:51:27Z","description":"Open-source library of AI superpowers — 59 skills, 34 commands, 10 agents + 24 GSD subagents, 3 system bundles. An entire team, wherever your AI lives. Vendor-neutral across Claude Code, Cursor, Codex, and any AGENTS.md tool.","skill_md_sha":"ac70725e1a6e36b32b739e9c3e33caad952d5bf2","skill_md_path":"skills/test-driven-development/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/rkz91/coco/tree/main/skills/test-driven-development"},"layout":"multi","source":"github","category":"coco","frontmatter":{"name":"test-driven-development","description":"Use when implementing any feature or bugfix, before writing implementation code"},"skills_sh_url":"https://skills.sh/rkz91/coco/test-driven-development"},"updatedAt":"2026-05-18T19:14:09.618Z"}}