@martinffx/atelier 1.4.0 → 3.0.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.
- package/CHANGELOG.md +38 -0
- package/README.md +95 -220
- package/agents/architect.md +6 -6
- package/agents/oracle.md +1 -1
- package/agents/{recon.md → sentinel.md} +3 -3
- package/dist/atelier.js +167 -26
- package/package.json +2 -1
- package/skills/atelier-orchestrator/SKILL.md +180 -0
- package/skills/atelier-setup/SKILL.md +80 -0
- package/skills/code-review/SKILL.md +2 -2
- package/skills/code-review/references/reviewers.md +3 -3
- package/skills/code-review/references/rq.md +9 -9
- package/skills/code-subagents/SKILL.md +44 -75
- package/skills/code-subagents/references/batch-reviewer-prompt.md +44 -0
- package/skills/code-subagents/references/implementor-prompt.md +10 -11
- package/skills/spec-brainstorm/SKILL.md +21 -16
- package/skills/spec-finish/SKILL.md +14 -14
- package/skills/spec-implement/SKILL.md +42 -42
- package/skills/spec-plan/SKILL.md +72 -26
- package/skills/spec-plan/references/plan_template.md +77 -0
- package/skills/code-subagents/references/code-quality-reviewer-prompt.md +0 -48
- package/skills/code-subagents/references/spec-reviewer-prompt.md +0 -62
- package/skills/python-architecture/SKILL.md +0 -148
- package/skills/python-architecture/references/data-modeling.md +0 -558
- package/skills/python-architecture/references/ddd.md +0 -569
- package/skills/python-architecture/references/functional-core.md +0 -337
- package/skills/python-build-tools/SKILL.md +0 -153
- package/skills/python-build-tools/references/basedpyright.md +0 -321
- package/skills/python-build-tools/references/ruff.md +0 -225
- package/skills/python-build-tools/references/uv.md +0 -257
- package/skills/python-fastapi/SKILL.md +0 -184
- package/skills/python-fastapi/references/api-design.md +0 -563
- package/skills/python-fastapi/references/dependencies.md +0 -479
- package/skills/python-fastapi/references/middleware.md +0 -475
- package/skills/python-fastapi/references/validation.md +0 -497
- package/skills/python-modern-python/SKILL.md +0 -201
- package/skills/python-modern-python/references/async.md +0 -76
- package/skills/python-modern-python/references/pattern-matching.md +0 -89
- package/skills/python-modern-python/references/typing.md +0 -96
- package/skills/python-monorepo/SKILL.md +0 -146
- package/skills/python-monorepo/references/docker.md +0 -515
- package/skills/python-monorepo/references/namespace-packages.md +0 -426
- package/skills/python-monorepo/references/workspace-config.md +0 -341
- package/skills/python-sqlalchemy/SKILL.md +0 -119
- package/skills/python-sqlalchemy/references/async.md +0 -51
- package/skills/python-sqlalchemy/references/models.md +0 -67
- package/skills/python-sqlalchemy/references/queries.md +0 -57
- package/skills/python-temporal/SKILL.md +0 -128
- package/skills/python-temporal/references/patterns.md +0 -87
- package/skills/python-temporal/references/testing.md +0 -54
- package/skills/python-testing/SKILL.md +0 -161
- package/skills/python-testing/references/boundaries.md +0 -449
- package/skills/python-testing/references/mocking.md +0 -449
- package/skills/python-testing/references/pytest.md +0 -524
- package/skills/spec-orchestrator/SKILL.md +0 -145
- package/skills/typescript-api-design/SKILL.md +0 -396
- package/skills/typescript-api-design/references/error-responses.md +0 -469
- package/skills/typescript-build-tools/SKILL.md +0 -447
- package/skills/typescript-build-tools/references/biome.md +0 -436
- package/skills/typescript-build-tools/references/bun.md +0 -432
- package/skills/typescript-build-tools/references/turborepo.md +0 -426
- package/skills/typescript-build-tools/references/vitest.md +0 -518
- package/skills/typescript-drizzle-orm/SKILL.md +0 -398
- package/skills/typescript-drizzle-orm/references/cloudflare.md +0 -392
- package/skills/typescript-drizzle-orm/references/entity-pattern.md +0 -412
- package/skills/typescript-drizzle-orm/references/postgresql.md +0 -191
- package/skills/typescript-drizzle-orm/references/repository-pattern.md +0 -479
- package/skills/typescript-drizzle-orm/references/sqlite.md +0 -291
- package/skills/typescript-dynamodb-toolbox/SKILL.md +0 -370
- package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +0 -574
- package/skills/typescript-dynamodb-toolbox/references/error-handling.md +0 -495
- package/skills/typescript-dynamodb-toolbox/references/modeling.md +0 -332
- package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +0 -631
- package/skills/typescript-dynamodb-toolbox/references/testing.md +0 -718
- package/skills/typescript-dynamodb-toolbox/references/transactions.md +0 -423
- package/skills/typescript-effect-ts/SKILL.md +0 -341
- package/skills/typescript-effect-ts/references/core.md +0 -412
- package/skills/typescript-effect-ts/references/error-handling.md +0 -468
- package/skills/typescript-effect-ts/references/resources.md +0 -476
- package/skills/typescript-effect-ts/references/schema.md +0 -536
- package/skills/typescript-effect-ts/references/services.md +0 -461
- package/skills/typescript-fastify/SKILL.md +0 -405
- package/skills/typescript-fastify/references/plugins.md +0 -329
- package/skills/typescript-fastify/references/typeid.md +0 -315
- package/skills/typescript-functional-patterns/SKILL.md +0 -402
- package/skills/typescript-functional-patterns/references/adts.md +0 -497
- package/skills/typescript-functional-patterns/references/branded-types.md +0 -542
- package/skills/typescript-functional-patterns/references/migration-guide.md +0 -695
- package/skills/typescript-functional-patterns/references/option-result.md +0 -585
- package/skills/typescript-testing/SKILL.md +0 -353
- package/skills/typescript-testing/references/mocking.md +0 -675
- package/skills/typescript-testing/references/msw.md +0 -852
- package/skills/typescript-testing/references/snapshot-testing.md +0 -774
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# Async/Await Patterns
|
|
2
|
-
|
|
3
|
-
## Basic Async
|
|
4
|
-
|
|
5
|
-
```python
|
|
6
|
-
import asyncio
|
|
7
|
-
|
|
8
|
-
async def fetch_user(user_id: int) -> User:
|
|
9
|
-
"""Async function"""
|
|
10
|
-
await asyncio.sleep(1) # Simulate IO
|
|
11
|
-
return User(id=user_id)
|
|
12
|
-
|
|
13
|
-
# Run async function
|
|
14
|
-
user = await fetch_user(1)
|
|
15
|
-
|
|
16
|
-
# Or from sync code
|
|
17
|
-
user = asyncio.run(fetch_user(1))
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Concurrent Execution
|
|
21
|
-
|
|
22
|
-
```python
|
|
23
|
-
async def process_all(user_ids: list[int]):
|
|
24
|
-
"""Process multiple users concurrently"""
|
|
25
|
-
tasks = [fetch_user(id) for id in user_ids]
|
|
26
|
-
users = await asyncio.gather(*tasks)
|
|
27
|
-
return users
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Async Context Managers
|
|
31
|
-
|
|
32
|
-
```python
|
|
33
|
-
class AsyncDB:
|
|
34
|
-
async def __aenter__(self):
|
|
35
|
-
await self.connect()
|
|
36
|
-
return self
|
|
37
|
-
|
|
38
|
-
async def __aexit__(self, *args):
|
|
39
|
-
await self.disconnect()
|
|
40
|
-
|
|
41
|
-
async with AsyncDB() as db:
|
|
42
|
-
result = await db.query(...)
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Async Iterators
|
|
46
|
-
|
|
47
|
-
```python
|
|
48
|
-
class AsyncRange:
|
|
49
|
-
def __init__(self, n: int):
|
|
50
|
-
self.n = n
|
|
51
|
-
self.i = 0
|
|
52
|
-
|
|
53
|
-
def __aiter__(self):
|
|
54
|
-
return self
|
|
55
|
-
|
|
56
|
-
async def __anext__(self):
|
|
57
|
-
if self.i >= self.n:
|
|
58
|
-
raise StopAsyncIteration
|
|
59
|
-
self.i += 1
|
|
60
|
-
await asyncio.sleep(0.1)
|
|
61
|
-
return self.i
|
|
62
|
-
|
|
63
|
-
async for i in AsyncRange(10):
|
|
64
|
-
print(i)
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Error Handling
|
|
68
|
-
|
|
69
|
-
```python
|
|
70
|
-
async def safe_fetch(url: str):
|
|
71
|
-
try:
|
|
72
|
-
return await fetch_data(url)
|
|
73
|
-
except httpx.HTTPError as e:
|
|
74
|
-
logger.error(f"Failed to fetch {url}: {e}")
|
|
75
|
-
return None
|
|
76
|
-
```
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# Pattern Matching (Python 3.10+)
|
|
2
|
-
|
|
3
|
-
## Basic Patterns
|
|
4
|
-
|
|
5
|
-
```python
|
|
6
|
-
def handle_status(code: int):
|
|
7
|
-
match code:
|
|
8
|
-
case 200:
|
|
9
|
-
return "OK"
|
|
10
|
-
case 404:
|
|
11
|
-
return "Not Found"
|
|
12
|
-
case 500:
|
|
13
|
-
return "Server Error"
|
|
14
|
-
case _:
|
|
15
|
-
return "Unknown"
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Or Patterns
|
|
19
|
-
|
|
20
|
-
```python
|
|
21
|
-
match status:
|
|
22
|
-
case 200 | 201 | 204:
|
|
23
|
-
return "Success"
|
|
24
|
-
case 400 | 404:
|
|
25
|
-
return "Client Error"
|
|
26
|
-
case 500 | 502 | 503:
|
|
27
|
-
return "Server Error"
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Structural Patterns
|
|
31
|
-
|
|
32
|
-
```python
|
|
33
|
-
def process_point(point):
|
|
34
|
-
match point:
|
|
35
|
-
case (0, 0):
|
|
36
|
-
return "Origin"
|
|
37
|
-
case (x, 0):
|
|
38
|
-
return f"X-axis at {x}"
|
|
39
|
-
case (0, y):
|
|
40
|
-
return f"Y-axis at {y}"
|
|
41
|
-
case (x, y):
|
|
42
|
-
return f"Point at ({x}, {y})"
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Class Patterns
|
|
46
|
-
|
|
47
|
-
```python
|
|
48
|
-
from dataclasses import dataclass
|
|
49
|
-
|
|
50
|
-
@dataclass
|
|
51
|
-
class Circle:
|
|
52
|
-
radius: float
|
|
53
|
-
|
|
54
|
-
@dataclass
|
|
55
|
-
class Rectangle:
|
|
56
|
-
width: float
|
|
57
|
-
height: float
|
|
58
|
-
|
|
59
|
-
def area(shape):
|
|
60
|
-
match shape:
|
|
61
|
-
case Circle(radius=r):
|
|
62
|
-
return 3.14 * r * r
|
|
63
|
-
case Rectangle(width=w, height=h):
|
|
64
|
-
return w * h
|
|
65
|
-
case _:
|
|
66
|
-
raise ValueError("Unknown shape")
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Guards
|
|
70
|
-
|
|
71
|
-
```python
|
|
72
|
-
match point:
|
|
73
|
-
case (x, y) if x == y:
|
|
74
|
-
return "On diagonal"
|
|
75
|
-
case (x, y) if x > y:
|
|
76
|
-
return "Above diagonal"
|
|
77
|
-
case (x, y):
|
|
78
|
-
return "Below diagonal"
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Nested Patterns
|
|
82
|
-
|
|
83
|
-
```python
|
|
84
|
-
match event:
|
|
85
|
-
case {"type": "click", "position": (x, y)}:
|
|
86
|
-
handle_click(x, y)
|
|
87
|
-
case {"type": "key", "key": key_code}:
|
|
88
|
-
handle_key(key_code)
|
|
89
|
-
```
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
# Advanced Type Hints
|
|
2
|
-
|
|
3
|
-
## Generics
|
|
4
|
-
|
|
5
|
-
```python
|
|
6
|
-
from typing import TypeVar, Generic
|
|
7
|
-
|
|
8
|
-
T = TypeVar("T")
|
|
9
|
-
|
|
10
|
-
class Stack(Generic[T]):
|
|
11
|
-
def __init__(self):
|
|
12
|
-
self.items: list[T] = []
|
|
13
|
-
|
|
14
|
-
def push(self, item: T) -> None:
|
|
15
|
-
self.items.append(item)
|
|
16
|
-
|
|
17
|
-
def pop(self) -> T:
|
|
18
|
-
return self.items.pop()
|
|
19
|
-
|
|
20
|
-
stack: Stack[int] = Stack()
|
|
21
|
-
stack.push(1)
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Protocol
|
|
25
|
-
|
|
26
|
-
```python
|
|
27
|
-
from typing import Protocol
|
|
28
|
-
|
|
29
|
-
class Comparable(Protocol):
|
|
30
|
-
def __lt__(self, other: object) -> bool:
|
|
31
|
-
...
|
|
32
|
-
|
|
33
|
-
def sort_items(items: list[Comparable]) -> list[Comparable]:
|
|
34
|
-
return sorted(items)
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## TypedDict
|
|
38
|
-
|
|
39
|
-
```python
|
|
40
|
-
from typing import TypedDict
|
|
41
|
-
|
|
42
|
-
class UserDict(TypedDict):
|
|
43
|
-
id: int
|
|
44
|
-
name: str
|
|
45
|
-
email: str
|
|
46
|
-
|
|
47
|
-
def create_user(data: UserDict) -> User:
|
|
48
|
-
return User(
|
|
49
|
-
id=data["id"],
|
|
50
|
-
name=data["name"],
|
|
51
|
-
email=data["email"],
|
|
52
|
-
)
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Literal
|
|
56
|
-
|
|
57
|
-
```python
|
|
58
|
-
from typing import Literal
|
|
59
|
-
|
|
60
|
-
Status = Literal["pending", "active", "inactive"]
|
|
61
|
-
|
|
62
|
-
def set_status(status: Status) -> None:
|
|
63
|
-
...
|
|
64
|
-
|
|
65
|
-
set_status("pending") # OK
|
|
66
|
-
set_status("invalid") # Type error
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## ParamSpec
|
|
70
|
-
|
|
71
|
-
```python
|
|
72
|
-
from typing import Callable, ParamSpec, TypeVar
|
|
73
|
-
|
|
74
|
-
P = ParamSpec("P")
|
|
75
|
-
R = TypeVar("R")
|
|
76
|
-
|
|
77
|
-
def with_logging(func: Callable[P, R]) -> Callable[P, R]:
|
|
78
|
-
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
79
|
-
print(f"Calling {func.__name__}")
|
|
80
|
-
return func(*args, **kwargs)
|
|
81
|
-
return wrapper
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Self (Python 3.11+)
|
|
85
|
-
|
|
86
|
-
```python
|
|
87
|
-
from typing import Self
|
|
88
|
-
|
|
89
|
-
class Builder:
|
|
90
|
-
def with_name(self, name: str) -> Self:
|
|
91
|
-
self.name = name
|
|
92
|
-
return self
|
|
93
|
-
|
|
94
|
-
def build(self) -> Product:
|
|
95
|
-
return Product(self.name)
|
|
96
|
-
```
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: python-monorepo
|
|
3
|
-
description: Python monorepo architecture with uv workspaces, mise, and apps/packages pattern. Use when setting up project structure, configuring workspaces, managing dependencies across packages, or designing multi-app Python repositories.
|
|
4
|
-
user-invocable: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Python Monorepo with uv Workspaces
|
|
8
|
-
|
|
9
|
-
Modern Python monorepo architecture using `uv` for workspace management and `mise` for Python version and task orchestration.
|
|
10
|
-
|
|
11
|
-
## Core Concepts
|
|
12
|
-
|
|
13
|
-
**Monorepo**: Single repository containing multiple related packages and applications
|
|
14
|
-
|
|
15
|
-
**uv workspace**: Python's answer to npm/pnpm workspaces
|
|
16
|
-
- Single lock file for entire repo
|
|
17
|
-
- Shared virtual environment
|
|
18
|
-
- Cross-package dependency resolution
|
|
19
|
-
|
|
20
|
-
## Directory Structure
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
my-monorepo/
|
|
24
|
-
├── .mise.toml # Python version + task runner
|
|
25
|
-
├── pyproject.toml # Root workspace config
|
|
26
|
-
├── uv.lock # Unified lock file
|
|
27
|
-
├── apps/ # Deployable applications
|
|
28
|
-
│ ├── api/
|
|
29
|
-
│ └── worker/
|
|
30
|
-
└── packages/ # Shared libraries
|
|
31
|
-
├── core/
|
|
32
|
-
└── utils/
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Workspace Configuration
|
|
36
|
-
|
|
37
|
-
**Root pyproject.toml:**
|
|
38
|
-
|
|
39
|
-
```toml
|
|
40
|
-
[project]
|
|
41
|
-
name = "my-monorepo"
|
|
42
|
-
version = "0.1.0"
|
|
43
|
-
requires-python = ">=3.12"
|
|
44
|
-
|
|
45
|
-
[tool.uv.workspace]
|
|
46
|
-
members = ["apps/*", "packages/*"]
|
|
47
|
-
|
|
48
|
-
[tool.uv]
|
|
49
|
-
dev-dependencies = [
|
|
50
|
-
"pytest>=8.0.0",
|
|
51
|
-
"ruff>=0.8.0",
|
|
52
|
-
"basedpyright>=1.0.0",
|
|
53
|
-
]
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
See `references/workspace-config.md` for detailed configurations.
|
|
57
|
-
|
|
58
|
-
## Package Linking
|
|
59
|
-
|
|
60
|
-
Workspace packages reference each other by distribution name:
|
|
61
|
-
|
|
62
|
-
**packages/utils/pyproject.toml:**
|
|
63
|
-
```toml
|
|
64
|
-
[project]
|
|
65
|
-
name = "my-utils"
|
|
66
|
-
dependencies = ["my-core"]
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**apps/api/pyproject.toml:**
|
|
70
|
-
```toml
|
|
71
|
-
[project]
|
|
72
|
-
name = "my-api"
|
|
73
|
-
dependencies = ["my-core", "my-utils", "fastapi>=0.100.0"]
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Cross-Package Import
|
|
77
|
-
|
|
78
|
-
**packages/core/src/my_core/entities.py:**
|
|
79
|
-
```python
|
|
80
|
-
class User:
|
|
81
|
-
def __init__(self, email: str):
|
|
82
|
-
self.email = email
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**apps/api/src/my_api/main.py:**
|
|
86
|
-
```python
|
|
87
|
-
from my_core.entities import User # Import from workspace package
|
|
88
|
-
|
|
89
|
-
def run():
|
|
90
|
-
# App code...
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## Dependency Direction (Critical)
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
apps/ → packages/ (Apps depend on packages)
|
|
97
|
-
packages/ ⇏ apps/ (Never the reverse)
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
**Rules:**
|
|
101
|
-
- Apps can depend on packages
|
|
102
|
-
- Packages can depend on other packages
|
|
103
|
-
- Packages NEVER depend on apps
|
|
104
|
-
- Avoid circular dependencies
|
|
105
|
-
|
|
106
|
-
## mise Task Runner
|
|
107
|
-
|
|
108
|
-
**.mise.toml:**
|
|
109
|
-
|
|
110
|
-
```toml
|
|
111
|
-
[tools]
|
|
112
|
-
python = "3.12"
|
|
113
|
-
|
|
114
|
-
[tasks.check]
|
|
115
|
-
depends = ["lint", "typecheck", "test"]
|
|
116
|
-
|
|
117
|
-
[tasks.lint]
|
|
118
|
-
run = "uv run ruff check ."
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
**Usage:** `mise run check`
|
|
122
|
-
|
|
123
|
-
## Core uv Commands
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
uv sync # Install all packages
|
|
127
|
-
uv add fastapi --package my-api # Add to specific package
|
|
128
|
-
uv add my-core --package my-api # Add workspace package
|
|
129
|
-
uv run pytest # Run tests
|
|
130
|
-
uv lock --upgrade # Update dependencies
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Best Practices
|
|
134
|
-
|
|
135
|
-
1. Single lock file at root
|
|
136
|
-
2. Shared dev tools (ruff, pytest) in root dev-dependencies
|
|
137
|
-
3. Pin Python version with mise
|
|
138
|
-
4. Apps depend on packages only
|
|
139
|
-
5. Use namespace packages for logical grouping (optional)
|
|
140
|
-
|
|
141
|
-
## References
|
|
142
|
-
|
|
143
|
-
For detailed patterns:
|
|
144
|
-
- `references/workspace-config.md` - pyproject.toml patterns, dependencies, versions
|
|
145
|
-
- `references/docker.md` - Multi-stage Docker builds
|
|
146
|
-
- `references/namespace-packages.md` - PEP 420 namespace packages
|