[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7828XRRT4PNQSWB16MD2N2F":3,"skill-same:01M7828XRRT4PNQSWB16MD2N2F":53},{"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":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":27,"repositoryHtmlUrl":28,"repositoryHomepageUrl":6,"ownerHtmlUrl":29,"ownerBlogUrl":30,"ownerDescription":31,"updatedAt":32,"install":33,"resources":46},"01M7828XRRT4PNQSWB16MD2N2F","tdd",null,"Test-driven development with vertical tracer-bullet slices. Use when building test-first, red-green-refactor, or when the user mentions TDD.","stainless-code\u002Fpersist","stainless-code","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F188862219?v=4","01M7826VYMCF2NTQWQZRWQ454T","STAINLESS CODE","01M7826VZKNC149Y9ZNK0F93N7",5,"MIT","https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Ftdd\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: tdd\ndescription: Test-driven development with vertical tracer-bullet slices. Use when building test-first, red-green-refactor, or when the user mentions TDD.\n---\n\n# Test-driven development\n\nVertical RED→GREEN cycles — **one behavior per loop**, not horizontal \"all tests then all code\". Aligns with [`tracer-bullets`](..\u002F..\u002Frules\u002Ftracer-bullets.md) and [`verify-after-each-step`](..\u002F..\u002Frules\u002Fverify-after-each-step.md).\n\n## This repo\n\n- Runner split per `docs\u002Farchitecture.md` § Test matrix:\n  - `bun test \u003Cco-located *.test.ts>` — `src\u002F**` unit tests (core, codecs, backends, TanStack adapters, `useHydrated` SSR\u002Fsnapshot contracts). No DOM.\n  - `bun run test:dom` — `tests-dom\u002F**\u002F*.test.tsx` (vitest + jsdom + @testing-library\u002Freact) for `useHydrated` rerender \u002F unmount \u002F `useSyncExternalStore` reactivity.\n- Co-locate tests next to the module (`src\u002Fcore\u002Fpersist-core.ts` → `src\u002Fcore\u002Fpersist-core.test.ts`).\n- After each GREEN: format\u002Flint\u002Ftypecheck per [`verify-after-each-step`](..\u002F..\u002Frules\u002Fverify-after-each-step.md).\n- Mock at the **storage backend seam** (`StateStorage`), never inside `persist-core` or a codec. See [`PATTERNS.md`](.\u002FPATTERNS.md).\n\n## Workflow\n\n### 1. Planning\n\nConfirm **behaviors** to test (not implementation steps) with the user. Prefer deep modules — small public surface (`persistSource`, `createStorage`, a codec factory), complex internals.\n\n### 2. Tracer bullet (within slice)\n\n```\nRED:   one test for first behavior → bun test \u003Cfile>   (or test:dom for hydration rerenders)\nGREEN: minimal code to pass → re-run\n```\n\n### 3. Incremental loop\n\nFor each behavior: RED → GREEN → run affected tests. One test at a time; no speculative features.\n\n### 4. Refactor\n\nAfter GREEN — look for duplication, long methods, shallow modules, feature envy. Run `bun test \u003Cfile>` after each step. **Never refactor while RED.** For production polish on a completed slice, [`harden-pr`](..\u002Fharden-pr\u002FSKILL.md) lite may run in parallel with tracer-bullet commits.\n\n## Checklist per cycle\n\n```\n[ ] Test describes behavior, not implementation\n[ ] Test uses the public seam only (persistSource \u002F createStorage \u002F a codec \u002F useHydrated)\n[ ] Test would survive an internal refactor\n[ ] Code is minimal for this test\n[ ] bun test (or test:dom) passes on touched file(s)\n```\n\n## Reference\n\n- Good\u002Fbad test patterns + mock boundaries: [`PATTERNS.md`](.\u002FPATTERNS.md)\n- Slice cadence: [`tracer-bullets`](..\u002F..\u002Frules\u002Ftracer-bullets.md) · Verify: [`verify-after-each-step`](..\u002F..\u002Frules\u002Fverify-after-each-step.md)\n","# Test-driven development\n\nVertical RED→GREEN cycles — **one behavior per loop**, not horizontal \"all tests then all code\". Aligns with [`tracer-bullets`](..\u002F..\u002Frules\u002Ftracer-bullets.md) and [`verify-after-each-step`](..\u002F..\u002Frules\u002Fverify-after-each-step.md).\n\n## This repo\n\n- Runner split per `docs\u002Farchitecture.md` § Test matrix:\n  - `bun test \u003Cco-located *.test.ts>` — `src\u002F**` unit tests (core, codecs, backends, TanStack adapters, `useHydrated` SSR\u002Fsnapshot contracts). No DOM.\n  - `bun run test:dom` — `tests-dom\u002F**\u002F*.test.tsx` (vitest + jsdom + @testing-library\u002Freact) for `useHydrated` rerender \u002F unmount \u002F `useSyncExternalStore` reactivity.\n- Co-locate tests next to the module (`src\u002Fcore\u002Fpersist-core.ts` → `src\u002Fcore\u002Fpersist-core.test.ts`).\n- After each GREEN: format\u002Flint\u002Ftypecheck per [`verify-after-each-step`](..\u002F..\u002Frules\u002Fverify-after-each-step.md).\n- Mock at the **storage backend seam** (`StateStorage`), never inside `persist-core` or a codec. See [`PATTERNS.md`](.\u002FPATTERNS.md).\n\n## Workflow\n\n### 1. Planning\n\nConfirm **behaviors** to test (not implementation steps) with the user. Prefer deep modules — small public surface (`persistSource`, `createStorage`, a codec factory), complex internals.\n\n### 2. Tracer bullet (within slice)\n\n```\nRED:   one test for first behavior → bun test \u003Cfile>   (or test:dom for hydration rerenders)\nGREEN: minimal code to pass → re-run\n```\n\n### 3. Incremental loop\n\nFor each behavior: RED → GREEN → run affected tests. One test at a time; no speculative features.\n\n### 4. Refactor\n\nAfter GREEN — look for duplication, long methods, shallow modules, feature envy. Run `bun test \u003Cfile>` after each step. **Never refactor while RED.** For production polish on a completed slice, [`harden-pr`](..\u002Fharden-pr\u002FSKILL.md) lite may run in parallel with tracer-bullet commits.\n\n## Checklist per cycle\n\n```\n[ ] Test describes behavior, not implementation\n[ ] Test uses the public seam only (persistSource \u002F createStorage \u002F a codec \u002F useHydrated)\n[ ] Test would survive an internal refactor\n[ ] Code is minimal for this test\n[ ] bun test (or test:dom) passes on touched file(s)\n```\n\n## Reference\n\n- Good\u002Fbad test patterns + mock boundaries: [`PATTERNS.md`](.\u002FPATTERNS.md)\n- Slice cadence: [`tracer-bullets`](..\u002F..\u002Frules\u002Ftracer-bullets.md) · Verify: [`verify-after-each-step`](..\u002F..\u002Frules\u002Fverify-after-each-step.md)\n",{"name":5,"description":7},"main","29ca2183c92cd13e04ce6c14fb431fd6993862cd",".agents\u002Fskills\u002Ftdd",0,"https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist","https:\u002F\u002Fgithub.com\u002Fstainless-code","https:\u002F\u002Fstainless-code.com\u002F","Open-source tooling for JS\u002FTS and AI agents.","2026-11-01 20:56:20",{"source":8,"skillName":5,"commands":34,"prompt":44,"zipAvailable":45},[35,38,41],{"tool":36,"command":37},"npx","npx skills add stainless-code\u002Fpersist --skill tdd",{"tool":39,"command":40},"bunx","bunx skills add stainless-code\u002Fpersist --skill tdd",{"tool":42,"command":43},"pnpm","pnpm dlx skills add stainless-code\u002Fpersist --skill tdd","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Ftdd\u002FSKILL.md",true,[47],{"path":48,"resourceType":49,"resourceTypeDesc":50,"sizeBytes":51,"sourceHtmlUrl":52},"PATTERNS.md","REFERENCE","参考文档",4291,"https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Ftdd\u002FPATTERNS.md",[54,61,68,75,82,89],{"skillNo":55,"name":56,"nameZh":6,"description":57,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":58,"categories":59,"keywords":60,"publishedAt":19},"01M782D4ZQGJPNT470FSKDB6A8","vue-persist","Gate Vue 3 UI on Persist hydration with useHydrated (shallowRef). Use in setup\u002FeffectScope when avoiding flash of default state on async backends.","https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist\u002Fblob\u002Fmain\u002Fskills\u002Fvue-persist\u002FSKILL.md",[],[],{"skillNo":62,"name":63,"nameZh":6,"description":64,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":65,"categories":66,"keywords":67,"publishedAt":19},"01M782D1GJRWNQ3458F3H1FK2F","svelte-store-persist","Gate Svelte store-based UI on Persist hydration with hydratedStore (Readable). Use for Svelte 3–4 or Svelte 5 apps that still use stores; runes UI → svelte-persist.","https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist\u002Fblob\u002Fmain\u002Fskills\u002Fsvelte-store-persist\u002FSKILL.md",[],[],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":74,"publishedAt":19},"01M782CWBTRWAQ52TBNQ8665CC","svelte-persist","Gate Svelte 5 runes UI on Persist hydration with hydratedRune (.current). Use for Svelte 5; for stores \u002F Svelte 3–4 use svelte-store-persist.","https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist\u002Fblob\u002Fmain\u002Fskills\u002Fsvelte-persist\u002FSKILL.md",[],[],{"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":19},"01M782CR8Z2V3SJW661RTMWY2F","solid-persist","Gate Solid UI on Persist hydration with useHydrated (Accessor). Use when avoiding flash of default state on async backends; read hydrated() in reactive scopes.","https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist\u002Fblob\u002Fmain\u002Fskills\u002Fsolid-persist\u002FSKILL.md",[],[],{"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":19},"01M782CJQGP7739WA9BS801HZP","react-persist","Gate React UI on Persist hydration with useHydrated + toHydrationSignal. Use when avoiding flash of default state on async backends (IndexedDB), SSR snapshot true, or wiring HydrationSignal into React 18\u002F19.","https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist\u002Fblob\u002Fmain\u002Fskills\u002Freact-persist\u002FSKILL.md",[],[],{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":95,"publishedAt":19},"01M782CF96RMXCDETM5TF2JDRV","preact-persist","Gate Preact UI on Persist hydration with useHydrated (preact\u002Fcompat useSyncExternalStore). Use when avoiding flash of default state on async backends or wiring HydrationSignal into Preact.","https:\u002F\u002Fgithub.com\u002Fstainless-code\u002Fpersist\u002Fblob\u002Fmain\u002Fskills\u002Fpreact-persist\u002FSKILL.md",[],[]]