[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7AFN9TVR1D257PPCXW5VTWM":3,"skill-same:01M7AFN9TVR1D257PPCXW5VTWM":51},{"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":28,"ownerHtmlUrl":29,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":30,"install":31,"resources":44},"01M7AFN9TVR1D257PPCXW5VTWM","trove-typescript",null,"TypeScript type-system discipline for any .ts\u002F.tsx file: make illegal states unrepresentable, validate at boundaries, avoid as\u002Fany. Use when reading or editing TypeScript that isn't covered by a framework-specific skill. Defers to trove-react \u002F trove-react-best-practices on .tsx component work. Use when: typescript best practices; type this correctly; make illegal states unrepresentable.","bravew\u002Ftrove","bravew","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F10855844?v=4","01M7ACJ91JZSQYHT81XPVYR7VA","Yong","01M7AFERNR92HDPGNGP5QA16DM",10,"MIT","https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove\u002Fblob\u002Fmain\u002Fplugins\u002Ftrove-dev\u002F.copilot\u002Fskills\u002Ftrove-typescript\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: trove-typescript\ndescription: \"TypeScript type-system discipline for any .ts\u002F.tsx file: make illegal states unrepresentable, validate at boundaries, avoid as\u002Fany. Use when reading or editing TypeScript that isn't covered by a framework-specific skill. Defers to trove-react \u002F trove-react-best-practices on .tsx component work. Use when: typescript best practices; type this correctly; make illegal states unrepresentable.\"\n---\n\u003C!-- AUTO-GENERATED from SKILL.md.tmpl — do not edit directly -->\n\u003C!-- Regenerate: bun run build:skills -->\n\n## Session Init\n\nThis skill ships Trove conventions. Prefer existing project patterns over generic best practices when they conflict.\n\nIf a sibling skill in this plugin matches the request more directly, defer to it. See `AGENTS.md` (or `docs\u002Frouting.md` in the marketplace) for the per-plugin routing index.\n\n# TypeScript Type-System Discipline\n\nThe type checker is a proof assistant. Model the domain so wrong states don't compile. On `.tsx`, defer to `trove-react` \u002F `trove-react-best-practices` for component patterns; this skill owns the plain type discipline underneath them.\n\n## Core rules\n\n| Rule | Do | Not |\n|---|---|---|\n| Illegal states | Discriminated union with a `kind`\u002F`status` tag | `boolean` + optional field pairs |\n| Identity | Branded primitives (`string & { readonly __brand: 'UserId' }`) | bare `string` for ids |\n| External data | `unknown` + parse at the boundary | `any` |\n| Casts | `satisfies` to check shape while keeping literals | `as SomeType` |\n| Exhaustiveness | `const _exhaustive: never = x` in the default branch | unhandled union members |\n| Type guards | Guards that actually narrow and are verified | `x as Foo` inside the guard |\n| Derive | Types derived from a schema (Zod\u002Fvalibot `infer`) | hand-kept parallel types |\n\n## The canonical example\n\n```ts\n\u002F\u002F BAD — admits the meaningless { completed: true, completedAt: undefined }\ntype Task = { completed: boolean; completedAt?: Date };\n\n\u002F\u002F GOOD — the bad state cannot be constructed\ntype Task =\n  | { status: 'open' }\n  | { status: 'done'; completedAt: Date };\n```\n\n## Boundaries\n\nValidate once, at the edge (network, config, user input). Past the boundary, trust your domain types and keep logic pure. \"Parse, don't validate\": a parser returns a more precise type or fails; it doesn't just check and discard what it learned.\n\n```ts\nfunction parseUser(raw: unknown): User {\n  return UserSchema.parse(raw); \u002F\u002F unknown -> User, or throws at the boundary\n}\n```\n\nSee [references\u002Fpatterns.md](references\u002Fpatterns.md) for the full pattern set with worked examples.\n\n## AI Gotchas\n\n- **`as` to silence an error** hides the bug you'll debug next week. Reach for narrowing or `satisfies` first.\n- **`any` on external data** erases the boundary. Use `unknown` and parse.\n- **Non-exhaustive `switch`** over a union compiles today and breaks when a variant is added. Add the `never` guard.\n- **Parallel hand-maintained types** drift. Derive from the schema.\n","\u003C!-- AUTO-GENERATED from SKILL.md.tmpl — do not edit directly -->\n\u003C!-- Regenerate: bun run build:skills -->\n\n## Session Init\n\nThis skill ships Trove conventions. Prefer existing project patterns over generic best practices when they conflict.\n\nIf a sibling skill in this plugin matches the request more directly, defer to it. See `AGENTS.md` (or `docs\u002Frouting.md` in the marketplace) for the per-plugin routing index.\n\n# TypeScript Type-System Discipline\n\nThe type checker is a proof assistant. Model the domain so wrong states don't compile. On `.tsx`, defer to `trove-react` \u002F `trove-react-best-practices` for component patterns; this skill owns the plain type discipline underneath them.\n\n## Core rules\n\n| Rule | Do | Not |\n|---|---|---|\n| Illegal states | Discriminated union with a `kind`\u002F`status` tag | `boolean` + optional field pairs |\n| Identity | Branded primitives (`string & { readonly __brand: 'UserId' }`) | bare `string` for ids |\n| External data | `unknown` + parse at the boundary | `any` |\n| Casts | `satisfies` to check shape while keeping literals | `as SomeType` |\n| Exhaustiveness | `const _exhaustive: never = x` in the default branch | unhandled union members |\n| Type guards | Guards that actually narrow and are verified | `x as Foo` inside the guard |\n| Derive | Types derived from a schema (Zod\u002Fvalibot `infer`) | hand-kept parallel types |\n\n## The canonical example\n\n```ts\n\u002F\u002F BAD — admits the meaningless { completed: true, completedAt: undefined }\ntype Task = { completed: boolean; completedAt?: Date };\n\n\u002F\u002F GOOD — the bad state cannot be constructed\ntype Task =\n  | { status: 'open' }\n  | { status: 'done'; completedAt: Date };\n```\n\n## Boundaries\n\nValidate once, at the edge (network, config, user input). Past the boundary, trust your domain types and keep logic pure. \"Parse, don't validate\": a parser returns a more precise type or fails; it doesn't just check and discard what it learned.\n\n```ts\nfunction parseUser(raw: unknown): User {\n  return UserSchema.parse(raw); \u002F\u002F unknown -> User, or throws at the boundary\n}\n```\n\nSee [references\u002Fpatterns.md](references\u002Fpatterns.md) for the full pattern set with worked examples.\n\n## AI Gotchas\n\n- **`as` to silence an error** hides the bug you'll debug next week. Reach for narrowing or `satisfies` first.\n- **`any` on external data** erases the boundary. Use `unknown` and parse.\n- **Non-exhaustive `switch`** over a union compiles today and breaks when a variant is added. Add the `never` guard.\n- **Parallel hand-maintained types** drift. Derive from the schema.\n",{"name":5,"description":7},"main","f88db1f1cf0e0703dd962051ebc142db961d7799","plugins\u002Ftrove-dev\u002F.copilot\u002Fskills\u002Ftrove-typescript",1,"https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove","https:\u002F\u002Fgithub.com\u002Fbravew","2026-11-12 07:56:32",{"source":8,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add bravew\u002Ftrove --skill trove-typescript",{"tool":37,"command":38},"bunx","bunx skills add bravew\u002Ftrove --skill trove-typescript",{"tool":40,"command":41},"pnpm","pnpm dlx skills add bravew\u002Ftrove --skill trove-typescript","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove\u002Fblob\u002Fmain\u002Fplugins\u002Ftrove-dev\u002F.copilot\u002Fskills\u002Ftrove-typescript\u002FSKILL.md",true,[45],{"path":46,"resourceType":47,"resourceTypeDesc":48,"sizeBytes":49,"sourceHtmlUrl":50},"references\u002Fpatterns.md","REFERENCE","参考文档",3035,"https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove\u002Fblob\u002Fmain\u002Fplugins\u002Ftrove-dev\u002F.copilot\u002Fskills\u002Ftrove-typescript\u002Freferences\u002Fpatterns.md",[52,59,66,73,80,87],{"skillNo":53,"name":54,"nameZh":6,"description":55,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":56,"categories":57,"keywords":58,"publishedAt":19},"01M7AGJDHTQAS1VK6P7VJAV79G","using-trove","Skill discipline anchor for the Trove marketplace. Loaded once per session; routes the agent to the right trove-* skill before code, planning, review, or git actions.","https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fusing-trove\u002FSKILL.md",[],[],{"skillNo":60,"name":61,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":65,"publishedAt":19},"01M7AGJAS4V4TXE6TV6F839BGZ","trove-write-skill","Skill authoring workflow. Use when creating or updating a Codex or Trove skill, including rubrics, tasks, metadata, and validation.","https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Ftrove-write-skill\u002FSKILL.md",[],[],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":70,"categories":71,"keywords":72,"publishedAt":19},"01M7AGJ87K41ZAC8DDBAV17QFW","trove-worktree","Git worktree workflow for spikes, risky experiments, and broad refactors that should not disturb the user's current branch.","https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Ftrove-worktree\u002FSKILL.md",[],[],{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":79,"publishedAt":19},"01M7AGJ32V58VYBFYMS9EMHRY4","trove-why","Reconstruct design rationale and decision history from evidence — source control, issue tracker (Linear), docs (Notion), chat (Slack), error tracking (Sentry) — with calibrated confidence. Use for \"why does X work this way\", \"why did we pick Y\", regressions, and postmortems. Use trove-explain for how it works now.","https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Ftrove-why\u002FSKILL.md",[],[],{"skillNo":81,"name":82,"nameZh":6,"description":83,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":86,"publishedAt":19},"01M7AGJ0FHJSRR8MMXC3V8XNHF","trove-verify","Completion verification workflow. Use before claiming done, fixed, complete, ready, or shipped.","https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Ftrove-verify\u002FSKILL.md",[],[],{"skillNo":88,"name":89,"nameZh":6,"description":90,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":91,"categories":92,"keywords":93,"publishedAt":19},"01M7AGHWV4B9SDS60RH5W0B0K5","trove-unslop","Cut AI tells from writing — PR descriptions, release notes, specs, commit bodies, and replies. Use before finalizing prose, or when the user asks to clean up, de-slop, or make text sound human.","https:\u002F\u002Fgithub.com\u002Fbravew\u002Ftrove\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Ftrove-unslop\u002FSKILL.md",[],[]]