@ranimontagna/agent-toolkit 0.1.6 → 0.1.9

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 (108) hide show
  1. package/README.md +83 -10
  2. package/package.json +1 -1
  3. package/skills/backend/database/postgres-patterns/LICENSE.ANTIGRAVITY +21 -0
  4. package/skills/backend/database/postgres-patterns/LICENSE.ECC +21 -0
  5. package/skills/backend/database/postgres-patterns/NOTICE.md +11 -0
  6. package/skills/backend/database/postgres-patterns/SKILL.md +180 -0
  7. package/skills/backend/go/golang-patterns/LICENSE +21 -0
  8. package/skills/backend/go/golang-patterns/NOTICE.md +10 -0
  9. package/skills/backend/go/golang-patterns/SKILL.md +674 -0
  10. package/skills/backend/go/golang-testing/LICENSE +21 -0
  11. package/skills/backend/go/golang-testing/NOTICE.md +10 -0
  12. package/skills/backend/go/golang-testing/SKILL.md +329 -0
  13. package/skills/backend/java/java-coding-standards/LICENSE +21 -0
  14. package/skills/backend/java/java-coding-standards/NOTICE.md +10 -0
  15. package/skills/backend/java/java-coding-standards/SKILL.md +383 -0
  16. package/skills/backend/java/java-junit/LICENSE +21 -0
  17. package/skills/backend/java/java-junit/NOTICE.md +10 -0
  18. package/skills/backend/java/java-junit/SKILL.md +64 -0
  19. package/skills/backend/kotlin/kotlin-patterns/LICENSE +21 -0
  20. package/skills/backend/kotlin/kotlin-patterns/NOTICE.md +7 -0
  21. package/skills/backend/kotlin/kotlin-patterns/SKILL.md +711 -0
  22. package/skills/backend/kotlin/kotlin-testing/LICENSE +21 -0
  23. package/skills/backend/kotlin/kotlin-testing/NOTICE.md +7 -0
  24. package/skills/backend/kotlin/kotlin-testing/SKILL.md +824 -0
  25. package/skills/backend/python/python-patterns/LICENSE +21 -0
  26. package/skills/backend/python/python-patterns/NOTICE.md +7 -0
  27. package/skills/backend/python/python-patterns/SKILL.md +424 -0
  28. package/skills/backend/python/python-testing/LICENSE +21 -0
  29. package/skills/backend/python/python-testing/NOTICE.md +7 -0
  30. package/skills/backend/python/python-testing/SKILL.md +494 -0
  31. package/skills/devops/docker-patterns/LICENSE.ANTIGRAVITY +21 -0
  32. package/skills/devops/docker-patterns/LICENSE.ECC +21 -0
  33. package/skills/devops/docker-patterns/NOTICE.md +11 -0
  34. package/skills/devops/docker-patterns/SKILL.md +397 -0
  35. package/skills/frontend/accessibility/LICENSE +21 -0
  36. package/skills/frontend/accessibility/NOTICE.md +10 -0
  37. package/skills/frontend/accessibility/SKILL.md +145 -0
  38. package/skills/frontend/design/ui-ux-pro-max/LICENSE +21 -0
  39. package/skills/frontend/design/ui-ux-pro-max/NOTICE.md +12 -0
  40. package/skills/frontend/design/ui-ux-pro-max/SKILL.md +672 -0
  41. package/skills/frontend/design/ui-ux-pro-max/data/_sync_all.py +414 -0
  42. package/skills/frontend/design/ui-ux-pro-max/data/app-interface.csv +31 -0
  43. package/skills/frontend/design/ui-ux-pro-max/data/charts.csv +26 -0
  44. package/skills/frontend/design/ui-ux-pro-max/data/colors.csv +162 -0
  45. package/skills/frontend/design/ui-ux-pro-max/data/design.csv +1776 -0
  46. package/skills/frontend/design/ui-ux-pro-max/data/draft.csv +1779 -0
  47. package/skills/frontend/design/ui-ux-pro-max/data/google-fonts.csv +1924 -0
  48. package/skills/frontend/design/ui-ux-pro-max/data/icons.csv +106 -0
  49. package/skills/frontend/design/ui-ux-pro-max/data/landing.csv +35 -0
  50. package/skills/frontend/design/ui-ux-pro-max/data/products.csv +162 -0
  51. package/skills/frontend/design/ui-ux-pro-max/data/react-performance.csv +45 -0
  52. package/skills/frontend/design/ui-ux-pro-max/data/stacks/angular.csv +51 -0
  53. package/skills/frontend/design/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  54. package/skills/frontend/design/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  55. package/skills/frontend/design/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  56. package/skills/frontend/design/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  57. package/skills/frontend/design/ui-ux-pro-max/data/stacks/laravel.csv +51 -0
  58. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  59. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  60. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  61. package/skills/frontend/design/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  62. package/skills/frontend/design/ui-ux-pro-max/data/stacks/react.csv +54 -0
  63. package/skills/frontend/design/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  64. package/skills/frontend/design/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  65. package/skills/frontend/design/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  66. package/skills/frontend/design/ui-ux-pro-max/data/stacks/threejs.csv +54 -0
  67. package/skills/frontend/design/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  68. package/skills/frontend/design/ui-ux-pro-max/data/styles.csv +85 -0
  69. package/skills/frontend/design/ui-ux-pro-max/data/typography.csv +74 -0
  70. package/skills/frontend/design/ui-ux-pro-max/data/ui-reasoning.csv +162 -0
  71. package/skills/frontend/design/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  72. package/skills/frontend/design/ui-ux-pro-max/scripts/core.py +262 -0
  73. package/skills/frontend/design/ui-ux-pro-max/scripts/design_system.py +1148 -0
  74. package/skills/frontend/design/ui-ux-pro-max/scripts/search.py +114 -0
  75. package/skills/frontend/react/react-patterns/SKILL.md +4 -4
  76. package/skills/frontend/react/react-patterns/rules/react/LICENSE +21 -0
  77. package/skills/frontend/react/react-patterns/rules/react/NOTICE.md +11 -0
  78. package/skills/frontend/react/react-patterns/rules/react/coding-style.md +109 -0
  79. package/skills/frontend/react/react-patterns/rules/react/hooks.md +187 -0
  80. package/skills/frontend/react/react-patterns/rules/react/patterns.md +194 -0
  81. package/skills/frontend/react/react-patterns/rules/react/security.md +180 -0
  82. package/skills/frontend/react/react-patterns/rules/react/testing.md +208 -0
  83. package/skills/frontend/react/react-performance/SKILL.md +2 -2
  84. package/skills/frontend/react/react-performance/rules/react/LICENSE +21 -0
  85. package/skills/frontend/react/react-performance/rules/react/NOTICE.md +11 -0
  86. package/skills/frontend/react/react-performance/rules/react/coding-style.md +109 -0
  87. package/skills/frontend/react/react-performance/rules/react/hooks.md +187 -0
  88. package/skills/frontend/react/react-performance/rules/react/patterns.md +194 -0
  89. package/skills/frontend/react/react-performance/rules/react/security.md +180 -0
  90. package/skills/frontend/react/react-performance/rules/react/testing.md +208 -0
  91. package/skills/frontend/react/react-testing/SKILL.md +4 -4
  92. package/skills/frontend/react/react-testing/rules/react/LICENSE +21 -0
  93. package/skills/frontend/react/react-testing/rules/react/NOTICE.md +11 -0
  94. package/skills/frontend/react/react-testing/rules/react/coding-style.md +109 -0
  95. package/skills/frontend/react/react-testing/rules/react/hooks.md +187 -0
  96. package/skills/frontend/react/react-testing/rules/react/patterns.md +194 -0
  97. package/skills/frontend/react/react-testing/rules/react/security.md +180 -0
  98. package/skills/frontend/react/react-testing/rules/react/testing.md +208 -0
  99. package/skills/general/code-reviewer/AGENTS.md +292 -0
  100. package/skills/general/code-reviewer/LICENSE +201 -0
  101. package/skills/general/code-reviewer/NOTICE.md +10 -0
  102. package/skills/general/code-reviewer/SKILL.md +132 -0
  103. package/skills/general/code-reviewer/rules/correctness-error-handling.md +279 -0
  104. package/skills/general/code-reviewer/rules/maintainability-naming.md +149 -0
  105. package/skills/general/code-reviewer/rules/maintainability-type-hints.md +93 -0
  106. package/skills/general/code-reviewer/rules/performance-n-plus-one.md +250 -0
  107. package/skills/general/code-reviewer/rules/security-sql-injection.md +142 -0
  108. package/skills/general/code-reviewer/rules/security-xss-prevention.md +225 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Affaan Mustafa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ # Attribution
