oh-my-customcode 0.12.1 → 0.12.3
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/README.md +8 -11
- package/dist/cli/index.js +137 -336
- package/dist/index.js +99 -260
- package/package.json +2 -4
- package/templates/.claude/skills/codex-exec/SKILL.md +123 -0
- package/templates/.claude/skills/codex-exec/scripts/codex-wrapper.cjs +413 -0
- package/templates/CLAUDE.md.en +1 -0
- package/templates/CLAUDE.md.ko +1 -0
- package/templates/.codex/agents/arch-documenter.md +0 -33
- package/templates/.codex/agents/arch-speckit-agent.md +0 -47
- package/templates/.codex/agents/be-express-expert.md +0 -30
- package/templates/.codex/agents/be-fastapi-expert.md +0 -43
- package/templates/.codex/agents/be-go-backend-expert.md +0 -43
- package/templates/.codex/agents/be-nestjs-expert.md +0 -28
- package/templates/.codex/agents/be-springboot-expert.md +0 -40
- package/templates/.codex/agents/db-postgres-expert.md +0 -36
- package/templates/.codex/agents/db-redis-expert.md +0 -36
- package/templates/.codex/agents/db-supabase-expert.md +0 -35
- package/templates/.codex/agents/de-airflow-expert.md +0 -34
- package/templates/.codex/agents/de-dbt-expert.md +0 -34
- package/templates/.codex/agents/de-kafka-expert.md +0 -81
- package/templates/.codex/agents/de-pipeline-expert.md +0 -32
- package/templates/.codex/agents/de-snowflake-expert.md +0 -36
- package/templates/.codex/agents/de-spark-expert.md +0 -36
- package/templates/.codex/agents/fe-svelte-agent.md +0 -29
- package/templates/.codex/agents/fe-vercel-agent.md +0 -37
- package/templates/.codex/agents/fe-vuejs-agent.md +0 -30
- package/templates/.codex/agents/infra-aws-expert.md +0 -47
- package/templates/.codex/agents/infra-docker-expert.md +0 -47
- package/templates/.codex/agents/lang-golang-expert.md +0 -43
- package/templates/.codex/agents/lang-java21-expert.md +0 -39
- package/templates/.codex/agents/lang-kotlin-expert.md +0 -43
- package/templates/.codex/agents/lang-python-expert.md +0 -43
- package/templates/.codex/agents/lang-rust-expert.md +0 -43
- package/templates/.codex/agents/lang-typescript-expert.md +0 -43
- package/templates/.codex/agents/mgr-claude-code-bible.md +0 -58
- package/templates/.codex/agents/mgr-creator.md +0 -39
- package/templates/.codex/agents/mgr-gitnerd.md +0 -45
- package/templates/.codex/agents/mgr-sauron.md +0 -161
- package/templates/.codex/agents/mgr-supplier.md +0 -35
- package/templates/.codex/agents/mgr-sync-checker.md +0 -38
- package/templates/.codex/agents/mgr-updater.md +0 -33
- package/templates/.codex/agents/qa-engineer.md +0 -32
- package/templates/.codex/agents/qa-planner.md +0 -73
- package/templates/.codex/agents/qa-writer.md +0 -27
- package/templates/.codex/agents/sys-memory-keeper.md +0 -43
- package/templates/.codex/agents/sys-naggy.md +0 -37
- package/templates/.codex/agents/tool-bun-expert.md +0 -26
- package/templates/.codex/agents/tool-npm-expert.md +0 -30
- package/templates/.codex/agents/tool-optimizer.md +0 -34
- package/templates/.codex/codex-native-hash.txt +0 -1
- package/templates/.codex/contexts/dev.md +0 -20
- package/templates/.codex/contexts/ecomode.md +0 -63
- package/templates/.codex/contexts/index.yaml +0 -41
- package/templates/.codex/contexts/research.md +0 -28
- package/templates/.codex/contexts/review.md +0 -23
- package/templates/.codex/hooks/hooks.json +0 -150
- package/templates/.codex/install-hooks.sh +0 -100
- package/templates/.codex/rules/MAY-optimization.md +0 -29
- package/templates/.codex/rules/MUST-agent-design.md +0 -57
- package/templates/.codex/rules/MUST-agent-identification.md +0 -29
- package/templates/.codex/rules/MUST-continuous-improvement.md +0 -25
- package/templates/.codex/rules/MUST-intent-transparency.md +0 -42
- package/templates/.codex/rules/MUST-language-policy.md +0 -27
- package/templates/.codex/rules/MUST-orchestrator-coordination.md +0 -128
- package/templates/.codex/rules/MUST-parallel-execution.md +0 -97
- package/templates/.codex/rules/MUST-permissions.md +0 -30
- package/templates/.codex/rules/MUST-safety.md +0 -23
- package/templates/.codex/rules/MUST-sync-verification.md +0 -125
- package/templates/.codex/rules/MUST-tool-identification.md +0 -82
- package/templates/.codex/rules/SHOULD-agent-teams.md +0 -39
- package/templates/.codex/rules/SHOULD-ecomode.md +0 -37
- package/templates/.codex/rules/SHOULD-error-handling.md +0 -33
- package/templates/.codex/rules/SHOULD-hud-statusline.md +0 -32
- package/templates/.codex/rules/SHOULD-interaction.md +0 -34
- package/templates/.codex/rules/SHOULD-memory-integration.md +0 -39
- package/templates/.codex/rules/index.yaml +0 -141
- package/templates/.codex/skills/airflow-best-practices/SKILL.md +0 -56
- package/templates/.codex/skills/audit-agents/SKILL.md +0 -116
- package/templates/.codex/skills/aws-best-practices/SKILL.md +0 -280
- package/templates/.codex/skills/claude-code-bible/SKILL.md +0 -100
- package/templates/.codex/skills/claude-code-bible/scripts/fetch-docs.js +0 -272
- package/templates/.codex/skills/create-agent/SKILL.md +0 -91
- package/templates/.codex/skills/dbt-best-practices/SKILL.md +0 -54
- package/templates/.codex/skills/de-lead-routing/SKILL.md +0 -243
- package/templates/.codex/skills/dev-lead-routing/SKILL.md +0 -94
- package/templates/.codex/skills/dev-refactor/SKILL.md +0 -123
- package/templates/.codex/skills/dev-review/SKILL.md +0 -81
- package/templates/.codex/skills/docker-best-practices/SKILL.md +0 -275
- package/templates/.codex/skills/fastapi-best-practices/SKILL.md +0 -270
- package/templates/.codex/skills/fix-refs/SKILL.md +0 -107
- package/templates/.codex/skills/go-backend-best-practices/SKILL.md +0 -338
- package/templates/.codex/skills/go-best-practices/SKILL.md +0 -203
- package/templates/.codex/skills/help/SKILL.md +0 -125
- package/templates/.codex/skills/intent-detection/SKILL.md +0 -215
- package/templates/.codex/skills/intent-detection/patterns/agent-triggers.yaml +0 -349
- package/templates/.codex/skills/kafka-best-practices/SKILL.md +0 -52
- package/templates/.codex/skills/kotlin-best-practices/SKILL.md +0 -256
- package/templates/.codex/skills/lists/SKILL.md +0 -78
- package/templates/.codex/skills/memory-management/SKILL.md +0 -195
- package/templates/.codex/skills/memory-recall/SKILL.md +0 -152
- package/templates/.codex/skills/memory-save/SKILL.md +0 -126
- package/templates/.codex/skills/monitoring-setup/SKILL.md +0 -115
- package/templates/.codex/skills/npm-audit/SKILL.md +0 -72
- package/templates/.codex/skills/npm-publish/SKILL.md +0 -63
- package/templates/.codex/skills/npm-version/SKILL.md +0 -75
- package/templates/.codex/skills/optimize-analyze/SKILL.md +0 -55
- package/templates/.codex/skills/optimize-bundle/SKILL.md +0 -67
- package/templates/.codex/skills/optimize-report/SKILL.md +0 -74
- package/templates/.codex/skills/pipeline-architecture-patterns/SKILL.md +0 -83
- package/templates/.codex/skills/postgres-best-practices/SKILL.md +0 -66
- package/templates/.codex/skills/python-best-practices/SKILL.md +0 -222
- package/templates/.codex/skills/qa-lead-routing/SKILL.md +0 -290
- package/templates/.codex/skills/react-best-practices/SKILL.md +0 -101
- package/templates/.codex/skills/redis-best-practices/SKILL.md +0 -83
- package/templates/.codex/skills/result-aggregation/SKILL.md +0 -164
- package/templates/.codex/skills/rust-best-practices/SKILL.md +0 -267
- package/templates/.codex/skills/sauron-watch/SKILL.md +0 -144
- package/templates/.codex/skills/secretary-routing/SKILL.md +0 -203
- package/templates/.codex/skills/snowflake-best-practices/SKILL.md +0 -65
- package/templates/.codex/skills/spark-best-practices/SKILL.md +0 -52
- package/templates/.codex/skills/springboot-best-practices/SKILL.md +0 -218
- package/templates/.codex/skills/status/SKILL.md +0 -153
- package/templates/.codex/skills/supabase-postgres-best-practices/SKILL.md +0 -99
- package/templates/.codex/skills/typescript-best-practices/SKILL.md +0 -321
- package/templates/.codex/skills/update-docs/SKILL.md +0 -140
- package/templates/.codex/skills/update-external/SKILL.md +0 -149
- package/templates/.codex/skills/vercel-deploy/SKILL.md +0 -73
- package/templates/.codex/skills/web-design-guidelines/SKILL.md +0 -118
- package/templates/.codex/skills/writing-clearly-and-concisely/SKILL.md +0 -64
- package/templates/.codex/uninstall-hooks.sh +0 -52
- package/templates/AGENTS.md.en +0 -39
- package/templates/AGENTS.md.ko +0 -39
- package/templates/manifest.codex.json +0 -43
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: fastapi-best-practices
|
|
3
|
-
description: FastAPI patterns for high-performance async APIs
|
|
4
|
-
user-invocable: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Purpose
|
|
8
|
-
|
|
9
|
-
Apply FastAPI patterns for building high-performance async APIs.
|
|
10
|
-
|
|
11
|
-
## Rules
|
|
12
|
-
|
|
13
|
-
### 1. Project Structure
|
|
14
|
-
|
|
15
|
-
```yaml
|
|
16
|
-
structure:
|
|
17
|
-
domain_based: true
|
|
18
|
-
module_contents:
|
|
19
|
-
- router.py: API endpoints
|
|
20
|
-
- schemas.py: Pydantic models
|
|
21
|
-
- models.py: Database models
|
|
22
|
-
- service.py: Business logic
|
|
23
|
-
- dependencies.py: Route validators
|
|
24
|
-
- constants.py: Module constants
|
|
25
|
-
- config.py: Module configuration
|
|
26
|
-
- exceptions.py: Custom exceptions
|
|
27
|
-
- utils.py: Helper functions
|
|
28
|
-
|
|
29
|
-
imports:
|
|
30
|
-
style: explicit
|
|
31
|
-
example: "from src.auth import constants as auth_constants"
|
|
32
|
-
|
|
33
|
-
layout: |
|
|
34
|
-
src/
|
|
35
|
-
├── auth/
|
|
36
|
-
│ ├── router.py
|
|
37
|
-
│ ├── schemas.py
|
|
38
|
-
│ ├── models.py
|
|
39
|
-
│ ├── service.py
|
|
40
|
-
│ └── dependencies.py
|
|
41
|
-
├── users/
|
|
42
|
-
│ └── ...
|
|
43
|
-
├── config.py
|
|
44
|
-
└── main.py
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### 2. Async Patterns
|
|
48
|
-
|
|
49
|
-
```yaml
|
|
50
|
-
io_intensive:
|
|
51
|
-
use: "async def"
|
|
52
|
-
await: "asyncio.sleep(), httpx, asyncpg, etc."
|
|
53
|
-
example: |
|
|
54
|
-
async def fetch_data():
|
|
55
|
-
async with httpx.AsyncClient() as client:
|
|
56
|
-
response = await client.get(url)
|
|
57
|
-
return response.json()
|
|
58
|
-
|
|
59
|
-
sync_io:
|
|
60
|
-
use: "def (regular function)"
|
|
61
|
-
reason: FastAPI offloads to threadpool automatically
|
|
62
|
-
example: |
|
|
63
|
-
def read_file():
|
|
64
|
-
with open('file.txt') as f:
|
|
65
|
-
return f.read()
|
|
66
|
-
|
|
67
|
-
cpu_intensive:
|
|
68
|
-
avoid: async and threadpool
|
|
69
|
-
use: separate worker processes
|
|
70
|
-
example: "Use Celery or multiprocessing"
|
|
71
|
-
|
|
72
|
-
never:
|
|
73
|
-
- "time.sleep() in async functions"
|
|
74
|
-
- "Blocking I/O in async functions"
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### 3. Pydantic Models
|
|
78
|
-
|
|
79
|
-
```yaml
|
|
80
|
-
validation:
|
|
81
|
-
use_builtin: regex, enums, email, URL validators
|
|
82
|
-
custom_validators: for complex logic
|
|
83
|
-
|
|
84
|
-
base_model:
|
|
85
|
-
create_custom: true
|
|
86
|
-
purpose: enforce application-wide standards
|
|
87
|
-
example: |
|
|
88
|
-
from pydantic import BaseModel
|
|
89
|
-
from datetime import datetime
|
|
90
|
-
|
|
91
|
-
class AppBaseModel(BaseModel):
|
|
92
|
-
class Config:
|
|
93
|
-
from_attributes = True
|
|
94
|
-
json_encoders = {
|
|
95
|
-
datetime: lambda v: v.isoformat()
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
settings:
|
|
99
|
-
split: across modules
|
|
100
|
-
avoid: single global configuration
|
|
101
|
-
example: |
|
|
102
|
-
# auth/config.py
|
|
103
|
-
class AuthSettings(BaseSettings):
|
|
104
|
-
jwt_secret: str
|
|
105
|
-
jwt_algorithm: str = "HS256"
|
|
106
|
-
|
|
107
|
-
# database/config.py
|
|
108
|
-
class DatabaseSettings(BaseSettings):
|
|
109
|
-
url: str
|
|
110
|
-
pool_size: int = 5
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### 4. Dependencies
|
|
114
|
-
|
|
115
|
-
```yaml
|
|
116
|
-
usage:
|
|
117
|
-
- Dependency injection
|
|
118
|
-
- Validation against database
|
|
119
|
-
- Authentication/authorization
|
|
120
|
-
- Request scoped caching
|
|
121
|
-
|
|
122
|
-
patterns:
|
|
123
|
-
chain: avoid code repetition
|
|
124
|
-
cache: FastAPI caches within request scope
|
|
125
|
-
decouple: small, reusable functions
|
|
126
|
-
|
|
127
|
-
example: |
|
|
128
|
-
async def get_current_user(
|
|
129
|
-
token: str = Depends(oauth2_scheme),
|
|
130
|
-
db: Session = Depends(get_db)
|
|
131
|
-
) -> User:
|
|
132
|
-
user = await db.get_user_by_token(token)
|
|
133
|
-
if not user:
|
|
134
|
-
raise HTTPException(status_code=401)
|
|
135
|
-
return user
|
|
136
|
-
|
|
137
|
-
async def get_active_user(
|
|
138
|
-
user: User = Depends(get_current_user)
|
|
139
|
-
) -> User:
|
|
140
|
-
if not user.is_active:
|
|
141
|
-
raise HTTPException(status_code=403)
|
|
142
|
-
return user
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### 5. Error Handling
|
|
146
|
-
|
|
147
|
-
```yaml
|
|
148
|
-
custom_exceptions:
|
|
149
|
-
scope: module-specific
|
|
150
|
-
purpose: clarity and consistency
|
|
151
|
-
|
|
152
|
-
pattern: |
|
|
153
|
-
# auth/exceptions.py
|
|
154
|
-
class AuthException(Exception):
|
|
155
|
-
pass
|
|
156
|
-
|
|
157
|
-
class InvalidCredentials(AuthException):
|
|
158
|
-
pass
|
|
159
|
-
|
|
160
|
-
class TokenExpired(AuthException):
|
|
161
|
-
pass
|
|
162
|
-
|
|
163
|
-
# auth/router.py
|
|
164
|
-
@router.post("/login")
|
|
165
|
-
async def login(credentials: LoginSchema):
|
|
166
|
-
try:
|
|
167
|
-
return await auth_service.login(credentials)
|
|
168
|
-
except InvalidCredentials:
|
|
169
|
-
raise HTTPException(
|
|
170
|
-
status_code=401,
|
|
171
|
-
detail="Invalid credentials"
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
exception_handlers: |
|
|
175
|
-
@app.exception_handler(AuthException)
|
|
176
|
-
async def auth_exception_handler(request, exc):
|
|
177
|
-
return JSONResponse(
|
|
178
|
-
status_code=401,
|
|
179
|
-
content={"detail": str(exc)}
|
|
180
|
-
)
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### 6. Database
|
|
184
|
-
|
|
185
|
-
```yaml
|
|
186
|
-
naming:
|
|
187
|
-
establish: upfront conventions
|
|
188
|
-
consistency: across all models
|
|
189
|
-
|
|
190
|
-
migrations:
|
|
191
|
-
tool: Alembic
|
|
192
|
-
naming: explicit naming rules
|
|
193
|
-
|
|
194
|
-
design:
|
|
195
|
-
approach: SQL-first
|
|
196
|
-
then: add Pydantic models
|
|
197
|
-
|
|
198
|
-
patterns: |
|
|
199
|
-
# Use async database drivers
|
|
200
|
-
from sqlalchemy.ext.asyncio import AsyncSession
|
|
201
|
-
|
|
202
|
-
async def get_user(db: AsyncSession, user_id: int):
|
|
203
|
-
result = await db.execute(
|
|
204
|
-
select(User).where(User.id == user_id)
|
|
205
|
-
)
|
|
206
|
-
return result.scalar_one_or_none()
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### 7. API Design
|
|
210
|
-
|
|
211
|
-
```yaml
|
|
212
|
-
routing:
|
|
213
|
-
prefix: meaningful module prefix
|
|
214
|
-
tags: for documentation grouping
|
|
215
|
-
|
|
216
|
-
responses:
|
|
217
|
-
schema: always define response models
|
|
218
|
-
status_codes: document all possible codes
|
|
219
|
-
|
|
220
|
-
example: |
|
|
221
|
-
router = APIRouter(
|
|
222
|
-
prefix="/users",
|
|
223
|
-
tags=["users"]
|
|
224
|
-
)
|
|
225
|
-
|
|
226
|
-
@router.get(
|
|
227
|
-
"/{user_id}",
|
|
228
|
-
response_model=UserResponse,
|
|
229
|
-
responses={
|
|
230
|
-
404: {"model": ErrorResponse}
|
|
231
|
-
}
|
|
232
|
-
)
|
|
233
|
-
async def get_user(user_id: int):
|
|
234
|
-
...
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### 8. Testing
|
|
238
|
-
|
|
239
|
-
```yaml
|
|
240
|
-
setup:
|
|
241
|
-
async_client: from day one
|
|
242
|
-
structure: mirror module layout
|
|
243
|
-
|
|
244
|
-
patterns: |
|
|
245
|
-
import pytest
|
|
246
|
-
from httpx import AsyncClient
|
|
247
|
-
|
|
248
|
-
@pytest.fixture
|
|
249
|
-
async def client():
|
|
250
|
-
async with AsyncClient(app=app, base_url="http://test") as ac:
|
|
251
|
-
yield ac
|
|
252
|
-
|
|
253
|
-
@pytest.mark.asyncio
|
|
254
|
-
async def test_get_user(client):
|
|
255
|
-
response = await client.get("/users/1")
|
|
256
|
-
assert response.status_code == 200
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
## Application
|
|
260
|
-
|
|
261
|
-
When writing FastAPI code:
|
|
262
|
-
|
|
263
|
-
1. **Always** use domain-based project structure
|
|
264
|
-
2. **Always** use `async def` for I/O operations
|
|
265
|
-
3. **Prefer** Pydantic for all validation
|
|
266
|
-
4. **Use** dependencies for reusable logic
|
|
267
|
-
5. **Define** module-specific exceptions
|
|
268
|
-
6. **Document** API with response models
|
|
269
|
-
7. **Test** with async client
|
|
270
|
-
8. **Use** Ruff for code quality
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: fix-refs
|
|
3
|
-
description: Fix broken agent references and symlinks
|
|
4
|
-
argument-hint: "[agent-name] [--all] [--dry-run]"
|
|
5
|
-
disable-model-invocation: true
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Fix References Skill
|
|
9
|
-
|
|
10
|
-
Fix broken references, missing symlinks, and other agent dependency issues.
|
|
11
|
-
|
|
12
|
-
## Options
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
--all, -a Fix all agents
|
|
16
|
-
--dry-run Show what would be fixed
|
|
17
|
-
--verbose, -v Show detailed actions
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Workflow
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
1. Run mgr-supplier:audit to identify issues
|
|
24
|
-
|
|
25
|
-
2. Fix issues:
|
|
26
|
-
├── Missing skill references → Add
|
|
27
|
-
├── Missing guide references → Add
|
|
28
|
-
├── Broken paths → Update
|
|
29
|
-
└── Invalid references → Remove
|
|
30
|
-
|
|
31
|
-
3. Validate fixes
|
|
32
|
-
└── Re-run mgr-supplier:audit
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Fixable Issues
|
|
36
|
-
|
|
37
|
-
| Issue | Action |
|
|
38
|
-
|-------|--------|
|
|
39
|
-
| Missing skill ref | Add to agent .md file |
|
|
40
|
-
| Missing guide ref | Add to agent .md file |
|
|
41
|
-
| Broken path | Update path in agent .md file |
|
|
42
|
-
| Invalid reference | Remove from agent .md file |
|
|
43
|
-
|
|
44
|
-
## Output Format
|
|
45
|
-
|
|
46
|
-
### Dry Run
|
|
47
|
-
```
|
|
48
|
-
[mgr-supplier:fix lang-kotlin-expert --dry-run]
|
|
49
|
-
|
|
50
|
-
Analyzing: lang-kotlin-expert
|
|
51
|
-
|
|
52
|
-
Issues found:
|
|
53
|
-
1. Missing guide reference: kotlin
|
|
54
|
-
|
|
55
|
-
Proposed fixes:
|
|
56
|
-
1. Add guide reference to .codex/agents/lang-kotlin-expert.md
|
|
57
|
-
|
|
58
|
-
No changes made (dry-run mode).
|
|
59
|
-
Run without --dry-run to apply fixes.
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Fix Mode
|
|
63
|
-
```
|
|
64
|
-
[mgr-supplier:fix lang-kotlin-expert]
|
|
65
|
-
|
|
66
|
-
Fixing: lang-kotlin-expert
|
|
67
|
-
|
|
68
|
-
[1/2] Adding missing reference...
|
|
69
|
-
Updating: .codex/agents/lang-kotlin-expert.md
|
|
70
|
-
✓ Guide reference added
|
|
71
|
-
|
|
72
|
-
[2/2] Validating...
|
|
73
|
-
Running mgr-supplier:audit...
|
|
74
|
-
✓ All dependencies valid
|
|
75
|
-
|
|
76
|
-
Summary:
|
|
77
|
-
Fixed: 1 issue
|
|
78
|
-
Status: HEALTHY
|
|
79
|
-
|
|
80
|
-
Agent lang-kotlin-expert is now healthy.
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Fix All
|
|
84
|
-
```
|
|
85
|
-
[mgr-supplier:fix --all]
|
|
86
|
-
|
|
87
|
-
Scanning all agents for issues...
|
|
88
|
-
|
|
89
|
-
Found issues in 2 agents:
|
|
90
|
-
- lang-kotlin-expert: 1 issue
|
|
91
|
-
- new-agent: 2 issues
|
|
92
|
-
|
|
93
|
-
Fixing lang-kotlin-expert...
|
|
94
|
-
✓ Added guide reference: kotlin
|
|
95
|
-
|
|
96
|
-
Fixing new-agent...
|
|
97
|
-
✓ Added skill reference: skill-a
|
|
98
|
-
✓ Added skill reference: skill-b
|
|
99
|
-
|
|
100
|
-
Validating all agents...
|
|
101
|
-
✓ mgr-supplier:audit --all passed
|
|
102
|
-
|
|
103
|
-
Summary:
|
|
104
|
-
Agents fixed: 2
|
|
105
|
-
Issues resolved: 3
|
|
106
|
-
All agents healthy.
|
|
107
|
-
```
|
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: go-backend-best-practices
|
|
3
|
-
description: Go backend patterns from Uber style and standard layout
|
|
4
|
-
user-invocable: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Purpose
|
|
8
|
-
|
|
9
|
-
Apply Go backend patterns for building production-ready services.
|
|
10
|
-
|
|
11
|
-
## Rules
|
|
12
|
-
|
|
13
|
-
### 1. Project Structure (Standard Layout)
|
|
14
|
-
|
|
15
|
-
```yaml
|
|
16
|
-
layout: |
|
|
17
|
-
project/
|
|
18
|
-
├── cmd/
|
|
19
|
-
│ └── server/
|
|
20
|
-
│ └── main.go
|
|
21
|
-
├── internal/
|
|
22
|
-
│ ├── handler/
|
|
23
|
-
│ ├── service/
|
|
24
|
-
│ ├── repository/
|
|
25
|
-
│ └── model/
|
|
26
|
-
├── pkg/
|
|
27
|
-
│ └── shared/
|
|
28
|
-
├── api/
|
|
29
|
-
│ └── openapi.yaml
|
|
30
|
-
├── configs/
|
|
31
|
-
├── scripts/
|
|
32
|
-
├── Dockerfile
|
|
33
|
-
├── Makefile
|
|
34
|
-
└── go.mod
|
|
35
|
-
|
|
36
|
-
directories:
|
|
37
|
-
cmd: Main applications (one per binary)
|
|
38
|
-
internal: Private application code
|
|
39
|
-
pkg: Library code safe for external use
|
|
40
|
-
api: API definitions (OpenAPI, protobuf)
|
|
41
|
-
configs: Configuration files
|
|
42
|
-
scripts: Build and CI scripts
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### 2. Error Handling (Uber Style)
|
|
46
|
-
|
|
47
|
-
```yaml
|
|
48
|
-
principles:
|
|
49
|
-
- Wrap errors with context using %w
|
|
50
|
-
- Handle errors once (don't log AND return)
|
|
51
|
-
- Use sentinel errors for specific conditions
|
|
52
|
-
- Name error variables with Err prefix
|
|
53
|
-
|
|
54
|
-
patterns: |
|
|
55
|
-
// Sentinel errors
|
|
56
|
-
var (
|
|
57
|
-
ErrNotFound = errors.New("not found")
|
|
58
|
-
ErrInvalidInput = errors.New("invalid input")
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
// Wrap with context
|
|
62
|
-
func getUser(id string) (*User, error) {
|
|
63
|
-
user, err := db.FindUser(id)
|
|
64
|
-
if err != nil {
|
|
65
|
-
return nil, fmt.Errorf("getUser %s: %w", id, err)
|
|
66
|
-
}
|
|
67
|
-
return user, nil
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Check specific errors
|
|
71
|
-
if errors.Is(err, ErrNotFound) {
|
|
72
|
-
return http.StatusNotFound
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### 3. Concurrency (Uber Style)
|
|
77
|
-
|
|
78
|
-
```yaml
|
|
79
|
-
channels:
|
|
80
|
-
size: "Use 0 (unbuffered) or 1 only"
|
|
81
|
-
larger: "Requires careful review"
|
|
82
|
-
|
|
83
|
-
goroutines:
|
|
84
|
-
never: fire-and-forget
|
|
85
|
-
always: wait for completion or manage lifecycle
|
|
86
|
-
|
|
87
|
-
patterns: |
|
|
88
|
-
// Wait group for goroutines
|
|
89
|
-
func process(items []Item) error {
|
|
90
|
-
var wg sync.WaitGroup
|
|
91
|
-
errCh := make(chan error, 1)
|
|
92
|
-
|
|
93
|
-
for _, item := range items {
|
|
94
|
-
wg.Add(1)
|
|
95
|
-
go func(item Item) {
|
|
96
|
-
defer wg.Done()
|
|
97
|
-
if err := processItem(item); err != nil {
|
|
98
|
-
select {
|
|
99
|
-
case errCh <- err:
|
|
100
|
-
default:
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}(item)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
wg.Wait()
|
|
107
|
-
close(errCh)
|
|
108
|
-
return <-errCh
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Context for cancellation
|
|
112
|
-
func longRunningTask(ctx context.Context) error {
|
|
113
|
-
for {
|
|
114
|
-
select {
|
|
115
|
-
case <-ctx.Done():
|
|
116
|
-
return ctx.Err()
|
|
117
|
-
default:
|
|
118
|
-
// do work
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### 4. HTTP Server
|
|
125
|
-
|
|
126
|
-
```yaml
|
|
127
|
-
structure:
|
|
128
|
-
handler: HTTP layer (request/response)
|
|
129
|
-
service: Business logic
|
|
130
|
-
repository: Data access
|
|
131
|
-
|
|
132
|
-
patterns: |
|
|
133
|
-
// Handler with dependency injection
|
|
134
|
-
type UserHandler struct {
|
|
135
|
-
service UserService
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
func NewUserHandler(s UserService) *UserHandler {
|
|
139
|
-
return &UserHandler{service: s}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {
|
|
143
|
-
id := chi.URLParam(r, "id")
|
|
144
|
-
|
|
145
|
-
user, err := h.service.GetUser(r.Context(), id)
|
|
146
|
-
if err != nil {
|
|
147
|
-
if errors.Is(err, ErrNotFound) {
|
|
148
|
-
http.Error(w, "user not found", http.StatusNotFound)
|
|
149
|
-
return
|
|
150
|
-
}
|
|
151
|
-
http.Error(w, "internal error", http.StatusInternalServerError)
|
|
152
|
-
return
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
json.NewEncoder(w).Encode(user)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Router setup
|
|
159
|
-
func NewRouter(h *UserHandler) *chi.Mux {
|
|
160
|
-
r := chi.NewRouter()
|
|
161
|
-
r.Use(middleware.Logger)
|
|
162
|
-
r.Use(middleware.Recoverer)
|
|
163
|
-
|
|
164
|
-
r.Route("/api/v1", func(r chi.Router) {
|
|
165
|
-
r.Get("/users/{id}", h.GetUser)
|
|
166
|
-
r.Post("/users", h.CreateUser)
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
return r
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### 5. Dependency Injection
|
|
174
|
-
|
|
175
|
-
```yaml
|
|
176
|
-
approach: constructor injection
|
|
177
|
-
avoid: global variables
|
|
178
|
-
|
|
179
|
-
patterns: |
|
|
180
|
-
// Service with dependencies
|
|
181
|
-
type UserService struct {
|
|
182
|
-
repo UserRepository
|
|
183
|
-
cache Cache
|
|
184
|
-
logger *slog.Logger
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
func NewUserService(
|
|
188
|
-
repo UserRepository,
|
|
189
|
-
cache Cache,
|
|
190
|
-
logger *slog.Logger,
|
|
191
|
-
) *UserService {
|
|
192
|
-
return &UserService{
|
|
193
|
-
repo: repo,
|
|
194
|
-
cache: cache,
|
|
195
|
-
logger: logger,
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Wire up in main
|
|
200
|
-
func main() {
|
|
201
|
-
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
|
202
|
-
db := database.New(cfg.DatabaseURL)
|
|
203
|
-
cache := redis.New(cfg.RedisURL)
|
|
204
|
-
|
|
205
|
-
repo := repository.NewUserRepository(db)
|
|
206
|
-
service := service.NewUserService(repo, cache, logger)
|
|
207
|
-
handler := handler.NewUserHandler(service)
|
|
208
|
-
|
|
209
|
-
router := handler.NewRouter(handler)
|
|
210
|
-
http.ListenAndServe(":8080", router)
|
|
211
|
-
}
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
### 6. Configuration
|
|
215
|
-
|
|
216
|
-
```yaml
|
|
217
|
-
approach:
|
|
218
|
-
- Use environment variables
|
|
219
|
-
- Validate at startup
|
|
220
|
-
- Group related settings
|
|
221
|
-
|
|
222
|
-
patterns: |
|
|
223
|
-
type Config struct {
|
|
224
|
-
Server ServerConfig
|
|
225
|
-
Database DatabaseConfig
|
|
226
|
-
Redis RedisConfig
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
type ServerConfig struct {
|
|
230
|
-
Host string `env:"SERVER_HOST" envDefault:"0.0.0.0"`
|
|
231
|
-
Port int `env:"SERVER_PORT" envDefault:"8080"`
|
|
232
|
-
ReadTimeout time.Duration `env:"SERVER_READ_TIMEOUT" envDefault:"5s"`
|
|
233
|
-
WriteTimeout time.Duration `env:"SERVER_WRITE_TIMEOUT" envDefault:"10s"`
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
func LoadConfig() (*Config, error) {
|
|
237
|
-
var cfg Config
|
|
238
|
-
if err := env.Parse(&cfg); err != nil {
|
|
239
|
-
return nil, fmt.Errorf("parse config: %w", err)
|
|
240
|
-
}
|
|
241
|
-
return &cfg, nil
|
|
242
|
-
}
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### 7. Testing
|
|
246
|
-
|
|
247
|
-
```yaml
|
|
248
|
-
patterns:
|
|
249
|
-
table_driven: for comprehensive coverage
|
|
250
|
-
interfaces: for mocking
|
|
251
|
-
parallel: for speed
|
|
252
|
-
|
|
253
|
-
example: |
|
|
254
|
-
func TestUserService_GetUser(t *testing.T) {
|
|
255
|
-
tests := []struct {
|
|
256
|
-
name string
|
|
257
|
-
userID string
|
|
258
|
-
mock func(*MockRepository)
|
|
259
|
-
want *User
|
|
260
|
-
wantErr error
|
|
261
|
-
}{
|
|
262
|
-
{
|
|
263
|
-
name: "success",
|
|
264
|
-
userID: "123",
|
|
265
|
-
mock: func(m *MockRepository) {
|
|
266
|
-
m.EXPECT().FindByID("123").Return(&User{ID: "123"}, nil)
|
|
267
|
-
},
|
|
268
|
-
want: &User{ID: "123"},
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
name: "not found",
|
|
272
|
-
userID: "999",
|
|
273
|
-
mock: func(m *MockRepository) {
|
|
274
|
-
m.EXPECT().FindByID("999").Return(nil, ErrNotFound)
|
|
275
|
-
},
|
|
276
|
-
wantErr: ErrNotFound,
|
|
277
|
-
},
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
for _, tt := range tests {
|
|
281
|
-
t.Run(tt.name, func(t *testing.T) {
|
|
282
|
-
t.Parallel()
|
|
283
|
-
ctrl := gomock.NewController(t)
|
|
284
|
-
repo := NewMockRepository(ctrl)
|
|
285
|
-
tt.mock(repo)
|
|
286
|
-
|
|
287
|
-
svc := NewUserService(repo, nil, slog.Default())
|
|
288
|
-
got, err := svc.GetUser(context.Background(), tt.userID)
|
|
289
|
-
|
|
290
|
-
if !errors.Is(err, tt.wantErr) {
|
|
291
|
-
t.Errorf("got error %v, want %v", err, tt.wantErr)
|
|
292
|
-
}
|
|
293
|
-
if diff := cmp.Diff(tt.want, got); diff != "" {
|
|
294
|
-
t.Errorf("mismatch (-want +got):\n%s", diff)
|
|
295
|
-
}
|
|
296
|
-
})
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### 8. Performance (Uber Style)
|
|
302
|
-
|
|
303
|
-
```yaml
|
|
304
|
-
guidelines:
|
|
305
|
-
- Use strconv over fmt for conversions
|
|
306
|
-
- Pre-allocate slices with known capacity
|
|
307
|
-
- Avoid repeated string-to-byte conversions
|
|
308
|
-
- Copy slices/maps at boundaries
|
|
309
|
-
|
|
310
|
-
patterns: |
|
|
311
|
-
// Pre-allocate
|
|
312
|
-
items := make([]Item, 0, len(input))
|
|
313
|
-
|
|
314
|
-
// strconv for conversions
|
|
315
|
-
s := strconv.Itoa(n) // not fmt.Sprintf("%d", n)
|
|
316
|
-
|
|
317
|
-
// Copy at boundaries
|
|
318
|
-
func (s *Store) GetItems() []Item {
|
|
319
|
-
s.mu.RLock()
|
|
320
|
-
defer s.mu.RUnlock()
|
|
321
|
-
items := make([]Item, len(s.items))
|
|
322
|
-
copy(items, s.items)
|
|
323
|
-
return items
|
|
324
|
-
}
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
## Application
|
|
328
|
-
|
|
329
|
-
When writing Go backend code:
|
|
330
|
-
|
|
331
|
-
1. **Always** use standard project layout
|
|
332
|
-
2. **Always** wrap errors with context
|
|
333
|
-
3. **Never** fire-and-forget goroutines
|
|
334
|
-
4. **Use** constructor injection
|
|
335
|
-
5. **Use** table-driven tests
|
|
336
|
-
6. **Handle** errors once
|
|
337
|
-
7. **Copy** data at boundaries
|
|
338
|
-
8. **Validate** config at startup
|