devflow-kit 1.1.0 → 1.2.0

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 (107) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +23 -6
  3. package/dist/plugins.js +67 -3
  4. package/package.json +2 -1
  5. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +15 -0
  6. package/plugins/devflow-ambient/.claude-plugin/plugin.json +1 -1
  7. package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +1 -1
  8. package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +4 -0
  9. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
  10. package/plugins/devflow-code-review/.claude-plugin/plugin.json +1 -4
  11. package/plugins/devflow-code-review/agents/reviewer.md +8 -0
  12. package/plugins/devflow-code-review/commands/code-review-teams.md +11 -1
  13. package/plugins/devflow-code-review/commands/code-review.md +12 -2
  14. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +2 -6
  15. package/plugins/devflow-debug/.claude-plugin/plugin.json +1 -1
  16. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +15 -0
  17. package/plugins/devflow-go/.claude-plugin/plugin.json +15 -0
  18. package/plugins/devflow-go/skills/go/SKILL.md +187 -0
  19. package/plugins/devflow-go/skills/go/references/concurrency.md +312 -0
  20. package/plugins/devflow-go/skills/go/references/detection.md +129 -0
  21. package/plugins/devflow-go/skills/go/references/patterns.md +232 -0
  22. package/plugins/devflow-go/skills/go/references/violations.md +205 -0
  23. package/plugins/devflow-implement/.claude-plugin/plugin.json +1 -3
  24. package/plugins/devflow-implement/agents/coder.md +11 -6
  25. package/plugins/devflow-java/.claude-plugin/plugin.json +15 -0
  26. package/plugins/devflow-java/skills/java/SKILL.md +183 -0
  27. package/plugins/devflow-java/skills/java/references/detection.md +120 -0
  28. package/plugins/devflow-java/skills/java/references/modern-java.md +270 -0
  29. package/plugins/devflow-java/skills/java/references/patterns.md +235 -0
  30. package/plugins/devflow-java/skills/java/references/violations.md +213 -0
  31. package/plugins/devflow-python/.claude-plugin/plugin.json +15 -0
  32. package/plugins/devflow-python/skills/python/SKILL.md +188 -0
  33. package/plugins/devflow-python/skills/python/references/async.md +220 -0
  34. package/plugins/devflow-python/skills/python/references/detection.md +128 -0
  35. package/plugins/devflow-python/skills/python/references/patterns.md +226 -0
  36. package/plugins/devflow-python/skills/python/references/violations.md +204 -0
  37. package/plugins/devflow-react/.claude-plugin/plugin.json +15 -0
  38. package/plugins/{devflow-core-skills → devflow-react}/skills/react/SKILL.md +1 -1
  39. package/plugins/{devflow-core-skills → devflow-react}/skills/react/references/patterns.md +3 -3
  40. package/plugins/devflow-resolve/.claude-plugin/plugin.json +1 -1
  41. package/plugins/devflow-rust/.claude-plugin/plugin.json +15 -0
  42. package/plugins/devflow-rust/skills/rust/SKILL.md +193 -0
  43. package/plugins/devflow-rust/skills/rust/references/detection.md +131 -0
  44. package/plugins/devflow-rust/skills/rust/references/ownership.md +242 -0
  45. package/plugins/devflow-rust/skills/rust/references/patterns.md +210 -0
  46. package/plugins/devflow-rust/skills/rust/references/violations.md +191 -0
  47. package/plugins/devflow-self-review/.claude-plugin/plugin.json +1 -1
  48. package/plugins/devflow-specify/.claude-plugin/plugin.json +1 -1
  49. package/plugins/devflow-typescript/.claude-plugin/plugin.json +15 -0
  50. package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/patterns.md +3 -3
  51. package/shared/agents/coder.md +11 -6
  52. package/shared/agents/reviewer.md +8 -0
  53. package/shared/skills/ambient-router/SKILL.md +1 -1
  54. package/shared/skills/ambient-router/references/skill-catalog.md +4 -0
  55. package/shared/skills/go/SKILL.md +187 -0
  56. package/shared/skills/go/references/concurrency.md +312 -0
  57. package/shared/skills/go/references/detection.md +129 -0
  58. package/shared/skills/go/references/patterns.md +232 -0
  59. package/shared/skills/go/references/violations.md +205 -0
  60. package/shared/skills/java/SKILL.md +183 -0
  61. package/shared/skills/java/references/detection.md +120 -0
  62. package/shared/skills/java/references/modern-java.md +270 -0
  63. package/shared/skills/java/references/patterns.md +235 -0
  64. package/shared/skills/java/references/violations.md +213 -0
  65. package/shared/skills/python/SKILL.md +188 -0
  66. package/shared/skills/python/references/async.md +220 -0
  67. package/shared/skills/python/references/detection.md +128 -0
  68. package/shared/skills/python/references/patterns.md +226 -0
  69. package/shared/skills/python/references/violations.md +204 -0
  70. package/shared/skills/react/SKILL.md +1 -1
  71. package/shared/skills/react/references/patterns.md +3 -3
  72. package/shared/skills/rust/SKILL.md +193 -0
  73. package/shared/skills/rust/references/detection.md +131 -0
  74. package/shared/skills/rust/references/ownership.md +242 -0
  75. package/shared/skills/rust/references/patterns.md +210 -0
  76. package/shared/skills/rust/references/violations.md +191 -0
  77. package/shared/skills/typescript/references/patterns.md +3 -3
  78. package/plugins/devflow-code-review/skills/react/SKILL.md +0 -276
  79. package/plugins/devflow-code-review/skills/react/references/patterns.md +0 -1331
  80. package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +0 -229
  81. package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +0 -171
  82. package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +0 -670
  83. package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +0 -419
  84. package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +0 -254
  85. package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +0 -184
  86. package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +0 -511
  87. package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +0 -453
  88. package/plugins/devflow-core-skills/skills/react/references/violations.md +0 -565
  89. package/plugins/devflow-implement/skills/accessibility/SKILL.md +0 -229
  90. package/plugins/devflow-implement/skills/accessibility/references/detection.md +0 -171
  91. package/plugins/devflow-implement/skills/accessibility/references/patterns.md +0 -670
  92. package/plugins/devflow-implement/skills/accessibility/references/violations.md +0 -419
  93. package/plugins/devflow-implement/skills/frontend-design/SKILL.md +0 -254
  94. package/plugins/devflow-implement/skills/frontend-design/references/detection.md +0 -184
  95. package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +0 -511
  96. package/plugins/devflow-implement/skills/frontend-design/references/violations.md +0 -453
  97. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/SKILL.md +0 -0
  98. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/detection.md +0 -0
  99. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/patterns.md +0 -0
  100. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/violations.md +0 -0
  101. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/SKILL.md +0 -0
  102. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/detection.md +0 -0
  103. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/patterns.md +0 -0
  104. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/violations.md +0 -0
  105. /package/plugins/{devflow-code-review → devflow-react}/skills/react/references/violations.md +0 -0
  106. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/SKILL.md +0 -0
  107. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/violations.md +0 -0
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "devflow-python",
3
+ "description": "Python language patterns - type hints, protocols, dataclasses, async programming",
4
+ "author": {
5
+ "name": "DevFlow Contributors",
6
+ "email": "dean@keren.dev"
7
+ },
8
+ "version": "1.2.0",
9
+ "homepage": "https://github.com/dean0x/devflow",
10
+ "repository": "https://github.com/dean0x/devflow",
11
+ "license": "MIT",
12
+ "keywords": ["python", "type-hints", "dataclasses", "async"],
13
+ "agents": [],
14
+ "skills": ["python"]
15
+ }
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: python
3
+ description: This skill should be used when the user works with Python files (.py), asks about "type hints", "protocols", "dataclasses", "async/await", "decorators", or discusses Pythonic patterns and data modeling. Provides patterns for type safety, error handling, data modeling, and async programming.
4
+ user-invocable: false
5
+ allowed-tools: Read, Grep, Glob
6
+ activation:
7
+ file-patterns:
8
+ - "**/*.py"
9
+ exclude:
10
+ - "venv/**"
11
+ - ".venv/**"
12
+ - "**/__pycache__/**"
13
+ ---
14
+
15
+ # Python Patterns
16
+
17
+ Reference for Python-specific patterns, type safety, and idioms.
18
+
19
+ ## Iron Law
20
+
21
+ > **EXPLICIT IS BETTER THAN IMPLICIT**
22
+ >
23
+ > Type-hint every function signature. Name every exception. Use dataclasses over raw dicts.
24
+ > Python's flexibility is a strength only when boundaries are explicit. Implicit behavior
25
+ > causes debugging nightmares and makes codebases hostile to newcomers.
26
+
27
+ ## When This Skill Activates
28
+
29
+ - Working with Python codebases
30
+ - Designing typed APIs with type hints
31
+ - Modeling data with dataclasses or Pydantic
32
+ - Implementing async code
33
+ - Structuring Python packages
34
+
35
+ ---
36
+
37
+ ## Type Safety
38
+
39
+ ### Type Hint Everything
40
+
41
+ ```python
42
+ # BAD: def process(data, config): ...
43
+ # GOOD:
44
+ def process(data: list[dict[str, Any]], config: AppConfig) -> ProcessResult:
45
+ ...
46
+ ```
47
+
48
+ ### Use Protocols for Structural Typing
49
+
50
+ ```python
51
+ from typing import Protocol
52
+
53
+ class Repository(Protocol):
54
+ def find_by_id(self, id: str) -> User | None: ...
55
+ def save(self, entity: User) -> User: ...
56
+
57
+ # Any class with these methods satisfies Repository — no inheritance needed
58
+ ```
59
+
60
+ ### Strict Optional Handling
61
+
62
+ ```python
63
+ # BAD: def get_name(user): return user.name
64
+ # GOOD:
65
+ def get_name(user: User | None) -> str:
66
+ if user is None:
67
+ return "Anonymous"
68
+ return user.name
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Error Handling
74
+
75
+ ### Custom Exception Hierarchies
76
+
77
+ ```python
78
+ class AppError(Exception):
79
+ """Base application error."""
80
+
81
+ class NotFoundError(AppError):
82
+ def __init__(self, entity: str, id: str) -> None:
83
+ super().__init__(f"{entity} {id} not found")
84
+ self.entity = entity
85
+ self.id = id
86
+
87
+ class ValidationError(AppError):
88
+ def __init__(self, field: str, message: str) -> None:
89
+ super().__init__(f"Validation failed for {field}: {message}")
90
+ ```
91
+
92
+ ### Context Managers for Resources
93
+
94
+ ```python
95
+ from contextlib import contextmanager
96
+
97
+ @contextmanager
98
+ def database_transaction(conn: Connection):
99
+ try:
100
+ yield conn
101
+ conn.commit()
102
+ except Exception:
103
+ conn.rollback()
104
+ raise
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Data Modeling
110
+
111
+ ### Dataclasses Over Raw Dicts
112
+
113
+ ```python
114
+ # BAD: user = {"name": "Alice", "email": "alice@example.com"}
115
+ # GOOD:
116
+ @dataclass(frozen=True)
117
+ class User:
118
+ name: str
119
+ email: str
120
+ created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
121
+ ```
122
+
123
+ ### Pydantic for Validation at Boundaries
124
+
125
+ ```python
126
+ from pydantic import BaseModel, EmailStr
127
+
128
+ class CreateUserRequest(BaseModel):
129
+ name: str
130
+ email: EmailStr
131
+ age: int = Field(ge=0, le=150)
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Pythonic Patterns
137
+
138
+ ```python
139
+ # Comprehensions over loops for transforms
140
+ names = [user.name for user in users if user.active]
141
+
142
+ # Enumerate over manual index tracking
143
+ for i, item in enumerate(items):
144
+ process(i, item)
145
+
146
+ # EAFP: Easier to Ask Forgiveness than Permission
147
+ try:
148
+ value = mapping[key]
149
+ except KeyError:
150
+ value = default
151
+ ```
152
+
153
+ ---
154
+
155
+ ## Anti-Patterns
156
+
157
+ | Pattern | Bad | Good |
158
+ |---------|-----|------|
159
+ | Bare except | `except:` | `except (ValueError, KeyError):` |
160
+ | Mutable default | `def fn(items=[])` | `def fn(items: list | None = None)` |
161
+ | No type hints | `def process(data)` | `def process(data: DataFrame) -> Result` |
162
+ | String typing | `x: "MyClass"` (without reason) | `from __future__ import annotations` |
163
+ | God class | `class App` with 50 methods | Compose smaller focused classes |
164
+
165
+ ---
166
+
167
+ ## Extended References
168
+
169
+ For additional patterns and examples:
170
+ - `references/violations.md` - Common Python violations
171
+ - `references/patterns.md` - Extended Python patterns
172
+ - `references/detection.md` - Detection patterns for Python issues
173
+ - `references/async.md` - Async Python patterns
174
+
175
+ ---
176
+
177
+ ## Checklist
178
+
179
+ - [ ] All functions have type hints (params + return)
180
+ - [ ] Custom exceptions with meaningful messages
181
+ - [ ] Dataclasses or Pydantic for structured data
182
+ - [ ] No bare `except:` clauses
183
+ - [ ] No mutable default arguments
184
+ - [ ] Context managers for resource management
185
+ - [ ] `from __future__ import annotations` for forward refs
186
+ - [ ] Protocols for structural typing (not ABC unless needed)
187
+ - [ ] Comprehensions for simple transforms
188
+ - [ ] Tests use pytest with fixtures
@@ -0,0 +1,220 @@
1
+ # Async Python Patterns
2
+
3
+ Deep-dive on async Python programming. Reference from main SKILL.md.
4
+
5
+ ## Core asyncio Patterns
6
+
7
+ ### Basic Async Function
8
+
9
+ ```python
10
+ import asyncio
11
+ from typing import Any
12
+
13
+ async def fetch_user(user_id: str) -> User:
14
+ async with aiohttp.ClientSession() as session:
15
+ async with session.get(f"/api/users/{user_id}") as response:
16
+ data = await response.json()
17
+ return User.model_validate(data)
18
+ ```
19
+
20
+ ### Concurrent Execution with gather
21
+
22
+ ```python
23
+ async def load_dashboard(user_id: str) -> Dashboard:
24
+ # Independent fetches run concurrently
25
+ user, orders, preferences = await asyncio.gather(
26
+ fetch_user(user_id),
27
+ fetch_orders(user_id),
28
+ fetch_preferences(user_id),
29
+ )
30
+ return Dashboard(user=user, orders=orders, preferences=preferences)
31
+ ```
32
+
33
+ ## Structured Concurrency with TaskGroup
34
+
35
+ ### TaskGroup for Safe Concurrency (Python 3.11+)
36
+
37
+ ```python
38
+ async def process_batch(items: list[Item]) -> list[Result]:
39
+ results: list[Result] = []
40
+
41
+ async with asyncio.TaskGroup() as tg:
42
+ for item in items:
43
+ tg.create_task(process_and_collect(item, results))
44
+
45
+ return results
46
+
47
+ async def process_and_collect(item: Item, results: list[Result]) -> None:
48
+ result = await process_item(item)
49
+ results.append(result)
50
+ ```
51
+
52
+ ### Error Handling with TaskGroup
53
+
54
+ ```python
55
+ async def resilient_batch(items: list[Item]) -> tuple[list[Result], list[Error]]:
56
+ results: list[Result] = []
57
+ errors: list[Error] = []
58
+
59
+ # TaskGroup cancels all tasks if one raises — wrap individual tasks
60
+ async def safe_process(item: Item) -> None:
61
+ try:
62
+ result = await process_item(item)
63
+ results.append(result)
64
+ except ProcessingError as e:
65
+ errors.append(Error(item_id=item.id, message=str(e)))
66
+
67
+ async with asyncio.TaskGroup() as tg:
68
+ for item in items:
69
+ tg.create_task(safe_process(item))
70
+
71
+ return results, errors
72
+ ```
73
+
74
+ ## Async Generators
75
+
76
+ ### Streaming Results
77
+
78
+ ```python
79
+ from typing import AsyncGenerator
80
+
81
+ async def stream_results(query: str, params: tuple = ()) -> AsyncGenerator[Record, None]:
82
+ async with get_connection() as conn:
83
+ cursor = await conn.execute(query, params)
84
+ async for row in cursor:
85
+ yield Record.from_row(row)
86
+
87
+ # Usage
88
+ async for record in stream_results("SELECT * FROM events WHERE type = ?", ("click",)):
89
+ await process(record)
90
+ ```
91
+
92
+ ### Async Generator with Cleanup
93
+
94
+ ```python
95
+ async def paginated_fetch(url: str, page_size: int = 100) -> AsyncGenerator[Item, None]:
96
+ page = 0
97
+ while True:
98
+ response = await fetch_page(url, page=page, size=page_size)
99
+ if not response.items:
100
+ break
101
+ for item in response.items:
102
+ yield item
103
+ page += 1
104
+ ```
105
+
106
+ ## Semaphore for Rate Limiting
107
+
108
+ ### Bounded Concurrency
109
+
110
+ ```python
111
+ async def fetch_all(urls: list[str], max_concurrent: int = 10) -> list[Response]:
112
+ semaphore = asyncio.Semaphore(max_concurrent)
113
+
114
+ async def bounded_fetch(url: str) -> Response:
115
+ async with semaphore:
116
+ return await fetch(url)
117
+
118
+ return await asyncio.gather(*[bounded_fetch(url) for url in urls])
119
+ ```
120
+
121
+ ## aiohttp Patterns
122
+
123
+ ### Client Session Management
124
+
125
+ ```python
126
+ from contextlib import asynccontextmanager
127
+ from typing import AsyncGenerator
128
+
129
+ @asynccontextmanager
130
+ async def api_client(base_url: str) -> AsyncGenerator[aiohttp.ClientSession, None]:
131
+ timeout = aiohttp.ClientTimeout(total=30)
132
+ async with aiohttp.ClientSession(base_url, timeout=timeout) as session:
133
+ yield session
134
+
135
+ # Usage — session reused for multiple requests
136
+ async def sync_users(user_ids: list[str]) -> list[User]:
137
+ async with api_client("https://api.example.com") as client:
138
+ tasks = [fetch_user_with_session(client, uid) for uid in user_ids]
139
+ return await asyncio.gather(*tasks)
140
+
141
+ async def fetch_user_with_session(
142
+ client: aiohttp.ClientSession, user_id: str
143
+ ) -> User:
144
+ async with client.get(f"/users/{user_id}") as response:
145
+ response.raise_for_status()
146
+ data = await response.json()
147
+ return User.model_validate(data)
148
+ ```
149
+
150
+ ## Timeout Patterns
151
+
152
+ ### Per-Operation Timeout
153
+
154
+ ```python
155
+ async def fetch_with_timeout(url: str, timeout_seconds: float = 5.0) -> dict[str, Any]:
156
+ try:
157
+ async with asyncio.timeout(timeout_seconds):
158
+ return await fetch(url)
159
+ except TimeoutError:
160
+ raise OperationTimeout(f"Request to {url} timed out after {timeout_seconds}s")
161
+ ```
162
+
163
+ ## Anti-Patterns
164
+
165
+ ### Blocking Calls in Async Code
166
+
167
+ ```python
168
+ # VIOLATION: Blocks the event loop
169
+ async def bad_fetch(url: str) -> str:
170
+ import requests
171
+ return requests.get(url).text # Blocks entire event loop!
172
+
173
+ # CORRECT: Use async library or run in executor
174
+ async def good_fetch(url: str) -> str:
175
+ async with aiohttp.ClientSession() as session:
176
+ async with session.get(url) as response:
177
+ return await response.text()
178
+
179
+ # CORRECT: Offload blocking call to thread pool
180
+ async def run_blocking(func: Callable[..., R], *args: Any) -> R:
181
+ loop = asyncio.get_running_loop()
182
+ return await loop.run_in_executor(None, func, *args)
183
+ ```
184
+
185
+ ### Fire-and-Forget Without Error Handling
186
+
187
+ ```python
188
+ # VIOLATION: Exception silently lost
189
+ async def bad_handler(event: Event) -> None:
190
+ asyncio.create_task(send_notification(event)) # Error vanishes
191
+
192
+ # CORRECT: Track the task and handle errors
193
+ async def good_handler(event: Event) -> None:
194
+ task = asyncio.create_task(send_notification(event))
195
+ task.add_done_callback(handle_task_exception)
196
+
197
+ def handle_task_exception(task: asyncio.Task[Any]) -> None:
198
+ if not task.cancelled() and task.exception() is not None:
199
+ logger.error("Background task failed", exc_info=task.exception())
200
+ ```
201
+
202
+ ### Sequential When Parallel Is Safe
203
+
204
+ ```python
205
+ # VIOLATION: Unnecessarily sequential — 3x slower
206
+ async def slow_load(user_id: str) -> Dashboard:
207
+ user = await fetch_user(user_id)
208
+ orders = await fetch_orders(user_id)
209
+ prefs = await fetch_preferences(user_id)
210
+ return Dashboard(user=user, orders=orders, preferences=prefs)
211
+
212
+ # CORRECT: Concurrent — ~1x latency
213
+ async def fast_load(user_id: str) -> Dashboard:
214
+ user, orders, prefs = await asyncio.gather(
215
+ fetch_user(user_id),
216
+ fetch_orders(user_id),
217
+ fetch_preferences(user_id),
218
+ )
219
+ return Dashboard(user=user, orders=orders, preferences=prefs)
220
+ ```
@@ -0,0 +1,128 @@
1
+ # Python Issue Detection
2
+
3
+ Grep patterns for finding common Python issues. Reference from main SKILL.md.
4
+
5
+ ## Type Safety Detection
6
+
7
+ ### Missing Type Hints
8
+
9
+ ```bash
10
+ # Functions without return type annotation
11
+ grep -rn "def .*):$" --include="*.py" | grep -v "->.*:"
12
+
13
+ # Functions without any annotations
14
+ grep -rn "def .*([a-z_][a-z_0-9]*\s*," --include="*.py" | grep -v ":"
15
+ ```
16
+
17
+ ### Bare Except Clauses
18
+
19
+ ```bash
20
+ # Bare except (catches everything)
21
+ grep -rn "except:" --include="*.py"
22
+
23
+ # Overly broad except Exception
24
+ grep -rn "except Exception:" --include="*.py" | grep -v "# noqa"
25
+ ```
26
+
27
+ ## Data Modeling Detection
28
+
29
+ ### Mutable Default Arguments
30
+
31
+ ```bash
32
+ # List defaults
33
+ grep -rn "def .*=\s*\[\]" --include="*.py"
34
+
35
+ # Dict defaults
36
+ grep -rn "def .*=\s*{}" --include="*.py"
37
+
38
+ # Set defaults
39
+ grep -rn "def .*=\s*set()" --include="*.py"
40
+ ```
41
+
42
+ ### Raw Dict Usage Instead of Dataclasses
43
+
44
+ ```bash
45
+ # Dict literals assigned to typed variables
46
+ grep -rn ': dict\[' --include="*.py" | grep "= {"
47
+
48
+ # Nested dict access patterns (fragile)
49
+ grep -rn '\["[a-z].*\]\["' --include="*.py"
50
+ ```
51
+
52
+ ## Anti-Pattern Detection
53
+
54
+ ### Assert in Production Code
55
+
56
+ ```bash
57
+ # Assert statements outside test files
58
+ grep -rn "^ assert " --include="*.py" | grep -v "test_\|_test\.py\|tests/"
59
+ ```
60
+
61
+ ### Global Mutable State
62
+
63
+ ```bash
64
+ # Global variable assignment
65
+ grep -rn "^[a-z_].*= \[\]\|^[a-z_].*= {}\|^[a-z_].*= set()" --include="*.py"
66
+
67
+ # Global keyword usage
68
+ grep -rn "global " --include="*.py"
69
+ ```
70
+
71
+ ### Old-Style String Formatting
72
+
73
+ ```bash
74
+ # Percent formatting
75
+ grep -rn '"%.*" %' --include="*.py"
76
+ grep -rn "'%.*' %" --include="*.py"
77
+
78
+ # .format() where f-strings would be cleaner
79
+ grep -rn '\.format(' --include="*.py"
80
+ ```
81
+
82
+ ### Wildcard Imports
83
+
84
+ ```bash
85
+ # Star imports
86
+ grep -rn "from .* import \*" --include="*.py"
87
+ ```
88
+
89
+ ## Async Detection
90
+
91
+ ### Missing Await
92
+
93
+ ```bash
94
+ # Coroutine called without await (common mistake)
95
+ grep -rn "async def" --include="*.py" -l | xargs grep -n "[^await ]fetch\|[^await ]save\|[^await ]send"
96
+ ```
97
+
98
+ ### Blocking Calls in Async Code
99
+
100
+ ```bash
101
+ # time.sleep in async context
102
+ grep -rn "time\.sleep" --include="*.py"
103
+
104
+ # requests library in async files (should use aiohttp/httpx)
105
+ grep -rn "import requests\|from requests" --include="*.py"
106
+ ```
107
+
108
+ ## Security Detection
109
+
110
+ ### Unsafe Deserialization
111
+
112
+ ```bash
113
+ # pickle usage (arbitrary code execution risk)
114
+ grep -rn "pickle\.loads\|pickle\.load(" --include="*.py"
115
+
116
+ # yaml.load without SafeLoader
117
+ grep -rn "yaml\.load(" --include="*.py" | grep -v "SafeLoader\|safe_load"
118
+ ```
119
+
120
+ ### Shell Injection
121
+
122
+ ```bash
123
+ # subprocess with shell=True
124
+ grep -rn "shell=True" --include="*.py"
125
+
126
+ # os.system calls
127
+ grep -rn "os\.system(" --include="*.py"
128
+ ```