2
+
3
+ This skill is adapted from `affaan-m/ECC`, `.kiro/skills/python-patterns`, commit `0f84c0e2796703fbda87d577b2636351418c7442`.
4
+
5
+ Source: https://github.com/affaan-m/ECC/tree/main/.kiro/skills/python-patterns
6
+
7
+ License: MIT. See `LICENSE`.
@@ -0,0 +1,424 @@
1
+ ---
2
+ name: python-patterns
3
+ description: Use when writing, reviewing, or refactoring Python code with protocols, dataclasses, context managers, decorators, async/await, type hints, and package organization.
4
+ metadata:
5
+ origin: ECC
6
+ globs: ["**/*.py", "**/*.pyi"]
7
+ ---
8
+
9
+ # Python Patterns
10
+
11
+ > This skill provides comprehensive Python patterns extending common design principles with Python-specific idioms.
12
+
13
+ ## Protocol (Duck Typing)
14
+
15
+ Use `Protocol` for structural subtyping (duck typing with type hints):
16
+
17
+ ```python
18
+ from typing import Protocol
19
+
20
+ class Repository(Protocol):
21
+ def find_by_id(self, id: str) -> dict | None: ...
22
+ def save(self, entity: dict) -> dict: ...
23
+
24
+ # Any class with these methods satisfies the protocol
25
+ class UserRepository:
26
+ def find_by_id(self, id: str) -> dict | None:
27
+ # implementation
28
+ pass
29
+
30
+ def save(self, entity: dict) -> dict:
31
+ # implementation
32
+ pass
33
+
34
+ def process_entity(repo: Repository, id: str) -> None:
35
+ entity = repo.find_by_id(id)
36
+ # ... process
37
+ ```
38
+
39
+ **Benefits:**
40
+ - Type safety without inheritance
41
+ - Flexible, loosely coupled code
42
+ - Easy testing and mocking
43
+
44
+ ## Dataclasses as DTOs
45
+
46
+ Use `dataclass` for data transfer objects and value objects:
47
+
48
+ ```python
49
+ from dataclasses import dataclass, field
50
+ from typing import Optional
51
+
52
+ @dataclass
53
+ class CreateUserRequest:
54
+ name: str
55
+ email: str
56
+ age: Optional[int] = None
57
+ tags: list[str] = field(default_factory=list)
58
+
59
+ @dataclass(frozen=True)
60
+ class User:
61
+ """Immutable user entity"""
62
+ id: str
63
+ name: str
64
+ email: str
65
+ ```
66
+
67
+ **Features:**
68
+ - Auto-generated `__init__`, `__repr__`, `__eq__`
69
+ - `frozen=True` for immutability
70
+ - `field()` for complex defaults
71
+ - Type hints for validation
72
+
73
+ ## Context Managers
74
+
75
+ Use context managers (`with` statement) for resource management:
76
+
77
+ ```python
78
+ from contextlib import contextmanager
79
+ from typing import Generator
80
+
81
+ @contextmanager
82
+ def database_transaction(db) -> Generator[None, None, None]:
83
+ """Context manager for database transactions"""
84
+ try:
85
+ yield
86
+ db.commit()
87
+ except Exception:
88
+ db.rollback()
89
+ raise
90
+
91
+ # Usage
92
+ with database_transaction(db):
93
+ db.execute("INSERT INTO users ...")
94
+ ```
95
+
96
+ **Class-based context manager:**
97
+
98
+ ```python
99
+ class FileProcessor:
100
+ def __init__(self, filename: str):
101
+ self.filename = filename
102
+ self.file = None
103
+
104
+ def __enter__(self):
105
+ self.file = open(self.filename, 'r')
106
+ return self.file
107
+
108
+ def __exit__(self, exc_type, exc_val, exc_tb):
109
+ if self.file:
110
+ self.file.close()
111
+ return False # Don't suppress exceptions
112
+ ```
113
+
114
+ ## Generators
115
+
116
+ Use generators for lazy evaluation and memory-efficient iteration:
117
+
118
+ ```python
119
+ def read_large_file(filename: str):
120
+ """Generator for reading large files line by line"""
121
+ with open(filename, 'r') as f:
122
+ for line in f:
123
+ yield line.strip()
124
+
125
+ # Memory-efficient processing
126
+ for line in read_large_file('huge.txt'):
127
+ process(line)
128
+ ```
129
+
130
+ **Generator expressions:**
131
+
132
+ ```python
133
+ # Instead of list comprehension
134
+ squares = (x**2 for x in range(1000000)) # Lazy evaluation
135
+
136
+ # Pipeline pattern
137
+ numbers = (x for x in range(100))
138
+ evens = (x for x in numbers if x % 2 == 0)
139
+ squares = (x**2 for x in evens)
140
+ ```
141
+
142
+ ## Decorators
143
+
144
+ ### Function Decorators
145
+
146
+ ```python
147
+ from functools import wraps
148
+ import time
149
+
150
+ def timing(func):
151
+ """Decorator to measure execution time"""
152
+ @wraps(func)
153
+ def wrapper(*args, **kwargs):
154
+ start = time.time()
155
+ result = func(*args, **kwargs)
156
+ end = time.time()
157
+ print(f"{func.__name__} took {end - start:.2f}s")
158
+ return result
159
+ return wrapper
160
+
161
+ @timing
162
+ def slow_function():
163
+ time.sleep(1)
164
+ ```
165
+
166
+ ### Class Decorators
167
+
168
+ ```python
169
+ def singleton(cls):
170
+ """Decorator to make a class a singleton"""
171
+ instances = {}
172
+
173
+ @wraps(cls)
174
+ def get_instance(*args, **kwargs):
175
+ if cls not in instances:
176
+ instances[cls] = cls(*args, **kwargs)
177
+ return instances[cls]
178
+
179
+ return get_instance
180
+
181
+ @singleton
182
+ class Config:
183
+ pass
184
+ ```
185
+
186
+ ## Async/Await
187
+
188
+ ### Async Functions
189
+
190
+ ```python
191
+ import asyncio
192
+ from typing import List
193
+
194
+ async def fetch_user(user_id: str) -> dict:
195
+ """Async function for I/O-bound operations"""
196
+ await asyncio.sleep(0.1) # Simulate network call
197
+ return {"id": user_id, "name": "Alice"}
198
+
199
+ async def fetch_all_users(user_ids: List[str]) -> List[dict]:
200
+ """Concurrent execution with asyncio.gather"""
201
+ tasks = [fetch_user(uid) for uid in user_ids]
202
+ return await asyncio.gather(*tasks)
203
+
204
+ # Run async code
205
+ asyncio.run(fetch_all_users(["1", "2", "3"]))
206
+ ```
207
+
208
+ ### Async Context Managers
209
+
210
+ ```python
211
+ class AsyncDatabase:
212
+ async def __aenter__(self):
213
+ await self.connect()
214
+ return self
215
+
216
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
217
+ await self.disconnect()
218
+
219
+ async with AsyncDatabase() as db:
220
+ await db.query("SELECT * FROM users")
221
+ ```
222
+
223
+ ## Type Hints
224
+
225
+ ### Advanced Type Hints
226
+
227
+ ```python
228
+ from typing import TypeVar, Generic, Callable, ParamSpec, Concatenate
229
+
230
+ T = TypeVar('T')
231
+ P = ParamSpec('P')
232
+
233
+ class Repository(Generic[T]):
234
+ """Generic repository pattern"""
235
+ def __init__(self, entity_type: type[T]):
236
+ self.entity_type = entity_type
237
+
238
+ def find_by_id(self, id: str) -> T | None:
239
+ # implementation
240
+ pass
241
+
242
+ # Type-safe decorator
243
+ def log_call(func: Callable[P, T]) -> Callable[P, T]:
244
+ @wraps(func)
245
+ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
246
+ print(f"Calling {func.__name__}")
247
+ return func(*args, **kwargs)
248
+ return wrapper
249
+ ```
250
+
251
+ ### Union Types (Python 3.10+)
252
+
253
+ ```python
254
+ def process(value: str | int | None) -> str:
255
+ match value:
256
+ case str():
257
+ return value.upper()
258
+ case int():
259
+ return str(value)
260
+ case None:
261
+ return "empty"
262
+ ```
263
+
264
+ ## Dependency Injection
265
+
266
+ ### Constructor Injection
267
+
268
+ ```python
269
+ class UserService:
270
+ def __init__(
271
+ self,
272
+ repository: Repository,
273
+ logger: Logger,
274
+ cache: Cache | None = None
275
+ ):
276
+ self.repository = repository
277
+ self.logger = logger
278
+ self.cache = cache
279
+
280
+ def get_user(self, user_id: str) -> User | None:
281
+ if self.cache:
282
+ cached = self.cache.get(user_id)
283
+ if cached:
284
+ return cached
285
+
286
+ user = self.repository.find_by_id(user_id)
287
+ if user and self.cache:
288
+ self.cache.set(user_id, user)
289
+
290
+ return user
291
+ ```
292
+
293
+ ## Package Organization
294
+
295
+ ### Project Structure
296
+
297
+ ```
298
+ project/
299
+ ├── src/
300
+ │ └── mypackage/
301
+ │ ├── __init__.py
302
+ │ ├── domain/ # Business logic
303
+ │ │ ├── __init__.py
304
+ │ │ └── models.py
305
+ │ ├── services/ # Application services
306
+ │ │ ├── __init__.py
307
+ │ │ └── user_service.py
308
+ │ └── infrastructure/ # External dependencies
309
+ │ ├── __init__.py
310
+ │ └── database.py
311
+ ├── tests/
312
+ │ ├── unit/
313
+ │ └── integration/
314
+ ├── pyproject.toml
315
+ └── README.md
316
+ ```
317
+
318
+ ### Module Exports
319
+
320
+ ```python
321
+ # __init__.py
322
+ from .models import User, Product
323
+ from .services import UserService
324
+
325
+ __all__ = ['User', 'Product', 'UserService']
326
+ ```
327
+
328
+ ## Error Handling
329
+
330
+ ### Custom Exceptions
331
+
332
+ ```python
333
+ class DomainError(Exception):
334
+ """Base exception for domain errors"""
335
+ pass
336
+
337
+ class UserNotFoundError(DomainError):
338
+ """Raised when user is not found"""
339
+ def __init__(self, user_id: str):
340
+ self.user_id = user_id
341
+ super().__init__(f"User {user_id} not found")
342
+
343
+ class ValidationError(DomainError):
344
+ """Raised when validation fails"""
345
+ def __init__(self, field: str, message: str):
346
+ self.field = field
347
+ self.message = message
348
+ super().__init__(f"{field}: {message}")
349
+ ```
350
+
351
+ ### Exception Groups (Python 3.11+)
352
+
353
+ ```python
354
+ try:
355
+ # Multiple operations
356
+ pass
357
+ except* ValueError as eg:
358
+ # Handle all ValueError instances
359
+ for exc in eg.exceptions:
360
+ print(f"ValueError: {exc}")
361
+ except* TypeError as eg:
362
+ # Handle all TypeError instances
363
+ for exc in eg.exceptions:
364
+ print(f"TypeError: {exc}")
365
+ ```
366
+
367
+ ## Property Decorators
368
+
369
+ ```python
370
+ class User:
371
+ def __init__(self, name: str):
372
+ self._name = name
373
+ self._email = None
374
+
375
+ @property
376
+ def name(self) -> str:
377
+ """Read-only property"""
378
+ return self._name
379
+
380
+ @property
381
+ def email(self) -> str | None:
382
+ return self._email
383
+
384
+ @email.setter
385
+ def email(self, value: str) -> None:
386
+ if '@' not in value:
387
+ raise ValueError("Invalid email")
388
+ self._email = value
389
+ ```
390
+
391
+ ## Functional Programming
392
+
393
+ ### Higher-Order Functions
394
+
395
+ ```python
396
+ from functools import reduce
397
+ from typing import Callable, TypeVar
398
+
399
+ T = TypeVar('T')
400
+ U = TypeVar('U')
401
+
402
+ def pipe(*functions: Callable) -> Callable:
403
+ """Compose functions left to right"""
404
+ def inner(arg):
405
+ return reduce(lambda x, f: f(x), functions, arg)
406
+ return inner
407
+
408
+ # Usage
409
+ process = pipe(
410
+ str.strip,
411
+ str.lower,
412
+ lambda s: s.replace(' ', '_')
413
+ )
414
+ result = process(" Hello World ") # "hello_world"
415
+ ```
416
+
417
+ ## When to Use This Skill
418
+
419
+ - Designing Python APIs and packages
420
+ - Implementing async/concurrent systems
421
+ - Structuring Python projects
422
+ - Writing Pythonic code
423
+ - Refactoring Python codebases
424
+ - Type-safe Python development
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Affaan Mustafa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ # Attribution
2
+
3
+ This skill is adapted from `affaan-m/ECC`, `.kiro/skills/python-testing`, commit `0f84c0e2796703fbda87d577b2636351418c7442`.
4
+
5
+ Source: https://github.com/affaan-m/ECC/tree/main/.kiro/skills/python-testing
6
+
7
+ License: MIT. See `LICENSE`.