[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M719D51F1VSFZP0MZB3W12AM":3,"skill-same:01M719D51F1VSFZP0MZB3W12AM":54},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":28,"linkOnly":29,"markdownContent":30,"markdownBody":31,"frontMatter":32,"refName":33,"commitSha":34,"skillDirectory":35,"forksCount":36,"repositoryHtmlUrl":37,"repositoryHomepageUrl":6,"ownerHtmlUrl":38,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":39,"install":40,"resources":53},"01M719D51F1VSFZP0MZB3W12AM","squad-conventions",null,"Core conventions and patterns used in the Squad codebase","DeDuva\u002Fsquad","DeDuva","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F8153108?v=4","01M719BQB25861D0TKS3RVHMN2","01M719BQBSWR380PSYDD5M9YD4",1,"MIT","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002F.squad-templates\u002Fskills\u002Fsquad-conventions\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27],"squad conventions","conventions","squad","project-conventions","core","project","manual","high","codebase","patterns","2026-11-10 10:12:30",false,"---\nname: \"squad-conventions\"\ndescription: \"Core conventions and patterns used in the Squad codebase\"\ndomain: \"project-conventions\"\nconfidence: \"high\"\nsource: \"manual\"\n---\n\n## Context\nThese conventions apply to all work on the Squad CLI tool (`create-squad`). Squad is a zero-dependency Node.js package that adds AI agent teams to any project. Understanding these patterns is essential before modifying any Squad source code.\n\n## Patterns\n\n### Zero Dependencies\nSquad has zero runtime dependencies. Everything uses Node.js built-ins (`fs`, `path`, `os`, `child_process`). Do not add packages to `dependencies` in `package.json`. This is a hard constraint, not a preference.\n\n### Node.js Built-in Test Runner\nTests use `node:test` and `node:assert\u002Fstrict` — no test frameworks. Run with `npm test`. Test files live in `test\u002F`. The test command is `node --test test\u002F`.\n\n### Error Handling — `fatal()` Pattern\nAll user-facing errors use the `fatal(msg)` function which prints a red `✗` prefix and exits with code 1. Never throw unhandled exceptions or print raw stack traces. The global `uncaughtException` handler calls `fatal()` as a safety net.\n\n### ANSI Color Constants\nColors are defined as constants at the top of `index.js`: `GREEN`, `RED`, `DIM`, `BOLD`, `RESET`. Use these constants — do not inline ANSI escape codes.\n\n### File Structure\n- `.squad\u002F` — Team state (user-owned, never overwritten by upgrades)\n- `.squad\u002Ftemplates\u002F` — Template files copied from `templates\u002F` (Squad-owned, overwritten on upgrade)\n- `.github\u002Fagents\u002Fsquad.agent.md` — Coordinator prompt (Squad-owned, overwritten on upgrade)\n- `templates\u002F` — Source templates shipped with the npm package\n- `.squad\u002Fskills\u002F` — Team skills in SKILL.md format (user-owned)\n- `.squad\u002Fdecisions\u002Finbox\u002F` — Drop-box for parallel decision writes\n\n### Windows Compatibility\nAlways use `path.join()` for file paths — never hardcode `\u002F` or `\\` separators. Squad must work on Windows, macOS, and Linux. All tests must pass on all platforms.\n\n### Init Idempotency\nThe init flow uses a skip-if-exists pattern: if a file or directory already exists, skip it and report \"already exists.\" Never overwrite user state during init. The upgrade flow overwrites only Squad-owned files.\n\n### Copy Pattern\n`copyRecursive(src, target)` handles both files and directories. It creates parent directories with `{ recursive: true }` and uses `fs.copyFileSync` for files.\n\n## Examples\n\n```javascript\n\u002F\u002F Error handling\nfunction fatal(msg) {\n  console.error(`${RED}✗${RESET} ${msg}`);\n  process.exit(1);\n}\n\n\u002F\u002F File path construction (Windows-safe)\nconst agentDest = path.join(dest, '.github', 'agents', 'squad.agent.md');\n\n\u002F\u002F Skip-if-exists pattern\nif (!fs.existsSync(ceremoniesDest)) {\n  fs.copyFileSync(ceremoniesSrc, ceremoniesDest);\n  console.log(`${GREEN}✓${RESET} .squad\u002Fceremonies.md`);\n} else {\n  console.log(`${DIM}ceremonies.md already exists — skipping${RESET}`);\n}\n```\n\n## Anti-Patterns\n- **Adding npm dependencies** — Squad is zero-dep. Use Node.js built-ins only.\n- **Hardcoded path separators** — Never use `\u002F` or `\\` directly. Always `path.join()`.\n- **Overwriting user state on init** — Init skips existing files. Only upgrade overwrites Squad-owned files.\n- **Raw stack traces** — All errors go through `fatal()`. Users see clean messages, not stack traces.\n- **Inline ANSI codes** — Use the color constants (`GREEN`, `RED`, `DIM`, `BOLD`, `RESET`).\n","## Context\nThese conventions apply to all work on the Squad CLI tool (`create-squad`). Squad is a zero-dependency Node.js package that adds AI agent teams to any project. Understanding these patterns is essential before modifying any Squad source code.\n\n## Patterns\n\n### Zero Dependencies\nSquad has zero runtime dependencies. Everything uses Node.js built-ins (`fs`, `path`, `os`, `child_process`). Do not add packages to `dependencies` in `package.json`. This is a hard constraint, not a preference.\n\n### Node.js Built-in Test Runner\nTests use `node:test` and `node:assert\u002Fstrict` — no test frameworks. Run with `npm test`. Test files live in `test\u002F`. The test command is `node --test test\u002F`.\n\n### Error Handling — `fatal()` Pattern\nAll user-facing errors use the `fatal(msg)` function which prints a red `✗` prefix and exits with code 1. Never throw unhandled exceptions or print raw stack traces. The global `uncaughtException` handler calls `fatal()` as a safety net.\n\n### ANSI Color Constants\nColors are defined as constants at the top of `index.js`: `GREEN`, `RED`, `DIM`, `BOLD`, `RESET`. Use these constants — do not inline ANSI escape codes.\n\n### File Structure\n- `.squad\u002F` — Team state (user-owned, never overwritten by upgrades)\n- `.squad\u002Ftemplates\u002F` — Template files copied from `templates\u002F` (Squad-owned, overwritten on upgrade)\n- `.github\u002Fagents\u002Fsquad.agent.md` — Coordinator prompt (Squad-owned, overwritten on upgrade)\n- `templates\u002F` — Source templates shipped with the npm package\n- `.squad\u002Fskills\u002F` — Team skills in SKILL.md format (user-owned)\n- `.squad\u002Fdecisions\u002Finbox\u002F` — Drop-box for parallel decision writes\n\n### Windows Compatibility\nAlways use `path.join()` for file paths — never hardcode `\u002F` or `\\` separators. Squad must work on Windows, macOS, and Linux. All tests must pass on all platforms.\n\n### Init Idempotency\nThe init flow uses a skip-if-exists pattern: if a file or directory already exists, skip it and report \"already exists.\" Never overwrite user state during init. The upgrade flow overwrites only Squad-owned files.\n\n### Copy Pattern\n`copyRecursive(src, target)` handles both files and directories. It creates parent directories with `{ recursive: true }` and uses `fs.copyFileSync` for files.\n\n## Examples\n\n```javascript\n\u002F\u002F Error handling\nfunction fatal(msg) {\n  console.error(`${RED}✗${RESET} ${msg}`);\n  process.exit(1);\n}\n\n\u002F\u002F File path construction (Windows-safe)\nconst agentDest = path.join(dest, '.github', 'agents', 'squad.agent.md');\n\n\u002F\u002F Skip-if-exists pattern\nif (!fs.existsSync(ceremoniesDest)) {\n  fs.copyFileSync(ceremoniesSrc, ceremoniesDest);\n  console.log(`${GREEN}✓${RESET} .squad\u002Fceremonies.md`);\n} else {\n  console.log(`${DIM}ceremonies.md already exists — skipping${RESET}`);\n}\n```\n\n## Anti-Patterns\n- **Adding npm dependencies** — Squad is zero-dep. Use Node.js built-ins only.\n- **Hardcoded path separators** — Never use `\u002F` or `\\` directly. Always `path.join()`.\n- **Overwriting user state on init** — Init skips existing files. Only upgrade overwrites Squad-owned files.\n- **Raw stack traces** — All errors go through `fatal()`. Users see clean messages, not stack traces.\n- **Inline ANSI codes** — Use the color constants (`GREEN`, `RED`, `DIM`, `BOLD`, `RESET`).\n",{"name":5,"domain":21,"source":24,"confidence":25,"description":7},"dev","4ffda80d1bb1043d9169688cf161e53097345c72",".squad-templates\u002Fskills\u002Fsquad-conventions",0,"https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad","https:\u002F\u002Fgithub.com\u002FDeDuva","2026-11-09 20:24:44",{"source":8,"skillName":5,"commands":41,"prompt":51,"zipAvailable":52},[42,45,48],{"tool":43,"command":44},"npx","npx skills add DeDuva\u002Fsquad --skill squad-conventions",{"tool":46,"command":47},"bunx","bunx skills add DeDuva\u002Fsquad --skill squad-conventions",{"tool":49,"command":50},"pnpm","pnpm dlx skills add DeDuva\u002Fsquad --skill squad-conventions","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002F.squad-templates\u002Fskills\u002Fsquad-conventions\u002FSKILL.md",true,[],[55,71,79,84,108,123],{"skillNo":56,"name":57,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":58,"categories":59,"keywords":65,"publishedAt":28},"01M719NE6ZPZT80MKVWFDECJZ3","My Skill","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftest-fixtures\u002Fskills-test-abb30454\u002Fmy-skill\u002FSKILL.md",[60],{"categoryNo":61,"categoryName":62,"taxonomyType":63,"taxonomyTypeDesc":64},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[66,67,68,69,70],"my","my skill","testing","vitest","tester",{"skillNo":72,"name":73,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":28},"01M719NDJAMEWM8D9H355SCNA8","bad-skill","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftest-fixtures\u002Fskills-test-abb30454\u002Fbad-skill\u002FSKILL.md",[],[77,78],"bad skill","bad",{"skillNo":80,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":28},"01M719NCC1AZ02GHZ1V71YPEV7","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fsquad-conventions\u002FSKILL.md",[],[19,20,18,21,22,23,24,25,26,27],{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":90,"publishedAt":28},"01M719NAYM17B7X8MGP681EHKQ","rework-rate","Measure and interpret PR rework rate — the emerging 5th DORA metric","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Frework-rate\u002FSKILL.md",[],[91,92,93,94,25,95,96,97,20,98,99,100,101,24,102,103,104,105,106,107],"rate","rework rate","health","analyze","review efficiency","quality","metric","metrics","efficiency","code quality","pr","prs","when","code","team","code-review","review",{"skillNo":109,"name":110,"nameZh":6,"description":111,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":114,"publishedAt":28},"01M719NA136PDC3SQ10R4R88TH","nap","Context hygiene — compress, prune, archive .squad\u002F state","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fnap\u002FSKILL.md",[],[110,115,116,117,118,119,120,121,20,122],"prune","state","maintenance","context hygiene","archive","hygiene","compress","context",{"skillNo":124,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":127,"categories":128,"keywords":133,"publishedAt":28},"01M719N7B4PBQPNXW78TEJY4HQ","e2e-template-testing","End-to-end validation of coordinator and agent template changes","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fe2e-template-testing\u002FSKILL.md",[129,132],{"categoryNo":130,"categoryName":131,"taxonomyType":63,"taxonomyTypeDesc":64},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":61,"categoryName":62,"taxonomyType":63,"taxonomyTypeDesc":64},[68,134,135,136,137,138,139,24,140,25,141],"e2e template testing","e2e","template","end","coordinator","development","changes","validation"]