agentic-team-templates 0.12.0 → 0.13.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/README.md CHANGED
@@ -147,20 +147,25 @@ npx agentic-team-templates --reset --force
147
147
 
148
148
  | Template | Description |
149
149
  |----------|-------------|
150
- | `web-frontend` | SPAs, SSR, static sites, PWAs |
151
- | `web-backend` | REST, GraphQL, microservices |
152
- | `fullstack` | Full-stack apps (Next.js, Nuxt, etc.) |
153
- | `mobile` | React Native, Flutter, native iOS/Android |
154
- | `cli-tools` | Command-line applications and developer tools |
155
- | `blockchain` | Smart contracts, DeFi, Web3 applications |
156
- | `ml-ai` | Machine learning systems, model development |
157
- | `data-engineering` | Data pipelines, ETL, warehousing |
158
- | `platform-engineering` | Infrastructure as code, Kubernetes, CI/CD |
159
- | `devops-sre` | Incident management, SLOs, observability |
160
- | `product-manager` | Product strategy, discovery, OKRs, PRDs |
161
- | `qa-engineering` | Test strategy, automation, quality gates |
162
- | `utility-agent` | AI agent utilities, context management |
163
- | `documentation` | Technical writing, API docs, ADRs |
150
+ | `blockchain` | Smart contracts, DeFi protocols, and Web3 applications (Solidity, Foundry, Viem) |
151
+ | `cli-tools` | Command-line applications and developer tools (Cobra, Commander, Click) |
152
+ | `data-engineering` | Data platforms and pipelines (ETL, data modeling, data quality) |
153
+ | `devops-sre` | DevOps and SRE practices (incident management, observability, SLOs, chaos engineering) |
154
+ | `documentation` | Technical documentation standards (READMEs, API docs, ADRs, code comments) |
155
+ | `fullstack` | Full-stack web applications (Next.js, Nuxt, SvelteKit, Remix) |
156
+ | `golang-expert` | Principal-level Go engineering (concurrency, stdlib, production patterns, testing) |
157
+ | `javascript-expert` | Principal-level JavaScript engineering across Node.js, React, vanilla JS, and testing |
158
+ | `ml-ai` | Machine learning and AI systems (model development, deployment, monitoring) |
159
+ | `mobile` | Mobile applications (React Native, Flutter, native iOS/Android) |
160
+ | `platform-engineering` | Internal developer platforms, infrastructure automation, reliability engineering |
161
+ | `product-manager` | Product management with customer-centric discovery, prioritization, and execution |
162
+ | `python-expert` | Principal-level Python engineering (type system, async, testing, FastAPI, Django) |
163
+ | `qa-engineering` | Quality assurance programs for confident, rapid software delivery |
164
+ | `rust-expert` | Principal-level Rust engineering (ownership, concurrency, unsafe, traits, async) |
165
+ | `testing` | Comprehensive testing practices (TDD, test design, CI/CD integration, performance testing) |
166
+ | `utility-agent` | AI agent utilities with context management and hallucination prevention |
167
+ | `web-backend` | Backend APIs and services (REST, GraphQL, microservices) |
168
+ | `web-frontend` | Frontend web applications (SPAs, SSR, static sites, PWAs) |
164
169
 
165
170
  ## What Gets Installed
