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.
- package/LICENSE +202 -0
- package/README.md +159 -0
- package/bin/fleet-commander-mcp.js +27 -0
- package/bin/fleet-commander.js +22 -0
- package/dist/client/assets/index-CHukC8Hq.js +188 -0
- package/dist/client/assets/index-CHukC8Hq.js.map +1 -0
- package/dist/client/assets/index-DvMjcYbg.css +1 -0
- package/dist/client/index.html +13 -0
- package/dist/server/config.d.ts +51 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +104 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/db.d.ts +388 -0
- package/dist/server/db.d.ts.map +1 -0
- package/dist/server/db.js +1524 -0
- package/dist/server/db.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +162 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/mcp/index.d.ts +2 -0
- package/dist/server/mcp/index.d.ts.map +1 -0
- package/dist/server/mcp/index.js +112 -0
- package/dist/server/mcp/index.js.map +1 -0
- package/dist/server/mcp/tools/add-project.d.ts +9 -0
- package/dist/server/mcp/tools/add-project.d.ts.map +1 -0
- package/dist/server/mcp/tools/add-project.js +58 -0
- package/dist/server/mcp/tools/add-project.js.map +1 -0
- package/dist/server/mcp/tools/get-team-timeline.d.ts +9 -0
- package/dist/server/mcp/tools/get-team-timeline.d.ts.map +1 -0
- package/dist/server/mcp/tools/get-team-timeline.js +48 -0
- package/dist/server/mcp/tools/get-team-timeline.js.map +1 -0
- package/dist/server/mcp/tools/get-team.d.ts +9 -0
- package/dist/server/mcp/tools/get-team.d.ts.map +1 -0
- package/dist/server/mcp/tools/get-team.js +48 -0
- package/dist/server/mcp/tools/get-team.js.map +1 -0
- package/dist/server/mcp/tools/get-usage.d.ts +9 -0
- package/dist/server/mcp/tools/get-usage.d.ts.map +1 -0
- package/dist/server/mcp/tools/get-usage.js +33 -0
- package/dist/server/mcp/tools/get-usage.js.map +1 -0
- package/dist/server/mcp/tools/launch-team.d.ts +8 -0
- package/dist/server/mcp/tools/launch-team.d.ts.map +1 -0
- package/dist/server/mcp/tools/launch-team.js +49 -0
- package/dist/server/mcp/tools/launch-team.js.map +1 -0
- package/dist/server/mcp/tools/list-issues.d.ts +9 -0
- package/dist/server/mcp/tools/list-issues.d.ts.map +1 -0
- package/dist/server/mcp/tools/list-issues.js +47 -0
- package/dist/server/mcp/tools/list-issues.js.map +1 -0
- package/dist/server/mcp/tools/list-projects.d.ts +9 -0
- package/dist/server/mcp/tools/list-projects.d.ts.map +1 -0
- package/dist/server/mcp/tools/list-projects.js +32 -0
- package/dist/server/mcp/tools/list-projects.js.map +1 -0
- package/dist/server/mcp/tools/list-teams.d.ts +9 -0
- package/dist/server/mcp/tools/list-teams.d.ts.map +1 -0
- package/dist/server/mcp/tools/list-teams.js +43 -0
- package/dist/server/mcp/tools/list-teams.js.map +1 -0
- package/dist/server/mcp/tools/restart-team.d.ts +8 -0
- package/dist/server/mcp/tools/restart-team.d.ts.map +1 -0
- package/dist/server/mcp/tools/restart-team.js +46 -0
- package/dist/server/mcp/tools/restart-team.js.map +1 -0
- package/dist/server/mcp/tools/send-message.d.ts +9 -0
- package/dist/server/mcp/tools/send-message.d.ts.map +1 -0
- package/dist/server/mcp/tools/send-message.js +48 -0
- package/dist/server/mcp/tools/send-message.js.map +1 -0
- package/dist/server/mcp/tools/stop-team.d.ts +8 -0
- package/dist/server/mcp/tools/stop-team.d.ts.map +1 -0
- package/dist/server/mcp/tools/stop-team.js +46 -0
- package/dist/server/mcp/tools/stop-team.js.map +1 -0
- package/dist/server/mcp/tools/system-health.d.ts +9 -0
- package/dist/server/mcp/tools/system-health.d.ts.map +1 -0
- package/dist/server/mcp/tools/system-health.js +32 -0
- package/dist/server/mcp/tools/system-health.js.map +1 -0
- package/dist/server/middleware/error-handler.d.ts +32 -0
- package/dist/server/middleware/error-handler.d.ts.map +1 -0
- package/dist/server/middleware/error-handler.js +65 -0
- package/dist/server/middleware/error-handler.js.map +1 -0
- package/dist/server/routes/events.d.ts +16 -0
- package/dist/server/routes/events.d.ts.map +1 -0
- package/dist/server/routes/events.js +164 -0
- package/dist/server/routes/events.js.map +1 -0
- package/dist/server/routes/issues.d.ts +4 -0
- package/dist/server/routes/issues.d.ts.map +1 -0
- package/dist/server/routes/issues.js +198 -0
- package/dist/server/routes/issues.js.map +1 -0
- package/dist/server/routes/project-groups.d.ts +4 -0
- package/dist/server/routes/project-groups.d.ts.map +1 -0
- package/dist/server/routes/project-groups.js +124 -0
- package/dist/server/routes/project-groups.js.map +1 -0
- package/dist/server/routes/projects.d.ts +4 -0
- package/dist/server/routes/projects.d.ts.map +1 -0
- package/dist/server/routes/projects.js +319 -0
- package/dist/server/routes/projects.js.map +1 -0
- package/dist/server/routes/prs.d.ts +4 -0
- package/dist/server/routes/prs.d.ts.map +1 -0
- package/dist/server/routes/prs.js +186 -0
- package/dist/server/routes/prs.js.map +1 -0
- package/dist/server/routes/query.d.ts +4 -0
- package/dist/server/routes/query.d.ts.map +1 -0
- package/dist/server/routes/query.js +82 -0
- package/dist/server/routes/query.js.map +1 -0
- package/dist/server/routes/state-machine.d.ts +4 -0
- package/dist/server/routes/state-machine.d.ts.map +1 -0
- package/dist/server/routes/state-machine.js +86 -0
- package/dist/server/routes/state-machine.js.map +1 -0
- package/dist/server/routes/stream.d.ts +18 -0
- package/dist/server/routes/stream.d.ts.map +1 -0
- package/dist/server/routes/stream.js +62 -0
- package/dist/server/routes/stream.js.map +1 -0
- package/dist/server/routes/system.d.ts +4 -0
- package/dist/server/routes/system.d.ts.map +1 -0
- package/dist/server/routes/system.js +225 -0
- package/dist/server/routes/system.js.map +1 -0
- package/dist/server/routes/teams.d.ts +4 -0
- package/dist/server/routes/teams.d.ts.map +1 -0
- package/dist/server/routes/teams.js +570 -0
- package/dist/server/routes/teams.js.map +1 -0
- package/dist/server/routes/usage.d.ts +4 -0
- package/dist/server/routes/usage.d.ts.map +1 -0
- package/dist/server/routes/usage.js +80 -0
- package/dist/server/routes/usage.js.map +1 -0
- package/dist/server/schema.sql +267 -0
- package/dist/server/services/cc-query.d.ts +20 -0
- package/dist/server/services/cc-query.d.ts.map +1 -0
- package/dist/server/services/cc-query.js +352 -0
- package/dist/server/services/cc-query.js.map +1 -0
- package/dist/server/services/cleanup.d.ts +15 -0
- package/dist/server/services/cleanup.d.ts.map +1 -0
- package/dist/server/services/cleanup.js +232 -0
- package/dist/server/services/cleanup.js.map +1 -0
- package/dist/server/services/diagnostics-service.d.ts +85 -0
- package/dist/server/services/diagnostics-service.d.ts.map +1 -0
- package/dist/server/services/diagnostics-service.js +242 -0
- package/dist/server/services/diagnostics-service.js.map +1 -0
- package/dist/server/services/event-collector.d.ts +125 -0
- package/dist/server/services/event-collector.d.ts.map +1 -0
- package/dist/server/services/event-collector.js +299 -0
- package/dist/server/services/event-collector.js.map +1 -0
- package/dist/server/services/event-service.d.ts +22 -0
- package/dist/server/services/event-service.d.ts.map +1 -0
- package/dist/server/services/event-service.js +53 -0
- package/dist/server/services/event-service.js.map +1 -0
- package/dist/server/services/github-poller.d.ts +68 -0
- package/dist/server/services/github-poller.d.ts.map +1 -0
- package/dist/server/services/github-poller.js +563 -0
- package/dist/server/services/github-poller.js.map +1 -0
- package/dist/server/services/issue-fetcher.d.ts +231 -0
- package/dist/server/services/issue-fetcher.d.ts.map +1 -0
- package/dist/server/services/issue-fetcher.js +1053 -0
- package/dist/server/services/issue-fetcher.js.map +1 -0
- package/dist/server/services/issue-service.d.ts +102 -0
- package/dist/server/services/issue-service.d.ts.map +1 -0
- package/dist/server/services/issue-service.js +279 -0
- package/dist/server/services/issue-service.js.map +1 -0
- package/dist/server/services/message-template-service.d.ts +39 -0
- package/dist/server/services/message-template-service.d.ts.map +1 -0
- package/dist/server/services/message-template-service.js +87 -0
- package/dist/server/services/message-template-service.js.map +1 -0
- package/dist/server/services/pr-service.d.ts +73 -0
- package/dist/server/services/pr-service.d.ts.map +1 -0
- package/dist/server/services/pr-service.js +231 -0
- package/dist/server/services/pr-service.js.map +1 -0
- package/dist/server/services/project-group-service.d.ts +64 -0
- package/dist/server/services/project-group-service.d.ts.map +1 -0
- package/dist/server/services/project-group-service.js +149 -0
- package/dist/server/services/project-group-service.js.map +1 -0
- package/dist/server/services/project-service.d.ts +161 -0
- package/dist/server/services/project-service.d.ts.map +1 -0
- package/dist/server/services/project-service.js +623 -0
- package/dist/server/services/project-service.js.map +1 -0
- package/dist/server/services/service-error.d.ts +25 -0
- package/dist/server/services/service-error.d.ts.map +1 -0
- package/dist/server/services/service-error.js +49 -0
- package/dist/server/services/service-error.js.map +1 -0
- package/dist/server/services/sse-broker.d.ts +144 -0
- package/dist/server/services/sse-broker.d.ts.map +1 -0
- package/dist/server/services/sse-broker.js +111 -0
- package/dist/server/services/sse-broker.js.map +1 -0
- package/dist/server/services/startup-recovery.d.ts +10 -0
- package/dist/server/services/startup-recovery.d.ts.map +1 -0
- package/dist/server/services/startup-recovery.js +122 -0
- package/dist/server/services/startup-recovery.js.map +1 -0
- package/dist/server/services/stuck-detector.d.ts +20 -0
- package/dist/server/services/stuck-detector.d.ts.map +1 -0
- package/dist/server/services/stuck-detector.js +167 -0
- package/dist/server/services/stuck-detector.js.map +1 -0
- package/dist/server/services/stuck-detector.test.d.ts +2 -0
- package/dist/server/services/stuck-detector.test.d.ts.map +1 -0
- package/dist/server/services/stuck-detector.test.js +363 -0
- package/dist/server/services/stuck-detector.test.js.map +1 -0
- package/dist/server/services/team-manager.d.ts +188 -0
- package/dist/server/services/team-manager.d.ts.map +1 -0
- package/dist/server/services/team-manager.js +1869 -0
- package/dist/server/services/team-manager.js.map +1 -0
- package/dist/server/services/team-service.d.ts +251 -0
- package/dist/server/services/team-service.d.ts.map +1 -0
- package/dist/server/services/team-service.js +707 -0
- package/dist/server/services/team-service.js.map +1 -0
- package/dist/server/services/usage-service.d.ts +42 -0
- package/dist/server/services/usage-service.d.ts.map +1 -0
- package/dist/server/services/usage-service.js +101 -0
- package/dist/server/services/usage-service.js.map +1 -0
- package/dist/server/services/usage-tracker.d.ts +68 -0
- package/dist/server/services/usage-tracker.d.ts.map +1 -0
- package/dist/server/services/usage-tracker.js +220 -0
- package/dist/server/services/usage-tracker.js.map +1 -0
- package/dist/server/utils/build-timeline.d.ts +32 -0
- package/dist/server/utils/build-timeline.d.ts.map +1 -0
- package/dist/server/utils/build-timeline.js +142 -0
- package/dist/server/utils/build-timeline.js.map +1 -0
- package/dist/server/utils/find-git-bash.d.ts +10 -0
- package/dist/server/utils/find-git-bash.d.ts.map +1 -0
- package/dist/server/utils/find-git-bash.js +46 -0
- package/dist/server/utils/find-git-bash.js.map +1 -0
- package/dist/server/utils/hook-installer.d.ts +20 -0
- package/dist/server/utils/hook-installer.d.ts.map +1 -0
- package/dist/server/utils/hook-installer.js +90 -0
- package/dist/server/utils/hook-installer.js.map +1 -0
- package/dist/server/utils/process-utils.d.ts +10 -0
- package/dist/server/utils/process-utils.d.ts.map +1 -0
- package/dist/server/utils/process-utils.js +33 -0
- package/dist/server/utils/process-utils.js.map +1 -0
- package/dist/server/utils/resolve-claude-path.d.ts +4 -0
- package/dist/server/utils/resolve-claude-path.d.ts.map +1 -0
- package/dist/server/utils/resolve-claude-path.js +66 -0
- package/dist/server/utils/resolve-claude-path.js.map +1 -0
- package/dist/server/utils/resolve-message.d.ts +10 -0
- package/dist/server/utils/resolve-message.d.ts.map +1 -0
- package/dist/server/utils/resolve-message.js +27 -0
- package/dist/server/utils/resolve-message.js.map +1 -0
- package/dist/shared/message-templates.d.ts +9 -0
- package/dist/shared/message-templates.d.ts.map +1 -0
- package/dist/shared/message-templates.js +88 -0
- package/dist/shared/message-templates.js.map +1 -0
- package/dist/shared/state-machine.d.ts +28 -0
- package/dist/shared/state-machine.d.ts.map +1 -0
- package/dist/shared/state-machine.js +282 -0
- package/dist/shared/state-machine.js.map +1 -0
- package/dist/shared/types.d.ts +404 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +5 -0
- package/dist/shared/types.js.map +1 -0
- package/hooks/DESIGN.md +562 -0
- package/hooks/on_notification.sh +9 -0
- package/hooks/on_post_tool_use.sh +9 -0
- package/hooks/on_pre_compact.sh +10 -0
- package/hooks/on_session_end.sh +8 -0
- package/hooks/on_session_start.sh +8 -0
- package/hooks/on_stop.sh +8 -0
- package/hooks/on_stop_failure.sh +8 -0
- package/hooks/on_subagent_start.sh +8 -0
- package/hooks/on_subagent_stop.sh +8 -0
- package/hooks/on_teammate_idle.sh +8 -0
- package/hooks/on_tool_error.sh +8 -0
- package/hooks/send_event.sh +101 -0
- package/hooks/settings.json.example +120 -0
- package/package.json +93 -0
- package/prompts/default-prompt.md +16 -0
- package/scripts/install.ps1 +22 -0
- package/scripts/install.sh +229 -0
- package/scripts/launch.js +64 -0
- package/scripts/uninstall.ps1 +22 -0
- package/scripts/uninstall.sh +123 -0
- package/templates/agents/fleet-dev.md +162 -0
- package/templates/agents/fleet-planner.md +263 -0
- package/templates/agents/fleet-reviewer.md +309 -0
- package/templates/archive/fleet-coordinator.md +128 -0
- package/templates/archive/fleet-dev-csharp.md +74 -0
- package/templates/archive/fleet-dev-devops.md +76 -0
- package/templates/archive/fleet-dev-fsharp.md +83 -0
- package/templates/archive/fleet-dev-generic.md +64 -0
- package/templates/archive/fleet-dev-python.md +75 -0
- package/templates/archive/fleet-dev-typescript.md +76 -0
- package/templates/guides/api-design.md +159 -0
- package/templates/guides/csharp-conventions.md +182 -0
- package/templates/guides/devops-conventions.md +192 -0
- package/templates/guides/fsharp-conventions.md +201 -0
- package/templates/guides/python-conventions.md +146 -0
- package/templates/guides/sql-database.md +125 -0
- package/templates/guides/testing-strategies.md +123 -0
- package/templates/guides/typescript-conventions.md +130 -0
- package/templates/workflow.md +513 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fleet-dev-generic
|
|
3
|
+
description: Generic developer agent. Handles any language or framework. Falls back to CLAUDE.md for project conventions. Use when no specialist matches the task.
|
|
4
|
+
tools: Glob, Grep, LS, Read, Edit, Write, Bash, WebFetch, WebSearch, Agent, Skill, ToolSearch
|
|
5
|
+
model: inherit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Generic Developer
|
|
9
|
+
|
|
10
|
+
You are a **Generic Developer** working on issue **#{{ISSUE_NUMBER}}** in **{{PROJECT_NAME}}**.
|
|
11
|
+
|
|
12
|
+
## About Fleet Commander
|
|
13
|
+
|
|
14
|
+
You are part of a team managed by Fleet Commander (FC). FC monitors your activity via hooks and communicates with you via stdin messages. FC handles CI/PR monitoring, idle/stuck detection (3min idle, 5min stuck), and dashboard visibility.
|
|
15
|
+
|
|
16
|
+
## Your Role
|
|
17
|
+
|
|
18
|
+
You are a generalist developer. You implement code changes, write tests, and deliver working commits. You adapt to whatever language, framework, or tooling the project uses by reading its CLAUDE.md and existing code conventions.
|
|
19
|
+
|
|
20
|
+
## Workflow
|
|
21
|
+
|
|
22
|
+
1. **Receive task** from Coordinator with issue details and target branch name
|
|
23
|
+
2. **Read CLAUDE.md** in the project root — this defines conventions, tech stack, and project rules
|
|
24
|
+
3. **Explore the codebase** — understand the relevant files, patterns, and test structure
|
|
25
|
+
4. **Create branch** from `{{BASE_BRANCH}}`:
|
|
26
|
+
```bash
|
|
27
|
+
git fetch origin {{BASE_BRANCH}}
|
|
28
|
+
git checkout -b {branch} origin/{{BASE_BRANCH}}
|
|
29
|
+
```
|
|
30
|
+
5. **Implement** the changes — follow existing code patterns and CLAUDE.md rules
|
|
31
|
+
6. **Test locally** — run the project's test command; fix failures before committing
|
|
32
|
+
7. **Commit atomically** — one logical commit per change unit:
|
|
33
|
+
```
|
|
34
|
+
Issue #{{ISSUE_NUMBER}}: {description}
|
|
35
|
+
```
|
|
36
|
+
8. **Rebase and push**:
|
|
37
|
+
```bash
|
|
38
|
+
git fetch origin {{BASE_BRANCH}} && git rebase origin/{{BASE_BRANCH}} && git push -u origin {branch}
|
|
39
|
+
```
|
|
40
|
+
9. **Report** to Coordinator: "Ready for review. Branch: `{branch}`"
|
|
41
|
+
|
|
42
|
+
## Branch Naming
|
|
43
|
+
|
|
44
|
+
- Features: `feat/{{ISSUE_NUMBER}}-{short-desc}`
|
|
45
|
+
- Bug fixes: `fix/{{ISSUE_NUMBER}}-{short-desc}`
|
|
46
|
+
- Tests: `test/{{ISSUE_NUMBER}}-{short-desc}`
|
|
47
|
+
|
|
48
|
+
## Commit Format
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Issue #{{ISSUE_NUMBER}}: {concise description of what changed}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
One commit per logical change. Squash fixups before pushing.
|
|
55
|
+
|
|
56
|
+
## Prohibitions
|
|
57
|
+
|
|
58
|
+
- Do NOT create PRs — the Coordinator handles that
|
|
59
|
+
- Do NOT merge branches or push to `{{BASE_BRANCH}}`
|
|
60
|
+
- Do NOT skip tests — if tests fail, fix them
|
|
61
|
+
- Do NOT deviate from CLAUDE.md conventions
|
|
62
|
+
- Do NOT install new dependencies without confirming they're needed for the task
|
|
63
|
+
- Do NOT work outside the scope of your assigned task
|
|
64
|
+
- On `shutdown_request` → respond `shutdown_response` with `approve: true`
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fleet-dev-python
|
|
3
|
+
description: Python specialist developer. Handles Django, Flask, FastAPI, SQLAlchemy, pytest, async, and type hints. Use for Python backend, scripting, and data work.
|
|
4
|
+
tools: Glob, Grep, LS, Read, Edit, Write, Bash, WebFetch, WebSearch, Agent, Skill, ToolSearch
|
|
5
|
+
model: inherit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Python Developer
|
|
9
|
+
|
|
10
|
+
You are a **Python Specialist Developer** working on issue **#{{ISSUE_NUMBER}}** in **{{PROJECT_NAME}}**.
|
|
11
|
+
|
|
12
|
+
## About Fleet Commander
|
|
13
|
+
|
|
14
|
+
You are part of a team managed by Fleet Commander (FC). FC monitors your activity via hooks and communicates with you via stdin messages. FC handles CI/PR monitoring, idle/stuck detection (3min idle, 5min stuck), and dashboard visibility.
|
|
15
|
+
|
|
16
|
+
## Your Role
|
|
17
|
+
|
|
18
|
+
You implement Python code following PEP 8, the project's conventions, and established framework patterns. You write typed, tested, production-quality code.
|
|
19
|
+
|
|
20
|
+
## Domain Knowledge
|
|
21
|
+
|
|
22
|
+
- **Frameworks**: Django (ORM, views, middleware), Flask (blueprints, extensions), FastAPI (Pydantic, dependency injection, async)
|
|
23
|
+
- **ORM/DB**: SQLAlchemy (Core + ORM, sessions, migrations via Alembic), Django ORM
|
|
24
|
+
- **Testing**: pytest (fixtures, parametrize, conftest), unittest, mock/monkeypatch
|
|
25
|
+
- **Async**: asyncio, `async/await`, aiohttp, async context managers
|
|
26
|
+
- **Type hints**: `typing` module, Pydantic models, mypy/pyright compliance
|
|
27
|
+
- **Packaging**: pip, venv, requirements.txt, pyproject.toml, poetry, uv
|
|
28
|
+
|
|
29
|
+
## Workflow
|
|
30
|
+
|
|
31
|
+
1. **Receive task** from Coordinator with issue details and target branch name
|
|
32
|
+
2. **Read CLAUDE.md** in the project root for project-specific conventions
|
|
33
|
+
3. **Check environment** — identify virtualenv, dependency management, and test runner
|
|
34
|
+
4. **Create branch** from `{{BASE_BRANCH}}`:
|
|
35
|
+
```bash
|
|
36
|
+
git fetch origin {{BASE_BRANCH}}
|
|
37
|
+
git checkout -b {branch} origin/{{BASE_BRANCH}}
|
|
38
|
+
```
|
|
39
|
+
5. **Implement** — follow PEP 8, existing patterns, and type annotation style
|
|
40
|
+
6. **Test locally**: `pytest` (or project-specific command) — fix failures before committing
|
|
41
|
+
7. **Commit atomically**:
|
|
42
|
+
```
|
|
43
|
+
Issue #{{ISSUE_NUMBER}}: {description}
|
|
44
|
+
```
|
|
45
|
+
8. **Rebase and push**:
|
|
46
|
+
```bash
|
|
47
|
+
git fetch origin {{BASE_BRANCH}} && git rebase origin/{{BASE_BRANCH}} && git push -u origin {branch}
|
|
48
|
+
```
|
|
49
|
+
9. **Report** to Coordinator: "Ready for review. Branch: `{branch}`"
|
|
50
|
+
|
|
51
|
+
## Branch Naming
|
|
52
|
+
|
|
53
|
+
- Features: `feat/{{ISSUE_NUMBER}}-{short-desc}`
|
|
54
|
+
- Bug fixes: `fix/{{ISSUE_NUMBER}}-{short-desc}`
|
|
55
|
+
- Tests: `test/{{ISSUE_NUMBER}}-{short-desc}`
|
|
56
|
+
|
|
57
|
+
## Python-Specific Rules
|
|
58
|
+
|
|
59
|
+
- Activate the project's virtualenv before running any Python commands
|
|
60
|
+
- Add type hints to all new functions and method signatures
|
|
61
|
+
- Use `pathlib.Path` over `os.path` for file operations
|
|
62
|
+
- Django: create migrations via `makemigrations`, never edit migration files manually
|
|
63
|
+
- FastAPI: use Pydantic models for request/response schemas
|
|
64
|
+
- Keep imports organized: stdlib → third-party → local (match existing style or use isort)
|
|
65
|
+
|
|
66
|
+
## Prohibitions
|
|
67
|
+
|
|
68
|
+
- Do NOT create PRs — the Coordinator handles that
|
|
69
|
+
- Do NOT merge branches or push to `{{BASE_BRANCH}}`
|
|
70
|
+
- Do NOT skip tests — if tests fail, fix them
|
|
71
|
+
- Do NOT deviate from CLAUDE.md conventions
|
|
72
|
+
- Do NOT install packages outside the virtualenv
|
|
73
|
+
- Do NOT add dependencies without confirming they're needed for the task
|
|
74
|
+
- Do NOT work outside the scope of your assigned task
|
|
75
|
+
- On `shutdown_request` → respond `shutdown_response` with `approve: true`
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fleet-dev-typescript
|
|
3
|
+
description: TypeScript/JavaScript specialist developer. Handles React, Node.js, Vitest, Playwright, and modern JS tooling. Use for frontend, backend, and full-stack TS/JS work.
|
|
4
|
+
tools: Glob, Grep, LS, Read, Edit, Write, Bash, WebFetch, WebSearch, Agent, Skill, ToolSearch
|
|
5
|
+
preferred_plugins: playwright
|
|
6
|
+
model: inherit
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# TypeScript / JavaScript Developer
|
|
10
|
+
|
|
11
|
+
You are a **TypeScript/JS Specialist Developer** working on issue **#{{ISSUE_NUMBER}}** in **{{PROJECT_NAME}}**.
|
|
12
|
+
|
|
13
|
+
## About Fleet Commander
|
|
14
|
+
|
|
15
|
+
You are part of a team managed by Fleet Commander (FC). FC monitors your activity via hooks and communicates with you via stdin messages. FC handles CI/PR monitoring, idle/stuck detection (3min idle, 5min stuck), and dashboard visibility.
|
|
16
|
+
|
|
17
|
+
## Your Role
|
|
18
|
+
|
|
19
|
+
You implement TypeScript and JavaScript changes across frontend, backend, and full-stack codebases. You write strongly typed, tested, production-quality code.
|
|
20
|
+
|
|
21
|
+
## Domain Knowledge
|
|
22
|
+
|
|
23
|
+
- **Frontend**: React (hooks, context, suspense), Vue, Svelte, Tailwind CSS, CSS modules
|
|
24
|
+
- **Backend**: Node.js, Express, Fastify, NestJS, tRPC
|
|
25
|
+
- **Testing**: Vitest, Jest (describe/it/expect), Testing Library, Playwright (E2E)
|
|
26
|
+
- **Build**: Vite, webpack, tsup, esbuild, tsc
|
|
27
|
+
- **Package managers**: npm, pnpm, yarn — use whichever lockfile exists in the project
|
|
28
|
+
- **Quality**: ESLint, Prettier, TypeScript strict mode
|
|
29
|
+
|
|
30
|
+
## Workflow
|
|
31
|
+
|
|
32
|
+
1. **Receive task** from Coordinator with issue details and target branch name
|
|
33
|
+
2. **Read CLAUDE.md** in the project root for project-specific framework and conventions
|
|
34
|
+
3. **Check tsconfig.json** — understand strict mode, paths, and module resolution
|
|
35
|
+
4. **Create branch** from `{{BASE_BRANCH}}`:
|
|
36
|
+
```bash
|
|
37
|
+
git fetch origin {{BASE_BRANCH}}
|
|
38
|
+
git checkout -b {branch} origin/{{BASE_BRANCH}}
|
|
39
|
+
```
|
|
40
|
+
5. **Implement** — follow existing patterns, use proper TypeScript types (no `any` leaks)
|
|
41
|
+
6. **Test locally**: run the project's test command — fix failures before committing
|
|
42
|
+
7. **Commit atomically**:
|
|
43
|
+
```
|
|
44
|
+
Issue #{{ISSUE_NUMBER}}: {description}
|
|
45
|
+
```
|
|
46
|
+
8. **Rebase and push**:
|
|
47
|
+
```bash
|
|
48
|
+
git fetch origin {{BASE_BRANCH}} && git rebase origin/{{BASE_BRANCH}} && git push -u origin {branch}
|
|
49
|
+
```
|
|
50
|
+
9. **Report** to Coordinator: "Ready for review. Branch: `{branch}`"
|
|
51
|
+
|
|
52
|
+
## Branch Naming
|
|
53
|
+
|
|
54
|
+
- Features: `feat/{{ISSUE_NUMBER}}-{short-desc}`
|
|
55
|
+
- Bug fixes: `fix/{{ISSUE_NUMBER}}-{short-desc}`
|
|
56
|
+
- Tests: `test/{{ISSUE_NUMBER}}-{short-desc}`
|
|
57
|
+
|
|
58
|
+
## TypeScript-Specific Rules
|
|
59
|
+
|
|
60
|
+
- Use the project's package manager (check for `pnpm-lock.yaml`, `yarn.lock`, or `package-lock.json`)
|
|
61
|
+
- No `any` types — use `unknown` + type guards, generics, or proper interfaces
|
|
62
|
+
- React: functional components only, hooks for state/effects, avoid prop drilling
|
|
63
|
+
- Prefer named exports over default exports (unless project convention differs)
|
|
64
|
+
- Run `tsc --noEmit` to catch type errors before committing
|
|
65
|
+
- For Playwright E2E: use the MCP plugin for browser interaction when available
|
|
66
|
+
|
|
67
|
+
## Prohibitions
|
|
68
|
+
|
|
69
|
+
- Do NOT create PRs — the Coordinator handles that
|
|
70
|
+
- Do NOT merge branches or push to `{{BASE_BRANCH}}`
|
|
71
|
+
- Do NOT skip tests — if tests fail, fix them
|
|
72
|
+
- Do NOT deviate from CLAUDE.md conventions
|
|
73
|
+
- Do NOT use `any` — find the correct type
|
|
74
|
+
- Do NOT add npm packages without confirming they're needed for the task
|
|
75
|
+
- Do NOT work outside the scope of your assigned task
|
|
76
|
+
- On `shutdown_request` → respond `shutdown_response` with `approve: true`
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# API Design Conventions
|
|
2
|
+
|
|
3
|
+
> Applies to: REST API route handlers, request/response schemas, middleware
|
|
4
|
+
> Last updated: 2026-03-18
|
|
5
|
+
|
|
6
|
+
## REST Conventions
|
|
7
|
+
|
|
8
|
+
### HTTP Methods
|
|
9
|
+
|
|
10
|
+
| Method | Use | Idempotent |
|
|
11
|
+
|--------|-----|-----------|
|
|
12
|
+
| `GET` | Retrieve resource(s) | Yes |
|
|
13
|
+
| `POST` | Create a resource or trigger an action | No |
|
|
14
|
+
| `PUT` | Replace a resource entirely | Yes |
|
|
15
|
+
| `PATCH` | Partially update a resource | No |
|
|
16
|
+
| `DELETE` | Remove a resource | Yes |
|
|
17
|
+
|
|
18
|
+
### Resource Naming
|
|
19
|
+
|
|
20
|
+
- Use plural nouns for collections: `/teams`, `/projects`, `/events`.
|
|
21
|
+
- Use the resource ID for individual items: `/teams/42`, `/projects/7`.
|
|
22
|
+
- Nest sub-resources when there is a clear parent-child relationship:
|
|
23
|
+
`/teams/42/events`, `/projects/7/teams`.
|
|
24
|
+
- Avoid verbs in URLs -- use HTTP methods to express the action:
|
|
25
|
+
`POST /teams/42/stop` (action) is acceptable; `GET /getTeamById` is not.
|
|
26
|
+
|
|
27
|
+
### Status Codes
|
|
28
|
+
|
|
29
|
+
| Code | When to use |
|
|
30
|
+
|------|------------|
|
|
31
|
+
| `200` | Successful GET, PUT, PATCH, DELETE |
|
|
32
|
+
| `201` | Successful POST that created a resource (include `Location` header) |
|
|
33
|
+
| `204` | Successful DELETE with no response body |
|
|
34
|
+
| `400` | Invalid request (missing fields, wrong types, validation failure) |
|
|
35
|
+
| `404` | Resource not found |
|
|
36
|
+
| `409` | Conflict (duplicate, state violation) |
|
|
37
|
+
| `422` | Semantically invalid request (valid JSON but business rule violation) |
|
|
38
|
+
| `500` | Unexpected server error |
|
|
39
|
+
|
|
40
|
+
## Error Responses
|
|
41
|
+
|
|
42
|
+
Use a consistent error response format across all endpoints:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"error": {
|
|
47
|
+
"code": "VALIDATION_ERROR",
|
|
48
|
+
"message": "Human-readable description of what went wrong",
|
|
49
|
+
"details": [
|
|
50
|
+
{ "field": "issueNumber", "message": "Must be a positive integer" }
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Rules:
|
|
57
|
+
- Always return JSON for errors, never plain text or HTML.
|
|
58
|
+
- Include a machine-readable `code` (for client error handling) and a
|
|
59
|
+
human-readable `message` (for debugging).
|
|
60
|
+
- Include `details` array for validation errors with per-field messages.
|
|
61
|
+
- Never expose stack traces, internal paths, or database errors to clients.
|
|
62
|
+
|
|
63
|
+
## Pagination
|
|
64
|
+
|
|
65
|
+
### Cursor-based (preferred)
|
|
66
|
+
|
|
67
|
+
Use cursor-based pagination for large or frequently updated collections:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
GET /events?cursor=eyJpZCI6MTAwfQ&limit=50
|
|
71
|
+
|
|
72
|
+
Response:
|
|
73
|
+
{
|
|
74
|
+
"data": [...],
|
|
75
|
+
"cursor": {
|
|
76
|
+
"next": "eyJpZCI6MTUwfQ",
|
|
77
|
+
"hasMore": true
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Offset/limit (simple cases)
|
|
83
|
+
|
|
84
|
+
Acceptable for small, stable collections:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
GET /teams?offset=20&limit=10
|
|
88
|
+
|
|
89
|
+
Response:
|
|
90
|
+
{
|
|
91
|
+
"data": [...],
|
|
92
|
+
"total": 85,
|
|
93
|
+
"offset": 20,
|
|
94
|
+
"limit": 10
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Always enforce a maximum limit (e.g., 100) to prevent clients from requesting
|
|
99
|
+
unbounded result sets.
|
|
100
|
+
|
|
101
|
+
## Input Validation
|
|
102
|
+
|
|
103
|
+
- Validate all input at the API boundary -- do not trust client data.
|
|
104
|
+
- Return `400` with clear error messages for invalid input.
|
|
105
|
+
- Use the framework's schema validation (Fastify JSON Schema, Pydantic,
|
|
106
|
+
FluentValidation, Zod) rather than manual validation.
|
|
107
|
+
- Validate types, ranges, required fields, and string formats.
|
|
108
|
+
- Sanitize strings to prevent injection attacks (SQL, command, XSS).
|
|
109
|
+
|
|
110
|
+
## Versioning
|
|
111
|
+
|
|
112
|
+
When the project requires API versioning:
|
|
113
|
+
|
|
114
|
+
- URL prefix is the simplest approach: `/api/v1/teams`, `/api/v2/teams`.
|
|
115
|
+
- Accept header versioning is an alternative: `Accept: application/vnd.api.v2+json`.
|
|
116
|
+
- Match whatever the project already uses. Do not introduce a new versioning
|
|
117
|
+
scheme.
|
|
118
|
+
|
|
119
|
+
## Security
|
|
120
|
+
|
|
121
|
+
### Authentication and authorization
|
|
122
|
+
|
|
123
|
+
- Check auth on every endpoint that requires it. Do not rely on frontend-only
|
|
124
|
+
protection.
|
|
125
|
+
- Use middleware or decorators for auth checks -- do not repeat auth logic in
|
|
126
|
+
every handler.
|
|
127
|
+
- Return `401` for missing/invalid credentials, `403` for insufficient permissions.
|
|
128
|
+
|
|
129
|
+
### Input sanitization
|
|
130
|
+
|
|
131
|
+
- Escape or parameterize all user input before using it in SQL, shell commands,
|
|
132
|
+
or HTML output.
|
|
133
|
+
- Validate file paths to prevent path traversal (`../../../etc/passwd`).
|
|
134
|
+
- Set appropriate CORS headers -- do not use `*` in production.
|
|
135
|
+
|
|
136
|
+
### Rate limiting
|
|
137
|
+
|
|
138
|
+
- Apply rate limits to public-facing endpoints to prevent abuse.
|
|
139
|
+
- Use the framework's rate limiting middleware when available.
|
|
140
|
+
- Return `429 Too Many Requests` with a `Retry-After` header.
|
|
141
|
+
|
|
142
|
+
## Common Pitfalls
|
|
143
|
+
|
|
144
|
+
### Inconsistent response shapes
|
|
145
|
+
|
|
146
|
+
Every endpoint should return the same shape for success responses (e.g., always
|
|
147
|
+
wrap in `{ "data": ... }`) and the same shape for errors. Inconsistency makes
|
|
148
|
+
client code fragile.
|
|
149
|
+
|
|
150
|
+
### Missing content-type headers
|
|
151
|
+
|
|
152
|
+
Always set `Content-Type: application/json` for JSON responses. Frameworks
|
|
153
|
+
usually handle this, but verify when returning manual responses.
|
|
154
|
+
|
|
155
|
+
### Leaking internal errors
|
|
156
|
+
|
|
157
|
+
A 500 response should return a generic error message to the client and log the
|
|
158
|
+
full error server-side. Never return database error messages, stack traces, or
|
|
159
|
+
internal file paths in API responses.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# C# / .NET Conventions
|
|
2
|
+
|
|
3
|
+
> Applies to: `*.cs`, `*.csproj`, `Directory.Build.props`
|
|
4
|
+
> Last updated: 2026-03-18
|
|
5
|
+
|
|
6
|
+
## Architecture
|
|
7
|
+
|
|
8
|
+
C# projects typically follow a layered or DDD architecture. Read the solution
|
|
9
|
+
structure (`.sln` and `.csproj` files) to understand the layers before making
|
|
10
|
+
changes.
|
|
11
|
+
|
|
12
|
+
Common layer patterns:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
Domain/ -- Entities, value objects, aggregates, domain events, interfaces
|
|
16
|
+
Application/ -- Use cases, commands, queries, DTOs, service interfaces
|
|
17
|
+
Infrastructure/ -- Database, external APIs, file system, DI registration
|
|
18
|
+
Api/ or Web/ -- Controllers, middleware, filters, model binding, startup
|
|
19
|
+
Tests/ -- Unit, integration, and E2E test projects
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Each layer depends only on layers above it in the list (Domain has zero
|
|
23
|
+
dependencies; Api depends on everything).
|
|
24
|
+
|
|
25
|
+
## Naming Conventions
|
|
26
|
+
|
|
27
|
+
| Element | Convention | Example |
|
|
28
|
+
|---------|-----------|---------|
|
|
29
|
+
| Classes | PascalCase, noun | `OrderService`, `CustomerRepository` |
|
|
30
|
+
| Interfaces | `I` prefix + PascalCase | `IOrderRepository`, `IEmailSender` |
|
|
31
|
+
| Methods | PascalCase, verb | `GetOrderById`, `CalculateTotal` |
|
|
32
|
+
| Async methods | suffix `Async` | `GetOrderByIdAsync` |
|
|
33
|
+
| Private fields | `_camelCase` | `_orderRepository`, `_logger` |
|
|
34
|
+
| Parameters | camelCase | `orderId`, `cancellationToken` |
|
|
35
|
+
| Constants | PascalCase | `MaxRetryCount`, `DefaultTimeout` |
|
|
36
|
+
| Namespaces | match folder path | `Company.Project.Domain.Orders` |
|
|
37
|
+
|
|
38
|
+
## Patterns to Follow
|
|
39
|
+
|
|
40
|
+
### Dependency injection
|
|
41
|
+
|
|
42
|
+
All services are registered in the DI container. Never use `new` for injected
|
|
43
|
+
dependencies. Constructor injection is the default:
|
|
44
|
+
|
|
45
|
+
```csharp
|
|
46
|
+
public class OrderService
|
|
47
|
+
{
|
|
48
|
+
private readonly IOrderRepository _orderRepository;
|
|
49
|
+
private readonly ILogger<OrderService> _logger;
|
|
50
|
+
|
|
51
|
+
public OrderService(IOrderRepository orderRepository, ILogger<OrderService> logger)
|
|
52
|
+
{
|
|
53
|
+
_orderRepository = orderRepository;
|
|
54
|
+
_logger = logger;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Register services with the appropriate lifetime:
|
|
60
|
+
- `Singleton` -- stateless services, configuration, caches
|
|
61
|
+
- `Scoped` -- per-request services, DbContext, unit of work
|
|
62
|
+
- `Transient` -- lightweight, stateless, no shared state
|
|
63
|
+
|
|
64
|
+
### Entity Framework Core
|
|
65
|
+
|
|
66
|
+
- Create migrations with `dotnet ef migrations add {Name}` -- never edit
|
|
67
|
+
generated migration files.
|
|
68
|
+
- Use `IQueryable` in repositories, materialize with `ToListAsync()` at the
|
|
69
|
+
application layer.
|
|
70
|
+
- Configure entities in separate `IEntityTypeConfiguration<T>` classes, not
|
|
71
|
+
in `OnModelCreating`.
|
|
72
|
+
- Always use `async` variants: `SaveChangesAsync`, `ToListAsync`, `FirstOrDefaultAsync`.
|
|
73
|
+
|
|
74
|
+
### Async/await
|
|
75
|
+
|
|
76
|
+
- Use `async/await` consistently. Never call `.Result` or `.Wait()` on hot
|
|
77
|
+
paths -- it causes thread pool starvation.
|
|
78
|
+
- Accept `CancellationToken` in all async public methods and pass it through.
|
|
79
|
+
- `ConfigureAwait(false)` in library code; omit in ASP.NET controller code.
|
|
80
|
+
|
|
81
|
+
### DDD patterns (when the project uses them)
|
|
82
|
+
|
|
83
|
+
- **Aggregates**: encapsulate invariants. External code accesses child entities
|
|
84
|
+
only through the aggregate root.
|
|
85
|
+
- **Value Objects**: immutable, compared by value. Use records or override
|
|
86
|
+
`Equals`/`GetHashCode`.
|
|
87
|
+
- **Domain Events**: raise events from aggregates, handle in application layer.
|
|
88
|
+
- **Repositories**: one per aggregate root. Return domain entities, not DTOs.
|
|
89
|
+
|
|
90
|
+
## Anti-Patterns to Avoid
|
|
91
|
+
|
|
92
|
+
### Anemic domain model
|
|
93
|
+
|
|
94
|
+
Do not put all business logic in services while entities are just data bags.
|
|
95
|
+
If the project uses DDD, entities should enforce their own invariants:
|
|
96
|
+
|
|
97
|
+
```csharp
|
|
98
|
+
// WRONG -- logic in service
|
|
99
|
+
service.ShipOrder(order);
|
|
100
|
+
order.Status = OrderStatus.Shipped;
|
|
101
|
+
|
|
102
|
+
// RIGHT -- logic in entity
|
|
103
|
+
order.Ship(); // internally validates and sets status
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Service locator
|
|
107
|
+
|
|
108
|
+
Never resolve services from `IServiceProvider` directly in business logic.
|
|
109
|
+
Use constructor injection. The service locator pattern hides dependencies and
|
|
110
|
+
makes testing difficult.
|
|
111
|
+
|
|
112
|
+
### Catching Exception base type
|
|
113
|
+
|
|
114
|
+
Do not catch `Exception` generically unless you are at an application boundary
|
|
115
|
+
(global error handler, middleware). Catch specific exception types:
|
|
116
|
+
|
|
117
|
+
```csharp
|
|
118
|
+
// WRONG
|
|
119
|
+
try { ... } catch (Exception ex) { _logger.LogError(ex, "Failed"); }
|
|
120
|
+
|
|
121
|
+
// RIGHT
|
|
122
|
+
try { ... } catch (OrderNotFoundException ex) { return NotFound(); }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Magic strings
|
|
126
|
+
|
|
127
|
+
Use constants, enums, or strongly-typed IDs instead of string literals for
|
|
128
|
+
status codes, configuration keys, or identifiers.
|
|
129
|
+
|
|
130
|
+
## Dependencies & Imports
|
|
131
|
+
|
|
132
|
+
- Use the project's C# version and nullable reference type settings.
|
|
133
|
+
- Add `using` directives at the top of the file, organized: System, third-party,
|
|
134
|
+
project namespaces.
|
|
135
|
+
- Do not add NuGet packages without confirming they are needed for the task.
|
|
136
|
+
- When adding a NuGet package, add it to the correct `.csproj` (not the solution root
|
|
137
|
+
unless it is a shared dependency).
|
|
138
|
+
|
|
139
|
+
## Testing
|
|
140
|
+
|
|
141
|
+
- **Framework**: Match the project (xUnit, NUnit, MSTest).
|
|
142
|
+
- **Mocking**: Use Moq, NSubstitute, or FakeItEasy -- whichever the project uses.
|
|
143
|
+
- **Integration tests**: Use `WebApplicationFactory<T>` for ASP.NET API tests.
|
|
144
|
+
- **Naming**: `MethodName_Condition_ExpectedResult` or the project's existing convention.
|
|
145
|
+
- **Arrange-Act-Assert**: Structure every test with clear AAA sections.
|
|
146
|
+
- Run `dotnet test` and fix all failures before committing.
|
|
147
|
+
|
|
148
|
+
## Build & Run
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
dotnet build # Compile the solution
|
|
152
|
+
dotnet test # Run all tests
|
|
153
|
+
dotnet run --project {ProjectName} # Run a specific project
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Check `Directory.Build.props` for shared build settings (nullable, implicit
|
|
157
|
+
usings, target framework) before adding project-level overrides.
|
|
158
|
+
|
|
159
|
+
## Common Pitfalls
|
|
160
|
+
|
|
161
|
+
### Nullable reference types
|
|
162
|
+
|
|
163
|
+
If the project has `<Nullable>enable</Nullable>`, treat all warnings as errors.
|
|
164
|
+
Do not suppress with `!` (null-forgiving operator) unless you can prove the
|
|
165
|
+
value is never null at that point.
|
|
166
|
+
|
|
167
|
+
### EF Core migration conflicts
|
|
168
|
+
|
|
169
|
+
When working on a branch, another branch may have added a migration. After
|
|
170
|
+
rebase, if the model snapshot conflicts, delete your migration and recreate it
|
|
171
|
+
against the rebased model state. Never merge migration snapshot files manually.
|
|
172
|
+
|
|
173
|
+
### Async void
|
|
174
|
+
|
|
175
|
+
Never use `async void` except for event handlers. It swallows exceptions and
|
|
176
|
+
cannot be awaited. Use `async Task` for all async methods.
|
|
177
|
+
|
|
178
|
+
### IDisposable leaks
|
|
179
|
+
|
|
180
|
+
If you create a disposable resource (HttpClient, Stream, DbConnection), ensure
|
|
181
|
+
it is disposed via `using` statement or DI container lifetime management. Prefer
|
|
182
|
+
`IHttpClientFactory` over `new HttpClient()`.
|