@ranimontagna/agent-toolkit 0.1.7 → 0.1.10

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 (89) hide show
  1. package/README.md +83 -14
  2. package/dist/src/args.js +10 -0
  3. package/dist/src/args.js.map +1 -1
  4. package/dist/src/menu.js +43 -2
  5. package/dist/src/menu.js.map +1 -1
  6. package/dist/src/skills.js +9 -2
  7. package/dist/src/skills.js.map +1 -1
  8. package/dist/src/state.d.ts +2 -0
  9. package/dist/src/state.js +7 -0
  10. package/dist/src/state.js.map +1 -1
  11. package/dist/src/status.js +3 -1
  12. package/dist/src/status.js.map +1 -1
  13. package/dist/src/ui.js +4 -1
  14. package/dist/src/ui.js.map +1 -1
  15. package/dist/src/usage.js +2 -0
  16. package/dist/src/usage.js.map +1 -1
  17. package/docs/assets/install-plan.svg +2 -2
  18. package/docs/assets/install-skill-packages.svg +14 -14
  19. package/package.json +1 -1
  20. package/skills/backend/database/postgres-patterns/LICENSE.ANTIGRAVITY +21 -0
  21. package/skills/backend/database/postgres-patterns/LICENSE.ECC +21 -0
  22. package/skills/backend/database/postgres-patterns/NOTICE.md +11 -0
  23. package/skills/backend/database/postgres-patterns/SKILL.md +180 -0
  24. package/skills/backend/kotlin/kotlin-patterns/LICENSE +21 -0
  25. package/skills/backend/kotlin/kotlin-patterns/NOTICE.md +7 -0
  26. package/skills/backend/kotlin/kotlin-patterns/SKILL.md +711 -0
  27. package/skills/backend/kotlin/kotlin-testing/LICENSE +21 -0
  28. package/skills/backend/kotlin/kotlin-testing/NOTICE.md +7 -0
  29. package/skills/backend/kotlin/kotlin-testing/SKILL.md +824 -0
  30. package/skills/backend/python/python-patterns/LICENSE +21 -0
  31. package/skills/backend/python/python-patterns/NOTICE.md +7 -0
  32. package/skills/backend/python/python-patterns/SKILL.md +424 -0
  33. package/skills/backend/python/python-testing/LICENSE +21 -0
  34. package/skills/backend/python/python-testing/NOTICE.md +7 -0
  35. package/skills/backend/python/python-testing/SKILL.md +494 -0
  36. package/skills/devops/docker-patterns/LICENSE.ANTIGRAVITY +21 -0
  37. package/skills/devops/docker-patterns/LICENSE.ECC +21 -0
  38. package/skills/devops/docker-patterns/NOTICE.md +11 -0
  39. package/skills/devops/docker-patterns/SKILL.md +397 -0
  40. package/skills/frontend/accessibility/LICENSE +21 -0
  41. package/skills/frontend/accessibility/NOTICE.md +10 -0
  42. package/skills/frontend/accessibility/SKILL.md +145 -0
  43. package/skills/frontend/design/ui-ux-pro-max/LICENSE +21 -0
  44. package/skills/frontend/design/ui-ux-pro-max/NOTICE.md +12 -0
  45. package/skills/frontend/design/ui-ux-pro-max/SKILL.md +672 -0
  46. package/skills/frontend/design/ui-ux-pro-max/data/_sync_all.py +414 -0
  47. package/skills/frontend/design/ui-ux-pro-max/data/app-interface.csv +31 -0
  48. package/skills/frontend/design/ui-ux-pro-max/data/charts.csv +26 -0
  49. package/skills/frontend/design/ui-ux-pro-max/data/colors.csv +162 -0
  50. package/skills/frontend/design/ui-ux-pro-max/data/design.csv +1776 -0
  51. package/skills/frontend/design/ui-ux-pro-max/data/draft.csv +1779 -0
  52. package/skills/frontend/design/ui-ux-pro-max/data/google-fonts.csv +1924 -0
  53. package/skills/frontend/design/ui-ux-pro-max/data/icons.csv +106 -0
  54. package/skills/frontend/design/ui-ux-pro-max/data/landing.csv +35 -0
  55. package/skills/frontend/design/ui-ux-pro-max/data/products.csv +162 -0
  56. package/skills/frontend/design/ui-ux-pro-max/data/react-performance.csv +45 -0
  57. package/skills/frontend/design/ui-ux-pro-max/data/stacks/angular.csv +51 -0
  58. package/skills/frontend/design/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  59. package/skills/frontend/design/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  60. package/skills/frontend/design/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  61. package/skills/frontend/design/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  62. package/skills/frontend/design/ui-ux-pro-max/data/stacks/laravel.csv +51 -0
  63. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  64. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  65. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  66. package/skills/frontend/design/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  67. package/skills/frontend/design/ui-ux-pro-max/data/stacks/react.csv +54 -0
  68. package/skills/frontend/design/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  69. package/skills/frontend/design/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  70. package/skills/frontend/design/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  71. package/skills/frontend/design/ui-ux-pro-max/data/stacks/threejs.csv +54 -0
  72. package/skills/frontend/design/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  73. package/skills/frontend/design/ui-ux-pro-max/data/styles.csv +85 -0
  74. package/skills/frontend/design/ui-ux-pro-max/data/typography.csv +74 -0
  75. package/skills/frontend/design/ui-ux-pro-max/data/ui-reasoning.csv +162 -0
  76. package/skills/frontend/design/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  77. package/skills/frontend/design/ui-ux-pro-max/scripts/core.py +262 -0
  78. package/skills/frontend/design/ui-ux-pro-max/scripts/design_system.py +1148 -0
  79. package/skills/frontend/design/ui-ux-pro-max/scripts/search.py +114 -0
  80. package/skills/general/code-reviewer/AGENTS.md +292 -0
  81. package/skills/general/code-reviewer/LICENSE +201 -0
  82. package/skills/general/code-reviewer/NOTICE.md +10 -0
  83. package/skills/general/code-reviewer/SKILL.md +132 -0
  84. package/skills/general/code-reviewer/rules/correctness-error-handling.md +279 -0
  85. package/skills/general/code-reviewer/rules/maintainability-naming.md +149 -0
  86. package/skills/general/code-reviewer/rules/maintainability-type-hints.md +93 -0
  87. package/skills/general/code-reviewer/rules/performance-n-plus-one.md +250 -0
  88. package/skills/general/code-reviewer/rules/security-sql-injection.md +142 -0
  89. package/skills/general/code-reviewer/rules/security-xss-prevention.md +225 -0
