fleet-commander-ai 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +159 -0
  3. package/bin/fleet-commander-mcp.js +27 -0
  4. package/bin/fleet-commander.js +22 -0
  5. package/dist/client/assets/index-CHukC8Hq.js +188 -0
  6. package/dist/client/assets/index-CHukC8Hq.js.map +1 -0
  7. package/dist/client/assets/index-DvMjcYbg.css +1 -0
  8. package/dist/client/index.html +13 -0
  9. package/dist/server/config.d.ts +51 -0
  10. package/dist/server/config.d.ts.map +1 -0
  11. package/dist/server/config.js +104 -0
  12. package/dist/server/config.js.map +1 -0
  13. package/dist/server/db.d.ts +388 -0
  14. package/dist/server/db.d.ts.map +1 -0
  15. package/dist/server/db.js +1524 -0
  16. package/dist/server/db.js.map +1 -0
  17. package/dist/server/index.d.ts +2 -0
  18. package/dist/server/index.d.ts.map +1 -0
  19. package/dist/server/index.js +162 -0
  20. package/dist/server/index.js.map +1 -0
  21. package/dist/server/mcp/index.d.ts +2 -0
  22. package/dist/server/mcp/index.d.ts.map +1 -0
  23. package/dist/server/mcp/index.js +112 -0
  24. package/dist/server/mcp/index.js.map +1 -0
  25. package/dist/server/mcp/tools/add-project.d.ts +9 -0
  26. package/dist/server/mcp/tools/add-project.d.ts.map +1 -0
  27. package/dist/server/mcp/tools/add-project.js +58 -0
  28. package/dist/server/mcp/tools/add-project.js.map +1 -0
  29. package/dist/server/mcp/tools/get-team-timeline.d.ts +9 -0
  30. package/dist/server/mcp/tools/get-team-timeline.d.ts.map +1 -0
  31. package/dist/server/mcp/tools/get-team-timeline.js +48 -0
  32. package/dist/server/mcp/tools/get-team-timeline.js.map +1 -0
  33. package/dist/server/mcp/tools/get-team.d.ts +9 -0
  34. package/dist/server/mcp/tools/get-team.d.ts.map +1 -0
  35. package/dist/server/mcp/tools/get-team.js +48 -0
  36. package/dist/server/mcp/tools/get-team.js.map +1 -0
  37. package/dist/server/mcp/tools/get-usage.d.ts +9 -0
  38. package/dist/server/mcp/tools/get-usage.d.ts.map +1 -0
  39. package/dist/server/mcp/tools/get-usage.js +33 -0
  40. package/dist/server/mcp/tools/get-usage.js.map +1 -0
  41. package/dist/server/mcp/tools/launch-team.d.ts +8 -0
  42. package/dist/server/mcp/tools/launch-team.d.ts.map +1 -0
  43. package/dist/server/mcp/tools/launch-team.js +49 -0
  44. package/dist/server/mcp/tools/launch-team.js.map +1 -0
  45. package/dist/server/mcp/tools/list-issues.d.ts +9 -0
  46. package/dist/server/mcp/tools/list-issues.d.ts.map +1 -0
  47. package/dist/server/mcp/tools/list-issues.js +47 -0
  48. package/dist/server/mcp/tools/list-issues.js.map +1 -0
  49. package/dist/server/mcp/tools/list-projects.d.ts +9 -0
  50. package/dist/server/mcp/tools/list-projects.d.ts.map +1 -0
  51. package/dist/server/mcp/tools/list-projects.js +32 -0
  52. package/dist/server/mcp/tools/list-projects.js.map +1 -0
  53. package/dist/server/mcp/tools/list-teams.d.ts +9 -0
  54. package/dist/server/mcp/tools/list-teams.d.ts.map +1 -0
  55. package/dist/server/mcp/tools/list-teams.js +43 -0
  56. package/dist/server/mcp/tools/list-teams.js.map +1 -0
  57. package/dist/server/mcp/tools/restart-team.d.ts +8 -0
  58. package/dist/server/mcp/tools/restart-team.d.ts.map +1 -0
  59. package/dist/server/mcp/tools/restart-team.js +46 -0
  60. package/dist/server/mcp/tools/restart-team.js.map +1 -0
  61. package/dist/server/mcp/tools/send-message.d.ts +9 -0
  62. package/dist/server/mcp/tools/send-message.d.ts.map +1 -0
  63. package/dist/server/mcp/tools/send-message.js +48 -0
  64. package/dist/server/mcp/tools/send-message.js.map +1 -0
  65. package/dist/server/mcp/tools/stop-team.d.ts +8 -0
  66. package/dist/server/mcp/tools/stop-team.d.ts.map +1 -0
  67. package/dist/server/mcp/tools/stop-team.js +46 -0
  68. package/dist/server/mcp/tools/stop-team.js.map +1 -0
  69. package/dist/server/mcp/tools/system-health.d.ts +9 -0
  70. package/dist/server/mcp/tools/system-health.d.ts.map +1 -0
  71. package/dist/server/mcp/tools/system-health.js +32 -0
  72. package/dist/server/mcp/tools/system-health.js.map +1 -0
  73. package/dist/server/middleware/error-handler.d.ts +32 -0
  74. package/dist/server/middleware/error-handler.d.ts.map +1 -0
  75. package/dist/server/middleware/error-handler.js +65 -0
  76. package/dist/server/middleware/error-handler.js.map +1 -0
  77. package/dist/server/routes/events.d.ts +16 -0
  78. package/dist/server/routes/events.d.ts.map +1 -0
  79. package/dist/server/routes/events.js +164 -0
  80. package/dist/server/routes/events.js.map +1 -0
  81. package/dist/server/routes/issues.d.ts +4 -0
  82. package/dist/server/routes/issues.d.ts.map +1 -0
  83. package/dist/server/routes/issues.js +198 -0
  84. package/dist/server/routes/issues.js.map +1 -0
  85. package/dist/server/routes/project-groups.d.ts +4 -0
  86. package/dist/server/routes/project-groups.d.ts.map +1 -0
  87. package/dist/server/routes/project-groups.js +124 -0
  88. package/dist/server/routes/project-groups.js.map +1 -0
  89. package/dist/server/routes/projects.d.ts +4 -0
  90. package/dist/server/routes/projects.d.ts.map +1 -0
  91. package/dist/server/routes/projects.js +319 -0
  92. package/dist/server/routes/projects.js.map +1 -0
  93. package/dist/server/routes/prs.d.ts +4 -0
  94. package/dist/server/routes/prs.d.ts.map +1 -0
  95. package/dist/server/routes/prs.js +186 -0
  96. package/dist/server/routes/prs.js.map +1 -0
  97. package/dist/server/routes/query.d.ts +4 -0
  98. package/dist/server/routes/query.d.ts.map +1 -0
  99. package/dist/server/routes/query.js +82 -0
  100. package/dist/server/routes/query.js.map +1 -0
  101. package/dist/server/routes/state-machine.d.ts +4 -0
  102. package/dist/server/routes/state-machine.d.ts.map +1 -0
  103. package/dist/server/routes/state-machine.js +86 -0
  104. package/dist/server/routes/state-machine.js.map +1 -0
  105. package/dist/server/routes/stream.d.ts +18 -0
  106. package/dist/server/routes/stream.d.ts.map +1 -0
  107. package/dist/server/routes/stream.js +62 -0
  108. package/dist/server/routes/stream.js.map +1 -0
  109. package/dist/server/routes/system.d.ts +4 -0
  110. package/dist/server/routes/system.d.ts.map +1 -0
  111. package/dist/server/routes/system.js +225 -0
  112. package/dist/server/routes/system.js.map +1 -0
  113. package/dist/server/routes/teams.d.ts +4 -0
  114. package/dist/server/routes/teams.d.ts.map +1 -0
  115. package/dist/server/routes/teams.js +570 -0
  116. package/dist/server/routes/teams.js.map +1 -0
  117. package/dist/server/routes/usage.d.ts +4 -0
  118. package/dist/server/routes/usage.d.ts.map +1 -0
  119. package/dist/server/routes/usage.js +80 -0
  120. package/dist/server/routes/usage.js.map +1 -0
  121. package/dist/server/schema.sql +267 -0
  122. package/dist/server/services/cc-query.d.ts +20 -0
  123. package/dist/server/services/cc-query.d.ts.map +1 -0
  124. package/dist/server/services/cc-query.js +352 -0
  125. package/dist/server/services/cc-query.js.map +1 -0
  126. package/dist/server/services/cleanup.d.ts +15 -0
  127. package/dist/server/services/cleanup.d.ts.map +1 -0
  128. package/dist/server/services/cleanup.js +232 -0
  129. package/dist/server/services/cleanup.js.map +1 -0
  130. package/dist/server/services/diagnostics-service.d.ts +85 -0
  131. package/dist/server/services/diagnostics-service.d.ts.map +1 -0
  132. package/dist/server/services/diagnostics-service.js +242 -0
  133. package/dist/server/services/diagnostics-service.js.map +1 -0
  134. package/dist/server/services/event-collector.d.ts +125 -0
  135. package/dist/server/services/event-collector.d.ts.map +1 -0
  136. package/dist/server/services/event-collector.js +299 -0
  137. package/dist/server/services/event-collector.js.map +1 -0
  138. package/dist/server/services/event-service.d.ts +22 -0
  139. package/dist/server/services/event-service.d.ts.map +1 -0
  140. package/dist/server/services/event-service.js +53 -0
  141. package/dist/server/services/event-service.js.map +1 -0
  142. package/dist/server/services/github-poller.d.ts +68 -0
  143. package/dist/server/services/github-poller.d.ts.map +1 -0
  144. package/dist/server/services/github-poller.js +563 -0
  145. package/dist/server/services/github-poller.js.map +1 -0
  146. package/dist/server/services/issue-fetcher.d.ts +231 -0
  147. package/dist/server/services/issue-fetcher.d.ts.map +1 -0
  148. package/dist/server/services/issue-fetcher.js +1053 -0
  149. package/dist/server/services/issue-fetcher.js.map +1 -0
  150. package/dist/server/services/issue-service.d.ts +102 -0
  151. package/dist/server/services/issue-service.d.ts.map +1 -0
  152. package/dist/server/services/issue-service.js +279 -0
  153. package/dist/server/services/issue-service.js.map +1 -0
  154. package/dist/server/services/message-template-service.d.ts +39 -0
  155. package/dist/server/services/message-template-service.d.ts.map +1 -0
  156. package/dist/server/services/message-template-service.js +87 -0
  157. package/dist/server/services/message-template-service.js.map +1 -0
  158. package/dist/server/services/pr-service.d.ts +73 -0
  159. package/dist/server/services/pr-service.d.ts.map +1 -0
  160. package/dist/server/services/pr-service.js +231 -0
  161. package/dist/server/services/pr-service.js.map +1 -0
  162. package/dist/server/services/project-group-service.d.ts +64 -0
  163. package/dist/server/services/project-group-service.d.ts.map +1 -0
  164. package/dist/server/services/project-group-service.js +149 -0
  165. package/dist/server/services/project-group-service.js.map +1 -0
  166. package/dist/server/services/project-service.d.ts +161 -0
  167. package/dist/server/services/project-service.d.ts.map +1 -0
  168. package/dist/server/services/project-service.js +623 -0
  169. package/dist/server/services/project-service.js.map +1 -0
  170. package/dist/server/services/service-error.d.ts +25 -0
  171. package/dist/server/services/service-error.d.ts.map +1 -0
  172. package/dist/server/services/service-error.js +49 -0
  173. package/dist/server/services/service-error.js.map +1 -0
  174. package/dist/server/services/sse-broker.d.ts +144 -0
  175. package/dist/server/services/sse-broker.d.ts.map +1 -0
  176. package/dist/server/services/sse-broker.js +111 -0
  177. package/dist/server/services/sse-broker.js.map +1 -0
  178. package/dist/server/services/startup-recovery.d.ts +10 -0
  179. package/dist/server/services/startup-recovery.d.ts.map +1 -0
  180. package/dist/server/services/startup-recovery.js +122 -0
  181. package/dist/server/services/startup-recovery.js.map +1 -0
  182. package/dist/server/services/stuck-detector.d.ts +20 -0
  183. package/dist/server/services/stuck-detector.d.ts.map +1 -0
  184. package/dist/server/services/stuck-detector.js +167 -0
  185. package/dist/server/services/stuck-detector.js.map +1 -0
  186. package/dist/server/services/stuck-detector.test.d.ts +2 -0
  187. package/dist/server/services/stuck-detector.test.d.ts.map +1 -0
  188. package/dist/server/services/stuck-detector.test.js +363 -0
  189. package/dist/server/services/stuck-detector.test.js.map +1 -0
  190. package/dist/server/services/team-manager.d.ts +188 -0
  191. package/dist/server/services/team-manager.d.ts.map +1 -0
  192. package/dist/server/services/team-manager.js +1869 -0
  193. package/dist/server/services/team-manager.js.map +1 -0
  194. package/dist/server/services/team-service.d.ts +251 -0
  195. package/dist/server/services/team-service.d.ts.map +1 -0
  196. package/dist/server/services/team-service.js +707 -0
  197. package/dist/server/services/team-service.js.map +1 -0
  198. package/dist/server/services/usage-service.d.ts +42 -0
  199. package/dist/server/services/usage-service.d.ts.map +1 -0
  200. package/dist/server/services/usage-service.js +101 -0
  201. package/dist/server/services/usage-service.js.map +1 -0
  202. package/dist/server/services/usage-tracker.d.ts +68 -0
  203. package/dist/server/services/usage-tracker.d.ts.map +1 -0
  204. package/dist/server/services/usage-tracker.js +220 -0
  205. package/dist/server/services/usage-tracker.js.map +1 -0
  206. package/dist/server/utils/build-timeline.d.ts +32 -0
  207. package/dist/server/utils/build-timeline.d.ts.map +1 -0
  208. package/dist/server/utils/build-timeline.js +142 -0
  209. package/dist/server/utils/build-timeline.js.map +1 -0
  210. package/dist/server/utils/find-git-bash.d.ts +10 -0
  211. package/dist/server/utils/find-git-bash.d.ts.map +1 -0
  212. package/dist/server/utils/find-git-bash.js +46 -0
  213. package/dist/server/utils/find-git-bash.js.map +1 -0
  214. package/dist/server/utils/hook-installer.d.ts +20 -0
  215. package/dist/server/utils/hook-installer.d.ts.map +1 -0
  216. package/dist/server/utils/hook-installer.js +90 -0
  217. package/dist/server/utils/hook-installer.js.map +1 -0
  218. package/dist/server/utils/process-utils.d.ts +10 -0
  219. package/dist/server/utils/process-utils.d.ts.map +1 -0
  220. package/dist/server/utils/process-utils.js +33 -0
  221. package/dist/server/utils/process-utils.js.map +1 -0
  222. package/dist/server/utils/resolve-claude-path.d.ts +4 -0
  223. package/dist/server/utils/resolve-claude-path.d.ts.map +1 -0
  224. package/dist/server/utils/resolve-claude-path.js +66 -0
  225. package/dist/server/utils/resolve-claude-path.js.map +1 -0
  226. package/dist/server/utils/resolve-message.d.ts +10 -0
  227. package/dist/server/utils/resolve-message.d.ts.map +1 -0
  228. package/dist/server/utils/resolve-message.js +27 -0
  229. package/dist/server/utils/resolve-message.js.map +1 -0
  230. package/dist/shared/message-templates.d.ts +9 -0
  231. package/dist/shared/message-templates.d.ts.map +1 -0
  232. package/dist/shared/message-templates.js +88 -0
  233. package/dist/shared/message-templates.js.map +1 -0
  234. package/dist/shared/state-machine.d.ts +28 -0
  235. package/dist/shared/state-machine.d.ts.map +1 -0
  236. package/dist/shared/state-machine.js +282 -0
  237. package/dist/shared/state-machine.js.map +1 -0
  238. package/dist/shared/types.d.ts +404 -0
  239. package/dist/shared/types.d.ts.map +1 -0
  240. package/dist/shared/types.js +5 -0
  241. package/dist/shared/types.js.map +1 -0
  242. package/hooks/DESIGN.md +562 -0
  243. package/hooks/on_notification.sh +9 -0
  244. package/hooks/on_post_tool_use.sh +9 -0
  245. package/hooks/on_pre_compact.sh +10 -0
  246. package/hooks/on_session_end.sh +8 -0
  247. package/hooks/on_session_start.sh +8 -0
  248. package/hooks/on_stop.sh +8 -0
  249. package/hooks/on_stop_failure.sh +8 -0
  250. package/hooks/on_subagent_start.sh +8 -0
  251. package/hooks/on_subagent_stop.sh +8 -0
  252. package/hooks/on_teammate_idle.sh +8 -0
  253. package/hooks/on_tool_error.sh +8 -0
  254. package/hooks/send_event.sh +101 -0
  255. package/hooks/settings.json.example +120 -0
  256. package/package.json +93 -0
  257. package/prompts/default-prompt.md +16 -0
  258. package/scripts/install.ps1 +22 -0
  259. package/scripts/install.sh +229 -0
  260. package/scripts/launch.js +64 -0
  261. package/scripts/uninstall.ps1 +22 -0
  262. package/scripts/uninstall.sh +123 -0
  263. package/templates/agents/fleet-dev.md +162 -0
  264. package/templates/agents/fleet-planner.md +263 -0
  265. package/templates/agents/fleet-reviewer.md +309 -0
  266. package/templates/archive/fleet-coordinator.md +128 -0
  267. package/templates/archive/fleet-dev-csharp.md +74 -0
  268. package/templates/archive/fleet-dev-devops.md +76 -0
  269. package/templates/archive/fleet-dev-fsharp.md +83 -0
  270. package/templates/archive/fleet-dev-generic.md +64 -0
  271. package/templates/archive/fleet-dev-python.md +75 -0
  272. package/templates/archive/fleet-dev-typescript.md +76 -0
  273. package/templates/guides/api-design.md +159 -0
  274. package/templates/guides/csharp-conventions.md +182 -0
  275. package/templates/guides/devops-conventions.md +192 -0
  276. package/templates/guides/fsharp-conventions.md +201 -0
  277. package/templates/guides/python-conventions.md +146 -0
  278. package/templates/guides/sql-database.md +125 -0
  279. package/templates/guides/testing-strategies.md +123 -0
  280. package/templates/guides/typescript-conventions.md +130 -0
  281. package/templates/workflow.md +513 -0