166
171
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-team-templates",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "description": "AI coding assistant templates for Cursor IDE. Pre-configured rules and guidelines that help AI assistants write better code. - use at your own risk",
5
5
  "keywords": [
6
6
  "cursor",
package/src/index.js CHANGED
@@ -60,10 +60,6 @@ const TEMPLATES = {
60
60
  description: 'Mobile applications (React Native, Flutter, native iOS/Android)',
61
61
  rules: ['navigation.md', 'offline-first.md', 'overview.md', 'performance.md', 'testing.md']
62
62
  },
63
- 'rust-expert': {
64
- description: 'Principal-level Rust engineering (ownership, concurrency, unsafe, traits, async)',
65
- rules: ['concurrency.md', 'ecosystem-and-tooling.md', 'error-handling.md', 'overview.md', 'ownership-and-borrowing.md', 'performance-and-unsafe.md', 'testing.md', 'traits-and-generics.md']
66
- },
67
63
  'platform-engineering': {
68
64
  description: 'Internal developer platforms, infrastructure automation, and reliability engineering',
69
65
  rules: ['ci-cd.md', 'developer-experience.md', 'infrastructure-as-code.md', 'kubernetes.md', 'observability.md', 'overview.md', 'security.md', 'testing.md']
@@ -72,10 +68,18 @@ const TEMPLATES = {
72
68
  description: 'Product management with customer-centric discovery, prioritization, and execution',
73
69
  rules: ['communication.md', 'discovery.md', 'metrics.md', 'overview.md', 'prioritization.md', 'requirements.md']
74
70
  },
71
+ 'python-expert': {
72
+ description: 'Principal-level Python engineering (type system, async, testing, FastAPI, Django)',
73
+ rules: ['async-python.md', 'overview.md', 'patterns-and-idioms.md', 'performance.md', 'testing.md', 'tooling.md', 'type-system.md', 'web-and-apis.md']
74
+ },
75
75
  'qa-engineering': {
76
76
  description: 'Quality assurance programs for confident, rapid software delivery',
77
77
  rules: ['automation.md', 'metrics.md', 'overview.md', 'quality-gates.md', 'test-design.md', 'test-strategy.md']
78
78
  },
79
+ 'rust-expert': {
80
+ description: 'Principal-level Rust engineering (ownership, concurrency, unsafe, traits, async)',
81
+ rules: ['concurrency.md', 'ecosystem-and-tooling.md', 'error-handling.md', 'overview.md', 'ownership-and-borrowing.md', 'performance-and-unsafe.md', 'testing.md', 'traits-and-generics.md']
82
+ },
79
83
  'testing': {
80
84
  description: 'Comprehensive testing practices (TDD, test design, CI/CD integration, performance testing)',
81
85
  rules: ['advanced-techniques.md', 'ci-cd-integration.md', 'overview.md', 'performance-testing.md', 'quality-metrics.md', 'reliability.md', 'tdd-methodology.md', 'test-data.md', 'test-design.md', 'test-types.md']
@@ -160,7 +164,7 @@ async function checkForUpdates() {
160
164
  function printBanner() {
161
165
  console.log(colors.blue(`
162
166
  ╔═══════════════════════════════════════════════════════════╗
163
- Cursor Templates Installer
167
+ Agentic Team Templates Installer
164
168
  ╚═══════════════════════════════════════════════════════════╝
165
169
  `));
166
170
  }
package/src/index.test.js CHANGED
@@ -83,10 +83,11 @@ describe('Constants', () => {
83
83
  'javascript-expert',
84
84
  'ml-ai',
85
85
  'mobile',
86
- 'rust-expert',
87
86
  'platform-engineering',
88
87
  'product-manager',
88
+ 'python-expert',
89
89
  'qa-engineering',
90
+ 'rust-expert',
90
91
  'testing',
91
92
  'utility-agent',
92
93
  'web-backend',
@@ -0,0 +1,214 @@
1
+ # Async Python
2
+
3
+ Python's `asyncio` enables concurrent I/O-bound operations on a single thread. Understanding the event loop, coroutines, and task lifecycle is essential for building high-performance async services.
4
+
5
+ ## Fundamentals
6
+
7
+ ### Coroutines and Tasks
8
+
9
+ ```python
10
+ import asyncio
11
+
12
+ # A coroutine is defined with async def
13
+ async def fetch_data(url: str) -> bytes:
14
+ async with aiohttp.ClientSession() as session:
15
+ async with session.get(url) as response:
16
+ return await response.read()
17
+
18
+ # Coroutines don't run until awaited or wrapped in a task
19
+ coro = fetch_data("https://example.com") # Nothing happens yet
20
+ data = await coro # Now it runs
21
+
22
+ # Tasks run concurrently on the event loop
23
+ async def fetch_all(urls: list[str]) -> list[bytes]:
24
+ tasks = [asyncio.create_task(fetch_data(url)) for url in urls]
25
+ return await asyncio.gather(*tasks)
26
+ ```
27
+
28
+ ### asyncio.gather vs TaskGroup
29
+
30
+ ```python
31
+ # gather — returns results in order, continues on individual failures (by default)
32
+ results = await asyncio.gather(
33
+ fetch_users(),
34
+ fetch_posts(),
35
+ fetch_comments(),
36
+ )
37
+ users, posts, comments = results
38
+
39
+ # TaskGroup (3.11+) — structured concurrency, cancels all on first failure
40
+ async with asyncio.TaskGroup() as tg:
41
+ user_task = tg.create_task(fetch_users())
42
+ post_task = tg.create_task(fetch_posts())
43
+
44
+ # All tasks complete or all cancelled if one fails
45
+ users = user_task.result()
46
+ posts = post_task.result()
47
+ ```
48
+
49
+ ### Timeouts
50
+
51
+ ```python
52
+ # asyncio.timeout (3.11+)
53
+ async with asyncio.timeout(5.0):
54
+ data = await fetch_data(url)
55
+
56
+ # asyncio.wait_for (older approach)
57
+ try:
58
+ data = await asyncio.wait_for(fetch_data(url), timeout=5.0)
59
+ except asyncio.TimeoutError:
60
+ logger.warning("fetch timed out", extra={"url": url})
61
+ raise
62
+ ```
63
+
64
+ ### Bounded Concurrency
65
+
66
+ ```python
67
+ # Semaphore for limiting concurrent operations
68
+ async def fetch_all(urls: list[str], max_concurrent: int = 10) -> list[Response]:
69
+ semaphore = asyncio.Semaphore(max_concurrent)
70
+
71
+ async def bounded_fetch(url: str) -> Response:
72
+ async with semaphore:
73
+ return await fetch(url)
74
+
75
+ async with asyncio.TaskGroup() as tg:
76
+ tasks = [tg.create_task(bounded_fetch(url)) for url in urls]
77
+
78
+ return [task.result() for task in tasks]
79
+ ```
80
+
81
+ ## Async Generators and Iteration
82
+
83
+ ```python
84
+ from collections.abc import AsyncIterator
85
+
86
+ # Async generator
87
+ async def stream_records(query: str) -> AsyncIterator[Record]:
88
+ async with db.execute(query) as cursor:
89
+ async for row in cursor:
90
+ yield Record.from_row(row)
91
+
92
+ # Async for loop
93
+ async for record in stream_records("SELECT * FROM events"):
94
+ await process(record)
95
+
96
+ # Async comprehension
97
+ results = [item async for item in stream_records(query) if item.is_valid()]
98
+ ```
99
+
100
+ ## Async Context Managers
101
+
102
+ ```python
103
+ from contextlib import asynccontextmanager
104
+ from collections.abc import AsyncIterator
105
+
106
+ @asynccontextmanager
107
+ async def managed_pool(url: str, size: int = 10) -> AsyncIterator[Pool]:
108
+ pool = await create_pool(url, max_size=size)
109
+ try:
110
+ yield pool
111
+ finally:
112
+ await pool.close()
113
+
114
+ async def main() -> None:
115
+ async with managed_pool("postgresql://localhost/db") as pool:
116
+ async with pool.acquire() as conn:
117
+ result = await conn.fetch("SELECT 1")
118
+ ```
119
+
120
+ ## Event Loop Patterns
121
+
122
+ ```python
123
+ # Main entry point
124
+ async def main() -> None:
125
+ ...
126
+
127
+ if __name__ == "__main__":
128
+ asyncio.run(main())
129
+
130
+ # Running blocking code in async context
131
+ import functools
132
+
133
+ async def process_file(path: Path) -> Data:
134
+ # Run CPU-bound or blocking I/O in a thread pool
135
+ loop = asyncio.get_running_loop()
136
+ data = await loop.run_in_executor(
137
+ None, # Default ThreadPoolExecutor
138
+ functools.partial(parse_file, path),
139
+ )
140
+ return data
141
+ ```
142
+
143
+ ## Graceful Shutdown
144
+
145
+ ```python
146
+ import signal
147
+
148
+ async def main() -> None:
149
+ loop = asyncio.get_running_loop()
150
+
151
+ shutdown_event = asyncio.Event()
152
+
153
+ for sig in (signal.SIGTERM, signal.SIGINT):
154
+ loop.add_signal_handler(sig, shutdown_event.set)
155
+
156
+ server = await start_server()
157
+
158
+ await shutdown_event.wait()
159
+
160
+ logger.info("shutting down")
161
+ await server.stop()
162
+ # Clean up resources
163
+ ```
164
+
165
+ ## Async Testing
166
+
167
+ ```python
168
+ import pytest
169
+
170
+ @pytest.mark.asyncio
171
+ async def test_fetch_user() -> None:
172
+ service = UserService(fake_repo)
173
+ user = await service.get_by_id("123")
174
+ assert user.name == "Alice"
175
+
176
+ # Fixtures
177
+ @pytest.fixture
178
+ async def db_pool():
179
+ pool = await create_pool(TEST_DATABASE_URL)
180
+ yield pool
181
+ await pool.close()
182
+
183
+ @pytest.fixture
184
+ async def service(db_pool):
185
+ return UserService(UserRepo(db_pool))
186
+ ```
187
+
188
+ ## Anti-Patterns
189
+
190
+ ```python
191
+ # Never: Blocking calls in async code
192
+ async def bad_handler(request: Request) -> Response:
193
+ data = requests.get(url) # Blocks the event loop!
194
+ time.sleep(1) # Blocks the event loop!
195
+ # Use aiohttp and asyncio.sleep() instead
196
+
197
+ # Never: Creating event loops manually (unless you're a framework author)
198
+ loop = asyncio.new_event_loop() # Use asyncio.run() instead
199
+
200
+ # Never: Fire-and-forget tasks without error handling
201
+ asyncio.create_task(background_work()) # Who catches the exception?
202
+ # Better:
203
+ task = asyncio.create_task(background_work())
204
+ task.add_done_callback(handle_task_exception)
205
+
206
+ # Never: Mixing sync and async without run_in_executor
207
+ async def handler():
208
+ result = cpu_bound_work() # Blocks event loop
209
+ # Use: result = await loop.run_in_executor(None, cpu_bound_work)
210
+
211
+ # Never: Unbounded task spawning
212
+ for item in million_items:
213
+ asyncio.create_task(process(item)) # OOM risk — use semaphore
214
+ ```
@@ -0,0 +1,174 @@
1
+ # Python Expert
2
+
3
+ Guidelines for principal-level Python engineering. Idiomatic Python, production systems, and deep interpreter knowledge.
4
+
5
+ ## Scope
6
+
7
+ This ruleset applies to:
8
+ - Web services and APIs (Django, FastAPI, Flask)
9
+ - CLI tools and automation scripts
10
+ - Data processing and ETL pipelines
11
+ - Libraries and packages published to PyPI
12
+ - Machine learning infrastructure
13
+ - System administration and DevOps tooling
14
+ - Async services and event-driven architectures
15
+
16
+ ## Core Philosophy
17
+
18
+ Python's power is in its clarity. The best Python code reads like well-written prose.
19
+
20
+ - **Readability counts.** The Zen of Python isn't decoration — it's the engineering standard. `import this` and mean it.
21
+ - **Explicit is better than implicit.** Type hints, clear names, no magic. If you need a comment to explain what a variable holds, rename the variable.
22
+ - **Simple is better than complex.** A straightforward `for` loop that's obvious beats a clever one-liner that requires a decoder ring.
23
+ - **Errors should never pass silently.** Bare `except:` is a bug. Swallowing exceptions hides the failures that will wake you up at 3 AM.
24
+ - **The standard library is rich — use it.** `collections`, `itertools`, `pathlib`, `dataclasses`, `contextlib`, `functools` — know them deeply before reaching for PyPI.
25
+ - **If you don't know, say so.** Python's ecosystem is vast. Admitting uncertainty about a niche library or CPython internal is honest and professional.
26
+
27
+ ## Key Principles
28
+
29
+ ### 1. Type Hints Are Not Optional
30
+
31
+ ```python
32
+ # Modern Python is typed Python. Type hints are documentation,
33
+ # tooling enablement, and bug prevention.
34
+
35
+ # Good: Fully typed function signatures
36
+ def fetch_users(
37
+ db: Database,
38
+ *,
39
+ limit: int = 100,
40
+ active_only: bool = True,
41
+ ) -> list[User]:
42
+ ...
43
+
44
+ # Good: Complex types with type aliases
45
+ type UserMap = dict[UserId, User]
46
+ type Handler = Callable[[Request], Awaitable[Response]]
47
+
48
+ # Bad: No type information
49
+ def fetch_users(db, limit=100, active_only=True):
50
+ ... # What does this return? What's db? Nobody knows.
51
+ ```
52
+
53
+ ### 2. Dataclasses and Pydantic Over Raw Dicts
54
+
55
+ ```python
56
+ # Good: Structured data with validation
57
+ from dataclasses import dataclass, field
58
+ from datetime import datetime
59
+
60
+ @dataclass(frozen=True, slots=True)
61
+ class User:
62
+ id: str
63
+ email: str
64
+ name: str
65
+ created_at: datetime = field(default_factory=datetime.now)
66
+
67
+ # Good: Pydantic for external data validation
68
+ from pydantic import BaseModel, EmailStr
69
+
70
+ class CreateUserRequest(BaseModel):
71
+ email: EmailStr
72
+ name: str = Field(min_length=1, max_length=200)
73
+
74
+ # Bad: Dict soup
75
+ user = {"id": "123", "email": "a@b.com"} # No validation, no autocomplete, no safety
76
+ ```
77
+
78
+ ### 3. EAFP Over LBYL
79
+
80
+ ```python
81
+ # Easier to Ask Forgiveness than Permission — Pythonic
82
+ # Good: Try it and handle the exception
83
+ try:
84
+ value = mapping[key]
85
+ except KeyError:
86
+ value = default
87
+
88
+ # Also good: Use .get() when it's clearer
89
+ value = mapping.get(key, default)
90
+
91
+ # Bad: Look Before You Leap (extra lookup, race conditions)
92
+ if key in mapping:
93
+ value = mapping[key] # What if it was deleted between check and access?
94
+ ```
95
+
96
+ ### 4. Context Managers for Resource Management
97
+
98
+ ```python
99
+ # Always use context managers for resources
100
+ # Good:
101
+ with open("data.json") as f:
102
+ data = json.load(f)
103
+
104
+ async with aiohttp.ClientSession() as session:
105
+ response = await session.get(url)
106
+
107
+ # Good: Custom context managers
108
+ from contextlib import contextmanager
109
+
110
+ @contextmanager
111
+ def temporary_directory():
112
+ path = Path(tempfile.mkdtemp())
113
+ try:
114
+ yield path
115
+ finally:
116
+ shutil.rmtree(path)
117
+ ```
118
+
119
+ ## Project Structure
120
+
121
+ ```
122
+ project/
123
+ ├── src/
124
+ │ └── mypackage/
125
+ │ ├── __init__.py
126
+ │ ├── py.typed # PEP 561 marker
127
+ │ ├── config.py # Configuration loading
128
+ │ ├── exceptions.py # Custom exceptions
129
+ │ ├── models/ # Domain models
130
+ │ │ ├── __init__.py
131
+ │ │ └── user.py
132
+ │ ├── services/ # Business logic
133
+ │ │ ├── __init__.py
134
+ │ │ └── user_service.py
135
+ │ ├── repositories/ # Data access
136
+ │ │ ├── __init__.py
137
+ │ │ └── user_repo.py
138
+ │ └── api/ # HTTP/CLI entry points
139
+ │ ├── __init__.py
140
+ │ └── routes.py
141
+ ├── tests/
142
+ │ ├── conftest.py # Shared fixtures
143
+ │ ├── unit/
144
+ │ │ └── test_user_service.py
145
+ │ ├── integration/
146
+ │ │ └── test_user_repo.py
147
+ │ └── e2e/
148
+ │ └── test_api.py
149
+ ├── pyproject.toml # Single source of truth for project config
150
+ ├── Makefile
151
+ └── .python-version # Pin Python version
152
+ ```
153
+
154
+ ### Layout Rules
155
+
156
+ - Use `src/` layout — it prevents accidental imports of uninstalled code
157
+ - `pyproject.toml` is the single config file — no `setup.py`, no `setup.cfg`, no `requirements.txt` for deps
158
+ - Tests mirror source structure but live outside `src/`
159
+ - One concern per module — don't dump everything in `utils.py`
160
+ - `__init__.py` defines the public API for each package
161
+
162
+ ## Definition of Done
163
+
164
+ A Python feature is complete when:
165
+ - [ ] `mypy --strict` passes with zero errors
166
+ - [ ] `ruff check` passes with zero warnings
167
+ - [ ] `ruff format --check` passes
168
+ - [ ] `pytest` passes with no failures
169
+ - [ ] Test coverage covers meaningful behavior (not just lines)
170
+ - [ ] Error cases are tested, not just happy paths
171
+ - [ ] Docstrings on all public functions and classes
172
+ - [ ] No bare `except:` or `except Exception:` without re-raise
173
+ - [ ] No mutable default arguments
174
+ - [ ] No `# type: ignore` without an inline explanation