@@ -0,0 +1,494 @@
1
+ ---
2
+ name: python-testing
3
+ description: Use when writing or improving Python tests with pytest fixtures, parametrization, mocking, coverage, async tests, and maintainable test organization.
4
+ metadata:
5
+ origin: ECC
6
+ globs: ["**/*.py", "**/*.pyi"]
7
+ ---
8
+
9
+ # Python Testing
10
+
11
+ > This skill provides comprehensive Python testing patterns using pytest as the primary testing framework.
12
+
13
+ ## Testing Framework
14
+
15
+ Use **pytest** as the testing framework for its powerful features and clean syntax.
16
+
17
+ ### Basic Test Structure
18
+
19
+ ```python
20
+ def test_user_creation():
21
+ """Test that a user can be created with valid data"""
22
+ user = User(name="Alice", email="alice@example.com")
23
+
24
+ assert user.name == "Alice"
25
+ assert user.email == "alice@example.com"
26
+ assert user.is_active is True
27
+ ```
28
+
29
+ ### Test Discovery
30
+
31
+ pytest automatically discovers tests following these conventions:
32
+ - Files: `test_*.py` or `*_test.py`
33
+ - Functions: `test_*`
34
+ - Classes: `Test*` (without `__init__`)
35
+ - Methods: `test_*`
36
+
37
+ ## Fixtures
38
+
39
+ Fixtures provide reusable test setup and teardown:
40
+
41
+ ```python
42
+ import pytest
43
+ from sqlalchemy import create_engine
44
+ from sqlalchemy.orm import sessionmaker
45
+
46
+ @pytest.fixture
47
+ def db_session():
48
+ """Provide a database session for tests"""
49
+ engine = create_engine("sqlite:///:memory:")
50
+ Session = sessionmaker(bind=engine)
51
+ session = Session()
52
+
53
+ # Setup
54
+ Base.metadata.create_all(engine)
55
+
56
+ yield session
57
+
58
+ # Teardown
59
+ session.close()
60
+
61
+ def test_user_repository(db_session):
62
+ """Test using the db_session fixture"""
63
+ repo = UserRepository(db_session)
64
+ user = repo.create(name="Alice", email="alice@example.com")
65
+
66
+ assert user.id is not None
67
+ ```
68
+
69
+ ### Fixture Scopes
70
+
71
+ ```python
72
+ @pytest.fixture(scope="function") # Default: per test
73
+ def user():
74
+ return User(name="Alice")
75
+
76
+ @pytest.fixture(scope="class") # Per test class
77
+ def database():
78
+ db = Database()
79
+ db.connect()
80
+ yield db
81
+ db.disconnect()
82
+
83
+ @pytest.fixture(scope="module") # Per module
84
+ def app():
85
+ return create_app()
86
+
87
+ @pytest.fixture(scope="session") # Once per test session
88
+ def config():
89
+ return load_config()
90
+ ```
91
+
92
+ ### Fixture Dependencies
93
+
94
+ ```python
95
+ @pytest.fixture
96
+ def database():
97
+ db = Database()
98
+ db.connect()
99
+ yield db
100
+ db.disconnect()
101
+
102
+ @pytest.fixture
103
+ def user_repository(database):
104
+ """Fixture that depends on database fixture"""
105
+ return UserRepository(database)
106
+
107
+ def test_create_user(user_repository):
108
+ user = user_repository.create(name="Alice")
109
+ assert user.id is not None
110
+ ```
111
+
112
+ ## Parametrization
113
+
114
+ Test multiple inputs with `@pytest.mark.parametrize`:
115
+
116
+ ```python
117
+ import pytest
118
+
119
+ @pytest.mark.parametrize("email,expected", [
120
+ ("user@example.com", True),
121
+ ("invalid-email", False),
122
+ ("", False),
123
+ ("user@", False),
124
+ ("@example.com", False),
125
+ ])
126
+ def test_email_validation(email, expected):
127
+ result = validate_email(email)
128
+ assert result == expected
129
+ ```
130
+
131
+ ### Multiple Parameters
132
+
133
+ ```python
134
+ @pytest.mark.parametrize("name,age,valid", [
135
+ ("Alice", 25, True),
136
+ ("Bob", 17, False),
137
+ ("", 25, False),
138
+ ("Charlie", -1, False),
139
+ ])
140
+ def test_user_validation(name, age, valid):
141
+ result = validate_user(name, age)
142
+ assert result == valid
143
+ ```
144
+
145
+ ### Parametrize with IDs
146
+
147
+ ```python
148
+ @pytest.mark.parametrize("input,expected", [
149
+ ("hello", "HELLO"),
150
+ ("world", "WORLD"),
151
+ ], ids=["lowercase", "another_lowercase"])
152
+ def test_uppercase(input, expected):
153
+ assert input.upper() == expected
154
+ ```
155
+
156
+ ## Test Markers
157
+
158
+ Use markers for test categorization and selective execution:
159
+
160
+ ```python
161
+ import pytest
162
+
163
+ @pytest.mark.unit
164
+ def test_calculate_total():
165
+ """Fast unit test"""
166
+ assert calculate_total([1, 2, 3]) == 6
167
+
168
+ @pytest.mark.integration
169
+ def test_database_connection():
170
+ """Slower integration test"""
171
+ db = Database()
172
+ assert db.connect() is True
173
+
174
+ @pytest.mark.slow
175
+ def test_large_dataset():
176
+ """Very slow test"""
177
+ process_million_records()
178
+
179
+ @pytest.mark.skip(reason="Not implemented yet")
180
+ def test_future_feature():
181
+ pass
182
+
183
+ @pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10+")
184
+ def test_new_syntax():
185
+ pass
186
+ ```
187
+
188
+ **Run specific markers:**
189
+ ```bash
190
+ pytest -m unit # Run only unit tests
191
+ pytest -m "not slow" # Skip slow tests
192
+ pytest -m "unit or integration" # Run unit OR integration
193
+ ```
194
+
195
+ ## Mocking
196
+
197
+ ### Using unittest.mock
198
+
199
+ ```python
200
+ from unittest.mock import Mock, patch, MagicMock
201
+
202
+ def test_user_service_with_mock():
203
+ """Test with mock repository"""
204
+ mock_repo = Mock()
205
+ mock_repo.find_by_id.return_value = User(id="1", name="Alice")
206
+
207
+ service = UserService(mock_repo)
208
+ user = service.get_user("1")
209
+
210
+ assert user.name == "Alice"
211
+ mock_repo.find_by_id.assert_called_once_with("1")
212
+
213
+ @patch('myapp.services.EmailService')
214
+ def test_send_notification(mock_email_service):
215
+ """Test with patched dependency"""
216
+ service = NotificationService()
217
+ service.send("user@example.com", "Hello")
218
+
219
+ mock_email_service.send.assert_called_once()
220
+ ```
221
+
222
+ ### pytest-mock Plugin
223
+
224
+ ```python
225
+ def test_with_mocker(mocker):
226
+ """Using pytest-mock plugin"""
227
+ mock_repo = mocker.Mock()
228
+ mock_repo.find_by_id.return_value = User(id="1", name="Alice")
229
+
230
+ service = UserService(mock_repo)
231
+ user = service.get_user("1")
232
+
233
+ assert user.name == "Alice"
234
+ ```
235
+
236
+ ## Coverage Analysis
237
+
238
+ ### Basic Coverage
239
+
240
+ ```bash
241
+ pytest --cov=src --cov-report=term-missing
242
+ ```
243
+
244
+ ### HTML Coverage Report
245
+
246
+ ```bash
247
+ pytest --cov=src --cov-report=html
248
+ open htmlcov/index.html
249
+ ```
250
+
251
+ ### Coverage Configuration
252
+
253
+ ```ini
254
+ # pytest.ini or pyproject.toml
255
+ [tool.pytest.ini_options]
256
+ addopts = """
257
+ --cov=src
258
+ --cov-report=term-missing
259
+ --cov-report=html
260
+ --cov-fail-under=80
261
+ """
262
+ ```
263
+
264
+ ### Branch Coverage
265
+
266
+ ```bash
267
+ pytest --cov=src --cov-branch
268
+ ```
269
+
270
+ ## Async Testing
271
+
272
+ ### Testing Async Functions
273
+
274
+ ```python
275
+ import pytest
276
+
277
+ @pytest.mark.asyncio
278
+ async def test_async_fetch_user():
279
+ """Test async function"""
280
+ user = await fetch_user("1")
281
+ assert user.name == "Alice"
282
+
283
+ @pytest.fixture
284
+ async def async_client():
285
+ """Async fixture"""
286
+ client = AsyncClient()
287
+ await client.connect()
288
+ yield client
289
+ await client.disconnect()
290
+
291
+ @pytest.mark.asyncio
292
+ async def test_with_async_fixture(async_client):
293
+ result = await async_client.get("/users/1")
294
+ assert result.status == 200
295
+ ```
296
+
297
+ ## Test Organization
298
+
299
+ ### Directory Structure
300
+
301
+ ```
302
+ tests/
303
+ ├── unit/
304
+ │ ├── test_models.py
305
+ │ ├── test_services.py
306
+ │ └── test_utils.py
307
+ ├── integration/
308
+ │ ├── test_database.py
309
+ │ └── test_api.py
310
+ ├── conftest.py # Shared fixtures
311
+ └── pytest.ini # Configuration
312
+ ```
313
+
314
+ ### conftest.py
315
+
316
+ ```python
317
+ # tests/conftest.py
318
+ import pytest
319
+
320
+ @pytest.fixture(scope="session")
321
+ def app():
322
+ """Application fixture available to all tests"""
323
+ return create_app()
324
+
325
+ @pytest.fixture
326
+ def client(app):
327
+ """Test client fixture"""
328
+ return app.test_client()
329
+
330
+ def pytest_configure(config):
331
+ """Register custom markers"""
332
+ config.addinivalue_line("markers", "unit: Unit tests")
333
+ config.addinivalue_line("markers", "integration: Integration tests")
334
+ config.addinivalue_line("markers", "slow: Slow tests")
335
+ ```
336
+
337
+ ## Assertions
338
+
339
+ ### Basic Assertions
340
+
341
+ ```python
342
+ def test_assertions():
343
+ assert value == expected
344
+ assert value != other
345
+ assert value > 0
346
+ assert value in collection
347
+ assert isinstance(value, str)
348
+ ```
349
+
350
+ ### pytest Assertions with Better Error Messages
351
+
352
+ ```python
353
+ def test_with_context():
354
+ """pytest provides detailed assertion introspection"""
355
+ result = calculate_total([1, 2, 3])
356
+ expected = 6
357
+
358
+ # pytest shows: assert 5 == 6
359
+ assert result == expected
360
+ ```
361
+
362
+ ### Custom Assertion Messages
363
+
364
+ ```python
365
+ def test_with_message():
366
+ result = process_data(input_data)
367
+ assert result.is_valid, f"Expected valid result, got errors: {result.errors}"
368
+ ```
369
+
370
+ ### Approximate Comparisons
371
+
372
+ ```python
373
+ import pytest
374
+
375
+ def test_float_comparison():
376
+ result = 0.1 + 0.2
377
+ assert result == pytest.approx(0.3)
378
+
379
+ # With tolerance
380
+ assert result == pytest.approx(0.3, abs=1e-9)
381
+ ```
382
+
383
+ ## Exception Testing
384
+
385
+ ```python
386
+ import pytest
387
+
388
+ def test_raises_exception():
389
+ """Test that function raises expected exception"""
390
+ with pytest.raises(ValueError):
391
+ validate_age(-1)
392
+
393
+ def test_exception_message():
394
+ """Test exception message"""
395
+ with pytest.raises(ValueError, match="Age must be positive"):
396
+ validate_age(-1)
397
+
398
+ def test_exception_details():
399
+ """Capture and inspect exception"""
400
+ with pytest.raises(ValidationError) as exc_info:
401
+ validate_user(name="", age=-1)
402
+
403
+ assert "name" in exc_info.value.errors
404
+ assert "age" in exc_info.value.errors
405
+ ```
406
+
407
+ ## Test Helpers
408
+
409
+ ```python
410
+ # tests/helpers.py
411
+ def assert_user_equal(actual, expected):
412
+ """Custom assertion helper"""
413
+ assert actual.id == expected.id
414
+ assert actual.name == expected.name
415
+ assert actual.email == expected.email
416
+
417
+ def create_test_user(**kwargs):
418
+ """Test data factory"""
419
+ defaults = {
420
+ "name": "Test User",
421
+ "email": "test@example.com",
422
+ "age": 25,
423
+ }
424
+ defaults.update(kwargs)
425
+ return User(**defaults)
426
+ ```
427
+
428
+ ## Property-Based Testing
429
+
430
+ Using `hypothesis` for property-based testing:
431
+
432
+ ```python
433
+ from hypothesis import given, strategies as st
434
+
435
+ @given(st.integers(), st.integers())
436
+ def test_addition_commutative(a, b):
437
+ """Test that addition is commutative"""
438
+ assert a + b == b + a
439
+
440
+ @given(st.lists(st.integers()))
441
+ def test_sort_idempotent(lst):
442
+ """Test that sorting twice gives same result"""
443
+ sorted_once = sorted(lst)
444
+ sorted_twice = sorted(sorted_once)
445
+ assert sorted_once == sorted_twice
446
+ ```
447
+
448
+ ## Best Practices
449
+
450
+ 1. **One assertion per test** (when possible)
451
+ 2. **Use descriptive test names** - describe what's being tested
452
+ 3. **Arrange-Act-Assert pattern** - clear test structure
453
+ 4. **Use fixtures for setup** - avoid duplication
454
+ 5. **Mock external dependencies** - keep tests fast and isolated
455
+ 6. **Test edge cases** - empty inputs, None, boundaries
456
+ 7. **Use parametrize** - test multiple scenarios efficiently
457
+ 8. **Keep tests independent** - no shared state between tests
458
+
459
+ ## Running Tests
460
+
461
+ ```bash
462
+ # Run all tests
463
+ pytest
464
+
465
+ # Run specific file
466
+ pytest tests/test_user.py
467
+
468
+ # Run specific test
469
+ pytest tests/test_user.py::test_create_user
470
+
471
+ # Run with verbose output
472
+ pytest -v
473
+
474
+ # Run with output capture disabled
475
+ pytest -s
476
+
477
+ # Run in parallel (requires pytest-xdist)
478
+ pytest -n auto
479
+
480
+ # Run only failed tests from last run
481
+ pytest --lf
482
+
483
+ # Run failed tests first
484
+ pytest --ff
485
+ ```
486
+
487
+ ## When to Use This Skill
488
+
489
+ - Writing new Python tests
490
+ - Improving test coverage
491
+ - Setting up pytest infrastructure
492
+ - Debugging flaky tests
493
+ - Implementing integration tests
494
+ - Testing async Python code
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Antigravity User
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,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,11 @@
1
+ # Third-party notice
2
+
3
+ This skill is adapted from two MIT-licensed community skills:
4
+
5
+ - ECC docker-patterns: https://github.com/affaan-m/ECC/tree/main/.kiro/skills/docker-patterns
6
+ - ECC source commit: 0f84c0e2796703fbda87d577b2636351418c7442
7
+ - Antigravity docker-expert: https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/docker-expert
8
+ - Antigravity source commit: b806b97a9a48063f7bdbee5611caf40edd17e305
9
+
10
+ The upstream MIT license texts are included in `LICENSE.ECC` and
11
+ `LICENSE.ANTIGRAVITY`.