[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6R7V9TYTX6Z621V6RWA51G6":3,"skill-same:01M6R7V9TYTX6Z621V6RWA51G6":53},{"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":13,"repositoryHtmlUrl":36,"repositoryHomepageUrl":6,"ownerHtmlUrl":37,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":38,"install":39,"resources":52},"01M6R7V9TYTX6Z621V6RWA51G6","squad-conventions",null,"Core conventions and patterns used in the Squad codebase","barichter\u002Fsquad","barichter","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F96797186?v=4","01M6R712K8ESMDF089BFENBR16","01M6R712R74BSQQSG2GTXBWR8P",0,"MIT","https:\u002F\u002Fgithub.com\u002Fbarichter\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fsquad-conventions\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27],"squad conventions","squad","conventions","core","project-conventions","patterns","project","manual","high","codebase","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":22,"source":25,"confidence":26,"description":7},"dev","ec19f5e92325e634e3c6eff500e3cefa56131cc9","templates\u002Fskills\u002Fsquad-conventions","https:\u002F\u002Fgithub.com\u002Fbarichter\u002Fsquad","https:\u002F\u002Fgithub.com\u002Fbarichter","2026-04-13 22:53:46",{"source":8,"skillName":5,"commands":40,"prompt":50,"zipAvailable":51},[41,44,47],{"tool":42,"command":43},"npx","npx skills add barichter\u002Fsquad --skill squad-conventions",{"tool":45,"command":46},"bunx","bunx skills add barichter\u002Fsquad --skill squad-conventions",{"tool":48,"command":49},"pnpm","pnpm dlx skills add barichter\u002Fsquad --skill squad-conventions","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fbarichter\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fsquad-conventions\u002FSKILL.md",true,[],[54,70,78,101,107,125],{"skillNo":55,"name":56,"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":57,"categories":58,"keywords":64,"publishedAt":28},"01M6R7VE8SZD1E37WWJN4ZFPWB","My Skill","https:\u002F\u002Fgithub.com\u002Fbarichter\u002Fsquad\u002Fblob\u002Fdev\u002Ftest-fixtures\u002Fskills-test-abb30454\u002Fmy-skill\u002FSKILL.md",[59],{"categoryNo":60,"categoryName":61,"taxonomyType":62,"taxonomyTypeDesc":63},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[65,66,67,68,69],"my","my skill","testing","vitest","tester",{"skillNo":71,"name":72,"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":73,"categories":74,"keywords":75,"publishedAt":28},"01M6R7VD19M4TMAA74XGD6QSZX","bad-skill","https:\u002F\u002Fgithub.com\u002Fbarichter\u002Fsquad\u002Fblob\u002Fdev\u002Ftest-fixtures\u002Fskills-test-abb30454\u002Fbad-skill\u002FSKILL.md",[],[76,77],"bad","bad skill",{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":28},"01M6R7TTF0ABMGSVWASVYF6D51","rework-rate","Measure and interpret PR rework rate — the emerging 5th DORA metric","https:\u002F\u002Fgithub.com\u002Fbarichter\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Frework-rate\u002FSKILL.md",[],[85,86,87,88,89,90,91,92,25,26,93,94,95,96,97,98,19,99,100],"rework rate","rate","health","metrics","team","analyze","quality","efficiency","metric","prs","when","review","code quality","pr","code","code-review",{"skillNo":102,"name":103,"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":104,"categories":105,"keywords":106,"publishedAt":28},"01M6R7TRZPET44JRCSQF08EEA8","nap","https:\u002F\u002Fgithub.com\u002Fbarichter\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fnap\u002FSKILL.md",[],[103],{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":114,"publishedAt":28},"01M6R7TK10WCT77A52E27GR5R3","{skill-name}","{what this skill teaches agents}","https:\u002F\u002Fgithub.com\u002Fbarichter\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskill.md",[113],{"categoryNo":60,"categoryName":61,"taxonomyType":62,"taxonomyTypeDesc":63},[115,116,117,118,119,120,121,122,123,124,67,25,26],"name","skill name","{skill name}","api-design","design","api","how","error-handling","learned","error",{"skillNo":126,"name":127,"nameZh":6,"description":128,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":129,"categories":130,"keywords":131,"publishedAt":28},"01M6R7TFPW0ZYH3X400MWQKZJD","windows-compatibility","Cross-platform path handling and command patterns","https:\u002F\u002Fgithub.com\u002Fbarichter\u002Fsquad\u002Fblob\u002Fdev\u002Fpackages\u002Fsquad-sdk\u002Ftemplates\u002Fskills\u002Fwindows-compatibility\u002FSKILL.md",[],[132,133,134,135,23,136,137,138,139,26,140],"windows compatibility","windows","compatibility","cross-platform","command","git","bugs","path","platform"]