@@ -0,0 +1,192 @@
1
+ # DevOps / Infrastructure Conventions
2
+
3
+ > Applies to: `.github/workflows/*.yml`, `Dockerfile`, `docker-compose.yml`, `*.sh`, `*.ps1`, `Makefile`
4
+ > Last updated: 2026-03-18
5
+
6
+ ## Architecture
7
+
8
+ Infrastructure code typically lives in these locations:
9
+
10
+ ```
11
+ .github/workflows/ -- GitHub Actions CI/CD pipelines
12
+ docker/ -- Dockerfiles and compose files (or project root)
13
+ scripts/ -- Build, deploy, and utility scripts
14
+ k8s/ or deploy/ -- Kubernetes manifests, Helm charts
15
+ infra/ -- Terraform, Pulumi, or other IaC
16
+ ```
17
+
18
+ Read `CLAUDE.md` and existing CI config before making changes. Match the project's
19
+ existing patterns for pipeline structure, script conventions, and deployment approach.
20
+
21
+ ## CI/CD — GitHub Actions
22
+
23
+ ### Pinned versions
24
+
25
+ Always use pinned action versions, not `@main` or floating tags:
26
+
27
+ ```yaml
28
+ # RIGHT
29
+ uses: actions/checkout@v4
30
+ uses: actions/setup-node@v4
31
+
32
+ # WRONG
33
+ uses: actions/checkout@main
34
+ ```
35
+
36
+ ### Permissions block
37
+
38
+ Set explicit `permissions` on every workflow. Use least-privilege:
39
+
40
+ ```yaml
41
+ permissions:
42
+ contents: read
43
+ pull-requests: write
44
+ ```
45
+
46
+ ### Matrix strategies
47
+
48
+ Use matrices for multi-version testing. Include `fail-fast: false` when you want
49
+ all combinations to run:
50
+
51
+ ```yaml
52
+ strategy:
53
+ fail-fast: false
54
+ matrix:
55
+ node-version: [18, 20, 22]
56
+ os: [ubuntu-latest, windows-latest]
57
+ ```
58
+
59
+ ### Secrets
60
+
61
+ - Never hardcode secrets in workflows -- use `${{ secrets.NAME }}`.
62
+ - Never echo or log secret values.
63
+ - Use environment-level secrets for deployment-specific values.
64
+
65
+ ## Docker
66
+
67
+ ### Multi-stage builds
68
+
69
+ Use multi-stage builds to minimize image size:
70
+
71
+ ```dockerfile
72
+ FROM node:20-alpine AS builder
73
+ WORKDIR /app
74
+ COPY package*.json ./
75
+ RUN npm ci
76
+ COPY . .
77
+ RUN npm run build
78
+
79
+ FROM node:20-alpine
80
+ WORKDIR /app
81
+ COPY --from=builder /app/dist ./dist
82
+ COPY --from=builder /app/node_modules ./node_modules
83
+ CMD ["node", "dist/index.js"]
84
+ ```
85
+
86
+ ### Layer caching
87
+
88
+ Order Dockerfile instructions from least-changing to most-changing. Copy
89
+ dependency files before source code so dependency installation is cached.
90
+
91
+ ### .dockerignore
92
+
93
+ Always maintain a `.dockerignore` file. Include at minimum:
94
+ `node_modules`, `.git`, `*.md`, `tests/`, `.env*`.
95
+
96
+ ## Scripts
97
+
98
+ ### Cross-platform compatibility
99
+
100
+ When the project supports both Windows and Linux:
101
+
102
+ - Provide both `.sh` and `.ps1` versions, or use a tool that runs on both (Node.js, Python).
103
+ - Use forward slashes in paths within scripts -- bash on Windows handles them.
104
+ - Avoid platform-specific commands without alternatives (`sed` on Windows needs Git Bash).
105
+ - Ensure shell scripts use LF line endings -- CRLF breaks shebang lines on Linux.
106
+
107
+ ### Idempotency
108
+
109
+ Scripts must be safe to run multiple times. Check for existing state before
110
+ creating resources:
111
+
112
+ ```bash
113
+ # RIGHT -- idempotent
114
+ mkdir -p "$TARGET_DIR"
115
+ [ -f "$CONFIG" ] || cp template.conf "$CONFIG"
116
+
117
+ # WRONG -- fails on second run
118
+ mkdir "$TARGET_DIR"
119
+ cp template.conf "$CONFIG"
120
+ ```
121
+
122
+ ### Error handling
123
+
124
+ Use `set -euo pipefail` in bash scripts. Check exit codes for critical operations.
125
+
126
+ ## Anti-Patterns to Avoid
127
+
128
+ ### Hardcoded paths and URLs
129
+
130
+ Never hardcode environment-specific values. Use environment variables or
131
+ configuration files:
132
+
133
+ ```bash
134
+ # WRONG
135
+ curl https://api.prod.example.com/deploy
136
+
137
+ # RIGHT
138
+ curl "${DEPLOY_URL}/deploy"
139
+ ```
140
+
141
+ ### Skipping YAML validation
142
+
143
+ Always validate YAML syntax before committing pipeline changes. A typo in a
144
+ workflow file can break CI for the entire team.
145
+
146
+ ### Database migrations without rollback
147
+
148
+ Database migrations must be reversible. Always provide a down/rollback migration.
149
+ Test migrations against a fresh database to catch ordering issues.
150
+
151
+ ## Testing Infrastructure Changes
152
+
153
+ - **GitHub Actions**: Use `act` for local testing when possible, or create a
154
+ draft PR to trigger the workflow.
155
+ - **Docker**: Build and run locally before pushing. Test with `docker build --no-cache`.
156
+ - **Scripts**: Run scripts in a clean environment to verify they work without
157
+ pre-existing state.
158
+
159
+ ## Build & Run
160
+
161
+ ```bash
162
+ # GitHub Actions
163
+ act -j build # Run locally with act
164
+ gh workflow run ci.yml # Trigger manually
165
+
166
+ # Docker
167
+ docker build -t app:test . # Build image
168
+ docker compose up -d # Start services
169
+
170
+ # Scripts
171
+ bash scripts/install.sh # Run install script
172
+ shellcheck scripts/*.sh # Lint shell scripts
173
+ ```
174
+
175
+ ## Common Pitfalls
176
+
177
+ ### GitHub Actions caching
178
+
179
+ Cache keys must include the lockfile hash. Stale caches cause mysterious build
180
+ failures. Use `hashFiles('**/package-lock.json')` or equivalent.
181
+
182
+ ### Docker build context size
183
+
184
+ A missing `.dockerignore` sends the entire repo (including `node_modules` and
185
+ `.git`) as build context, making builds slow. Check context size if builds are
186
+ unexpectedly slow.
187
+
188
+ ### Script encoding on Windows
189
+
190
+ Git on Windows may convert LF to CRLF. Bash scripts with CRLF line endings fail
191
+ with cryptic errors (`$'\r': command not found`). Use `.gitattributes` to force
192
+ LF for shell scripts: `*.sh text eol=lf`.
@@ -0,0 +1,201 @@
1
+ # F# Conventions
2
+
3
+ > Applies to: `*.fs`, `*.fsi`, `*.fsx`, `*.fsproj`
4
+ > Last updated: 2026-03-18
5
+
6
+ ## Architecture
7
+
8
+ F# projects use a layered module structure. Files compile top-to-bottom in the
9
+ order listed in the `.fsproj` file. This is enforced by the compiler -- there is
10
+ no way around it.
11
+
12
+ Typical layer ordering (top of .fsproj = compiled first):
13
+
14
+ ```
15
+ Domain.Types.fs -- Discriminated unions, value objects, domain types
16
+ Domain.Events.fs -- Domain events
17
+ Domain.Services.fs -- Pure domain logic, no IO
18
+ Application.Commands.fs -- Use-case orchestration
19
+ Application.Queries.fs -- Read-side projections
20
+ Infrastructure.Db.fs -- Database access (side effects live here)
21
+ Api.Handlers.fs -- HTTP handlers (thin, delegate to Application)
22
+ Program.fs -- Composition root, DI wiring, app startup (always last)
23
+ ```
24
+
25
+ Each file can only reference types and functions defined in files listed above it.
26
+
27
+ ## Naming Conventions
28
+
29
+ | Element | Convention | Example |
30
+ |---------|-----------|---------|
31
+ | Modules | PascalCase, noun | `module OrderProcessing` |
32
+ | Functions | camelCase, verb | `let calculateTotal items = ...` |
33
+ | Types (DUs, records) | PascalCase | `type OrderStatus = Pending \| Shipped` |
34
+ | DU cases | PascalCase | `Pending`, `Shipped`, `Cancelled` |
35
+ | Parameters | camelCase | `orderId`, `customerName` |
36
+ | Private helpers | prefix with underscore or nest in local scope | `let _validate x = ...` |
37
+ | Test functions | backtick names describing behavior | `` let `calculateTotal returns zero for empty list` () = `` |
38
+
39
+ ## Patterns to Follow
40
+
41
+ ### Discriminated unions for domain modeling
42
+
43
+ Prefer DUs over class hierarchies. Encode business rules in the type system so
44
+ invalid states are unrepresentable:
45
+
46
+ ```fsharp
47
+ type Email = private Email of string
48
+ module Email =
49
+ let create (s: string) =
50
+ if s.Contains("@") then Ok (Email s)
51
+ else Error "Invalid email"
52
+ let value (Email s) = s
53
+ ```
54
+
55
+ ### Railway-oriented programming
56
+
57
+ Use `Result<'T, 'E>` for operations that can fail. Chain with `Result.bind`
58
+ or a `result {}` computation expression:
59
+
60
+ ```fsharp
61
+ let processOrder orderId =
62
+ validateOrder orderId
63
+ |> Result.bind checkInventory
64
+ |> Result.bind chargePayment
65
+ |> Result.bind shipOrder
66
+ ```
67
+
68
+ ### Pipeline style
69
+
70
+ Prefer pipelines over nested function calls:
71
+
72
+ ```fsharp
73
+ // Good
74
+ orders
75
+ |> List.filter (fun o -> o.Status = Active)
76
+ |> List.sortBy (fun o -> o.CreatedAt)
77
+ |> List.take 10
78
+
79
+ // Avoid
80
+ List.take 10 (List.sortBy (fun o -> o.CreatedAt) (List.filter (fun o -> o.Status = Active) orders))
81
+ ```
82
+
83
+ ### Computation expressions
84
+
85
+ Use `async {}` for legacy async, `task {}` for .NET Task interop. Match whichever
86
+ the project already uses -- do not mix styles within a module.
87
+
88
+ ```fsharp
89
+ let fetchOrder (id: OrderId) = task {
90
+ let! result = db.QueryAsync<Order>(id)
91
+ return result |> Option.ofObj
92
+ }
93
+ ```
94
+
95
+ ## Anti-Patterns to Avoid
96
+
97
+ ### Mutable state in domain logic
98
+
99
+ Never use `mutable` in domain types or domain service functions. Mutation is
100
+ acceptable only in infrastructure code (e.g., filling a buffer) and must be
101
+ isolated behind a pure interface.
102
+
103
+ ### Classes for domain models
104
+
105
+ Do not create classes with inheritance hierarchies for domain concepts. Use
106
+ discriminated unions and records. Classes are acceptable for infrastructure
107
+ (e.g., a repository implementation) but not for domain types.
108
+
109
+ ### Ignoring Result errors
110
+
111
+ Never discard a `Result` value or convert it to an exception unless you are at
112
+ an application boundary (e.g., an HTTP handler returning 400/500):
113
+
114
+ ```fsharp
115
+ // WRONG -- silently ignores failure
116
+ let _ = processOrder orderId
117
+
118
+ // RIGHT -- handle both cases
119
+ match processOrder orderId with
120
+ | Ok order -> handleSuccess order
121
+ | Error e -> handleFailure e
122
+ ```
123
+
124
+ ### Float/double for financial values
125
+
126
+ Never use `float` or `double` for money, prices, quantities, or financial
127
+ calculations. Use `decimal` exclusively. Floating-point rounding errors
128
+ compound silently in financial contexts.
129
+
130
+ ```fsharp
131
+ // WRONG
132
+ let total: float = price * quantity
133
+
134
+ // RIGHT
135
+ let total: decimal = price * quantity
136
+ ```
137
+
138
+ ## Dependencies & Imports
139
+
140
+ - Open modules explicitly -- avoid `[<AutoOpen>]` on new modules unless the
141
+ project already uses it extensively.
142
+ - Prefer `open` at the top of the file, not inside functions.
143
+ - Group opens: FSharp.Core / System first, then third-party, then project modules.
144
+ - Do not add NuGet packages without confirming they are needed for the task.
145
+
146
+ ## Testing
147
+
148
+ - **Framework**: Match whatever the project uses (Expecto, xUnit+FsUnit, NUnit).
149
+ - **Property-based tests**: Use FsCheck for functions with well-defined input/output
150
+ contracts (e.g., `serialize >> deserialize = id`).
151
+ - **Assertions**: Prefer Unquote (`test <@ expr @>`) or FsUnit matchers over
152
+ raw `Assert.Equal` when the project supports them.
153
+ - **Test file placement**: Mirror the source file in a parallel test project.
154
+ If source is `Domain.Orders.fs`, test is `Domain.OrdersTests.fs`.
155
+ - Run `dotnet test` and fix all failures before committing.
156
+
157
+ ## Build & Run
158
+
159
+ ```bash
160
+ dotnet build # Compile -- catches type errors and .fsproj ordering issues
161
+ dotnet test # Run all tests
162
+ dotnet run # Run the application (if applicable)
163
+ ```
164
+
165
+ Always run `dotnet build` immediately after adding a new `.fs` file to catch
166
+ compilation order errors early. If you get "not defined" or "not recognized"
167
+ errors, the problem is almost certainly file ordering in `.fsproj`.
168
+
169
+ ## Common Pitfalls
170
+
171
+ ### .fsproj file ordering (CRITICAL)
172
+
173
+ F# compiles files strictly top-to-bottom as listed in the `.fsproj` `<Compile>`
174
+ items. When adding a new file:
175
+
176
+ 1. **Read the `.fsproj` first** -- understand the current order.
177
+ 2. **Insert the new `<Compile Include="..." />` at the correct position** --
178
+ after its dependencies, before its dependents.
179
+ 3. **Run `dotnet build` immediately** -- do not write more code until the build passes.
180
+
181
+ If build fails with "The type 'X' is not defined" or "The namespace 'Y' is not
182
+ defined", check `.fsproj` order FIRST. This is the most common F# build failure.
183
+
184
+ ### Module vs namespace
185
+
186
+ - `namespace Foo` -- groups types, cannot contain `let` bindings at top level.
187
+ - `module Foo` -- can contain `let` bindings, types, and nested modules.
188
+
189
+ Match whatever the project uses. Do not switch conventions within a project.
190
+
191
+ ### Partial application surprises
192
+
193
+ Be explicit with parameter counts. A function `let add x y = x + y` partially
194
+ applied as `add 1` returns a function, not a value. This is correct behavior
195
+ but can surprise when passing to higher-order functions that expect a value.
196
+
197
+ ### Equality semantics
198
+
199
+ F# records and DUs have structural equality by default. Classes do not. If you
200
+ wrap a class in a record, the record's equality will use reference equality for
201
+ that field. Use `[<CustomEquality; CustomComparison>]` if needed.
@@ -0,0 +1,146 @@
1
+ # Python Conventions
2
+
3
+ > Applies to: `*.py`, `pyproject.toml`, `requirements.txt`, `setup.cfg`
4
+ > Last updated: 2026-03-18
5
+
6
+ ## Architecture
7
+
8
+ Python projects vary widely. Read `CLAUDE.md` and the project's entry point to
9
+ understand the framework and structure before making changes.
10
+
11
+ Common patterns:
12
+
13
+ ```
14
+ src/
15
+ app/ -- Application code
16
+ models/ -- Database models / domain entities
17
+ services/ -- Business logic
18
+ api/ -- Route handlers / views
19
+ schemas/ -- Pydantic models / serializers
20
+ tests/ -- Test files (mirror src structure)
21
+ migrations/ -- Database migrations (Alembic / Django)
22
+ ```
23
+
24
+ ## Naming Conventions
25
+
26
+ | Element | Convention | Example |
27
+ |---------|-----------|---------|
28
+ | Modules | snake_case | `order_service.py`, `user_repository.py` |
29
+ | Classes | PascalCase | `OrderService`, `UserRepository` |
30
+ | Functions | snake_case | `get_order_by_id`, `calculate_total` |
31
+ | Constants | UPPER_SNAKE_CASE | `MAX_RETRIES`, `DEFAULT_TIMEOUT` |
32
+ | Private | underscore prefix | `_validate_input`, `_cache` |
33
+ | Type variables | single uppercase or descriptive | `T`, `ReturnType` |
34
+
35
+ ## Patterns to Follow
36
+
37
+ ### Type hints
38
+
39
+ Add type hints to all new function signatures. Use `typing` module types for
40
+ complex signatures:
41
+
42
+ ```python
43
+ from typing import Optional, Sequence
44
+
45
+ def get_orders(user_id: int, limit: Optional[int] = None) -> Sequence[Order]:
46
+ ...
47
+ ```
48
+
49
+ ### Framework patterns
50
+
51
+ - **Django**: Use class-based views when they fit, function-based for simple endpoints.
52
+ Create migrations with `makemigrations` -- never edit migration files manually.
53
+ - **Flask**: Use blueprints for route organization. Register extensions in the
54
+ application factory.
55
+ - **FastAPI**: Use Pydantic models for request/response schemas. Use dependency
56
+ injection for services and database sessions.
57
+
58
+ ### Async patterns
59
+
60
+ - Use `async/await` with asyncio when the framework supports it (FastAPI, aiohttp).
61
+ - Use `async with` for context managers that manage connections or sessions.
62
+ - Do not mix sync and async code without explicit bridges (`asyncio.to_thread`
63
+ for sync-in-async, `asyncio.run` for async-in-sync at boundaries only).
64
+
65
+ ## Anti-Patterns to Avoid
66
+
67
+ ### Mutable default arguments
68
+
69
+ ```python
70
+ # WRONG -- shared mutable default
71
+ def add_item(item: str, items: list[str] = []) -> list[str]:
72
+ items.append(item)
73
+ return items
74
+
75
+ # RIGHT -- use None sentinel
76
+ def add_item(item: str, items: list[str] | None = None) -> list[str]:
77
+ if items is None:
78
+ items = []
79
+ items.append(item)
80
+ return items
81
+ ```
82
+
83
+ ### Bare except clauses
84
+
85
+ Never catch `Exception` or use bare `except:` unless you are at an application
86
+ boundary (middleware, CLI entry point). Catch specific exception types.
87
+
88
+ ### os.path for file operations
89
+
90
+ Prefer `pathlib.Path` over `os.path` for all file operations:
91
+
92
+ ```python
93
+ # Prefer
94
+ from pathlib import Path
95
+ config_path = Path("config") / "settings.json"
96
+
97
+ # Avoid
98
+ import os
99
+ config_path = os.path.join("config", "settings.json")
100
+ ```
101
+
102
+ ## Dependencies & Imports
103
+
104
+ - Activate the project's virtualenv before running any Python commands.
105
+ - Import order: stdlib, third-party, local (match existing style or use isort).
106
+ - Do not add packages without confirming they are needed for the task.
107
+ - Check for the project's dependency tool: `requirements.txt`, `pyproject.toml`,
108
+ `poetry`, or `uv`.
109
+
110
+ ## Testing
111
+
112
+ - **Framework**: pytest (fixtures, parametrize, conftest) or unittest -- match the project.
113
+ - **Naming**: `test_function_name_condition_expected_result` or the project's convention.
114
+ - **Fixtures**: Use `conftest.py` for shared fixtures. Prefer fixture factories
115
+ over complex fixture chains.
116
+ - **Parametrize**: Use `@pytest.mark.parametrize` for testing multiple inputs.
117
+ - **Mocking**: Use `unittest.mock.patch` or `monkeypatch` -- mock at boundaries only.
118
+ - Run `pytest` (or project-specific command) and fix all failures before committing.
119
+
120
+ ## Build & Run
121
+
122
+ ```bash
123
+ python -m pytest # Run tests
124
+ python -m mypy . # Type check (if project uses mypy)
125
+ python -m black --check . # Format check (if project uses black)
126
+ pip install -e . # Install in development mode
127
+ ```
128
+
129
+ ## Common Pitfalls
130
+
131
+ ### Import errors from circular dependencies
132
+
133
+ Python resolves imports at module load time. Circular imports cause
134
+ `ImportError` or `AttributeError`. Fix by moving shared types to a separate
135
+ module or using `TYPE_CHECKING` guards for type-only imports.
136
+
137
+ ### Django migration conflicts after rebase
138
+
139
+ If another branch added a migration, yours may conflict. Delete your migration
140
+ and recreate with `python manage.py makemigrations`. Never manually merge
141
+ migration files.
142
+
143
+ ### Forgetting to close resources
144
+
145
+ Use context managers (`with` statements) for files, database connections, and
146
+ HTTP sessions. Do not rely on garbage collection to close resources.
@@ -0,0 +1,125 @@
1
+ # SQL & Database Conventions
2
+
3
+ > Applies to: `*.sql`, migration files, ORM model definitions, database access code
4
+ > Last updated: 2026-03-18
5
+
6
+ ## Migration Discipline
7
+
8
+ - Always use the project's migration framework (Alembic, Django migrations,
9
+ EF Core migrations, Flyway, Knex, Prisma). Never run raw DDL against production.
10
+ - Migrations must be reversible -- provide both up and down operations.
11
+ - Never edit a migration that has already been applied to any environment.
12
+ - Test migrations against a fresh database to catch ordering issues.
13
+ - After rebase, if migration files conflict, delete yours and regenerate against
14
+ the rebased model state. Never manually merge migration files.
15
+
16
+ ## Schema Conventions
17
+
18
+ ### Naming
19
+
20
+ | Element | Convention | Example |
21
+ |---------|-----------|---------|
22
+ | Tables | snake_case, plural | `orders`, `pull_requests`, `usage_snapshots` |
23
+ | Columns | snake_case | `created_at`, `issue_number`, `ci_status` |
24
+ | Primary keys | `id` (integer auto-increment or UUID) | `id INTEGER PRIMARY KEY` |
25
+ | Foreign keys | `{referenced_table_singular}_id` | `team_id`, `project_id` |
26
+ | Indexes | `idx_{table}_{columns}` | `idx_events_team_id_created_at` |
27
+ | Boolean columns | `is_` or `has_` prefix | `is_active`, `has_hooks` |
28
+ | Timestamp columns | `_at` suffix | `created_at`, `merged_at`, `stopped_at` |
29
+
30
+ ### Required columns
31
+
32
+ Every table should have:
33
+ - A primary key (`id`)
34
+ - `created_at` timestamp (set on insert, never updated)
35
+ - `updated_at` timestamp (set on insert, updated on every modification) -- optional
36
+ for append-only tables like events or logs
37
+
38
+ ## Query Optimization
39
+
40
+ ### Avoid N+1 queries
41
+
42
+ Never fetch a list of items and then query related data in a loop. Use JOINs,
43
+ subqueries, or the ORM's eager loading:
44
+
45
+ ```sql
46
+ -- WRONG: N+1
47
+ SELECT * FROM teams;
48
+ -- then for each team:
49
+ SELECT * FROM events WHERE team_id = ?;
50
+
51
+ -- RIGHT: single query
52
+ SELECT t.*, e.* FROM teams t
53
+ LEFT JOIN events e ON e.team_id = t.id;
54
+ ```
55
+
56
+ ### Index frequently filtered columns
57
+
58
+ Add indexes for columns that appear in WHERE, JOIN, ORDER BY, or GROUP BY clauses.
59
+ Foreign key columns should always be indexed.
60
+
61
+ ### Use EXPLAIN
62
+
63
+ Before committing complex queries, run `EXPLAIN` (or `EXPLAIN ANALYZE`) to verify
64
+ the query plan uses indexes and does not perform full table scans on large tables.
65
+
66
+ ## Transaction Safety
67
+
68
+ - Use explicit transactions for multi-step operations. Do not rely on auto-commit
69
+ for operations that must be atomic.
70
+ - Keep transactions short -- do not hold locks while performing external API calls
71
+ or expensive computations.
72
+ - Handle deadlocks gracefully -- retry with backoff when appropriate.
73
+
74
+ ## ORM Patterns
75
+
76
+ ### Lazy vs eager loading
77
+
78
+ - Use eager loading (JOINs / includes) for data you know you will need.
79
+ - Use lazy loading only when you rarely need the related data.
80
+ - Never traverse lazy relationships inside a loop -- this causes N+1.
81
+
82
+ ### Connection pooling
83
+
84
+ - Use the ORM's built-in connection pool. Never open connections manually unless
85
+ the framework requires it.
86
+ - Set pool size appropriate for the workload. For SQLite, a pool size of 1 is
87
+ typical (single-writer constraint).
88
+
89
+ ## SQLite-Specific
90
+
91
+ When working with SQLite (better-sqlite3 or similar):
92
+
93
+ - Enable WAL mode for concurrent reads: `PRAGMA journal_mode=WAL;`
94
+ - Use synchronous API -- better-sqlite3 is synchronous by design. Do not wrap
95
+ calls in async wrappers unnecessarily.
96
+ - SQLite has no native DATETIME type -- store timestamps as ISO 8601 strings
97
+ or Unix epoch integers. Be consistent within the project.
98
+ - Use `INSERT OR REPLACE` or `ON CONFLICT` for upserts.
99
+ - Foreign keys are off by default -- ensure `PRAGMA foreign_keys = ON` is set
100
+ at connection time.
101
+
102
+ ## Common Pitfalls
103
+
104
+ ### String interpolation in queries
105
+
106
+ Never interpolate user input into SQL strings. Always use parameterized queries:
107
+
108
+ ```sql
109
+ -- WRONG (SQL injection risk)
110
+ SELECT * FROM users WHERE name = '${userName}';
111
+
112
+ -- RIGHT (parameterized)
113
+ SELECT * FROM users WHERE name = ?;
114
+ ```
115
+
116
+ ### Missing NOT NULL constraints
117
+
118
+ Default to `NOT NULL` for all columns unless NULL has a meaningful semantic
119
+ (e.g., `stopped_at` is NULL while a team is still running). Nullable columns
120
+ require NULL checks everywhere they are used.
121
+
122
+ ### Large transactions in SQLite
123
+
124
+ SQLite uses a single-writer model. Long-running write transactions block all
125
+ other writers. Keep write transactions as short as possible.