| 1 | --- |
| 2 | name: "squad-conventions" |
| 3 | description: "Core conventions and patterns used in the Squad codebase" |
| 4 | domain: "project-conventions" |
| 5 | confidence: "high" |
| 6 | source: "manual" |
| 7 | --- |
| 8 | |
| 9 | ## Context |
| 10 | These 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. |
| 11 | |
| 12 | ## Patterns |
| 13 | |
| 14 | ### Zero Dependencies |
| 15 | Squad 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. |
| 16 | |
| 17 | ### Node.js Built-in Test Runner |
| 18 | Tests use `node:test` and `node:assert/strict` — no test frameworks. Run with `npm test`. Test files live in `test/`. The test command is `node --test test/`. |
| 19 | |
| 20 | ### Error Handling — `fatal()` Pattern |
| 21 | All 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. |
| 22 | |
| 23 | ### ANSI Color Constants |
| 24 | Colors are defined as constants at the top of `index.js`: `GREEN`, `RED`, `DIM`, `BOLD`, `RESET`. Use these constants — do not inline ANSI escape codes. |
| 25 | |
| 26 | ### File Structure |
| 27 | - `.squad/` — Team state (user-owned, never overwritten by upgrades) |
| 28 | - `.squad/templates/` — Template files copied from `templates/` (Squad-owned, overwritten on upgrade) |
| 29 | - `.github/agents/squad.agent.md` — Coordinator prompt (Squad-owned, overwritten on upgrade) |
| 30 | - `templates/` — Source templates shipped with the npm package |
| 31 | - `.squad/skills/` — Team skills in SKILL.md format (user-owned) |
| 32 | - `.squad/decisions/inbox/` — Drop-box for parallel decision writes |
| 33 | |
| 34 | ### Windows Compatibility |
| 35 | Always use `path.join()` for file paths — never hardcode `/` or `\` separators. Squad must work on Windows, macOS, and Linux. All tests must pass on all platforms. |
| 36 | |
| 37 | ### Init Idempotency |
| 38 | The 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. |
| 39 | |
| 40 | ### Copy Pattern |
| 41 | `copyRecursive(src, target)` handles both files and directories. It creates parent directories with `{ recursive: true }` and uses `fs.copyFileSync` for files. |
| 42 | |
| 43 | ## Examples |
| 44 | |
| 45 | ```javascript |
| 46 | // Error handling |
| 47 | function fatal(msg) { |
| 48 | console.error(`${RED}✗${RESET} ${msg}`); |
| 49 | process.exit(1); |
| 50 | } |
| 51 | |
| 52 | // File path construction (Windows-safe) |
| 53 | const agentDest = path.join(dest, '.github', 'agents', 'squad.agent.md'); |
| 54 | |
| 55 | // Skip-if-exists pattern |
| 56 | if (!fs.existsSync(ceremoniesDest)) { |
| 57 | fs.copyFileSync(ceremoniesSrc, ceremoniesDest); |
| 58 | console.log(`${GREEN}✓${RESET} .squad/ceremonies.md`); |
| 59 | } else { |
| 60 | console.log(`${DIM}ceremonies.md already exists — skipping${RESET}`); |
| 61 | } |
| 62 | ``` |
| 63 | |
| 64 | ## Anti-Patterns |
| 65 | - **Adding npm dependencies** — Squad is zero-dep. Use Node.js built-ins only. |
| 66 | - **Hardcoded path separators** — Never use `/` or `\` directly. Always `path.join()`. |
| 67 | - **Overwriting user state on init** — Init skips existing files. Only upgrade overwrites Squad-owned files. |
| 68 | - **Raw stack traces** — All errors go through `fatal()`. Users see clean messages, not stack traces. |
| 69 | - **Inline ANSI codes** — Use the color constants (`GREEN`, `RED`, `DIM`, `BOLD`, `RESET`). |