@neyugn/agent-kits 0.1.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 (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +514 -0
  3. package/README.vi.md +410 -0
  4. package/README.zh.md +410 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +422 -0
  7. package/kits/coder/ARCHITECTURE.md +289 -0
  8. package/kits/coder/agents/ai-engineer.md +344 -0
  9. package/kits/coder/agents/backend-specialist.md +270 -0
  10. package/kits/coder/agents/cloud-architect.md +363 -0
  11. package/kits/coder/agents/code-reviewer.md +284 -0
  12. package/kits/coder/agents/data-engineer.md +401 -0
  13. package/kits/coder/agents/database-specialist.md +251 -0
  14. package/kits/coder/agents/debugger.md +209 -0
  15. package/kits/coder/agents/devops-engineer.md +281 -0
  16. package/kits/coder/agents/documentation-writer.md +296 -0
  17. package/kits/coder/agents/frontend-specialist.md +298 -0
  18. package/kits/coder/agents/i18n-specialist.md +348 -0
  19. package/kits/coder/agents/integration-specialist.md +314 -0
  20. package/kits/coder/agents/mobile-developer.md +271 -0
  21. package/kits/coder/agents/multi-tenant-architect.md +281 -0
  22. package/kits/coder/agents/orchestrator.md +263 -0
  23. package/kits/coder/agents/performance-analyst.md +327 -0
  24. package/kits/coder/agents/project-planner.md +277 -0
  25. package/kits/coder/agents/queue-specialist.md +282 -0
  26. package/kits/coder/agents/realtime-specialist.md +267 -0
  27. package/kits/coder/agents/security-auditor.md +253 -0
  28. package/kits/coder/agents/test-engineer.md +315 -0
  29. package/kits/coder/agents/ux-researcher.md +388 -0
  30. package/kits/coder/rules/.cursorrules +287 -0
  31. package/kits/coder/rules/CLAUDE.md +287 -0
  32. package/kits/coder/rules/CODEX.md +287 -0
  33. package/kits/coder/rules/GEMINI.md +287 -0
  34. package/kits/coder/scripts/checklist.py +318 -0
  35. package/kits/coder/scripts/kit_status.py +292 -0
  36. package/kits/coder/scripts/skills_manager.py +243 -0
  37. package/kits/coder/scripts/verify_all.py +391 -0
  38. package/kits/coder/skills/accessibility-patterns/SKILL.md +372 -0
  39. package/kits/coder/skills/accessibility-patterns/scripts/a11y_checker.py +211 -0
  40. package/kits/coder/skills/ai-rag-patterns/SKILL.md +444 -0
  41. package/kits/coder/skills/api-patterns/SKILL.md +316 -0
  42. package/kits/coder/skills/api-patterns/assets/.gitkeep +1 -0
  43. package/kits/coder/skills/api-patterns/references/deep-dive.md +21 -0
  44. package/kits/coder/skills/api-patterns/scripts/api_validator.py +253 -0
  45. package/kits/coder/skills/api-patterns/scripts/validate.py +56 -0
  46. package/kits/coder/skills/auth-patterns/SKILL.md +267 -0
  47. package/kits/coder/skills/aws-patterns/SKILL.md +576 -0
  48. package/kits/coder/skills/brainstorming/SKILL.md +370 -0
  49. package/kits/coder/skills/brainstorming/assets/.gitkeep +1 -0
  50. package/kits/coder/skills/brainstorming/references/deep-dive.md +21 -0
  51. package/kits/coder/skills/brainstorming/scripts/validate.py +56 -0
  52. package/kits/coder/skills/clean-code/SKILL.md +240 -0
  53. package/kits/coder/skills/clean-code/assets/.gitkeep +1 -0
  54. package/kits/coder/skills/clean-code/references/deep-dive.md +21 -0
  55. package/kits/coder/skills/clean-code/scripts/lint_runner.py +186 -0
  56. package/kits/coder/skills/clean-code/scripts/validate.py +56 -0
  57. package/kits/coder/skills/database-design/SKILL.md +255 -0
  58. package/kits/coder/skills/database-design/assets/.gitkeep +1 -0
  59. package/kits/coder/skills/database-design/references/deep-dive.md +21 -0
  60. package/kits/coder/skills/database-design/scripts/schema_validator.py +272 -0
  61. package/kits/coder/skills/database-design/scripts/validate.py +56 -0
  62. package/kits/coder/skills/docker-patterns/SKILL.md +240 -0
  63. package/kits/coder/skills/documentation-templates/SKILL.md +441 -0
  64. package/kits/coder/skills/e2e-testing/SKILL.md +457 -0
  65. package/kits/coder/skills/flutter-patterns/SKILL.md +330 -0
  66. package/kits/coder/skills/frontend-design/SKILL.md +127 -0
  67. package/kits/coder/skills/github-actions/SKILL.md +349 -0
  68. package/kits/coder/skills/gitlab-ci-patterns/SKILL.md +466 -0
  69. package/kits/coder/skills/graphql-patterns/SKILL.md +558 -0
  70. package/kits/coder/skills/i18n-localization/SKILL.md +345 -0
  71. package/kits/coder/skills/i18n-localization/scripts/i18n_checker.py +267 -0
  72. package/kits/coder/skills/kubernetes-patterns/SKILL.md +357 -0
  73. package/kits/coder/skills/mermaid-diagrams/SKILL.md +351 -0
  74. package/kits/coder/skills/mobile-design/SKILL.md +305 -0
  75. package/kits/coder/skills/monitoring-observability/SKILL.md +458 -0
  76. package/kits/coder/skills/multi-tenancy/SKILL.md +317 -0
  77. package/kits/coder/skills/multi-tenancy/assets/.gitkeep +1 -0
  78. package/kits/coder/skills/multi-tenancy/references/deep-dive.md +21 -0
  79. package/kits/coder/skills/multi-tenancy/scripts/validate.py +56 -0
  80. package/kits/coder/skills/nodejs-best-practices/SKILL.md +220 -0
  81. package/kits/coder/skills/performance-profiling/SKILL.md +333 -0
  82. package/kits/coder/skills/performance-profiling/assets/.gitkeep +1 -0
  83. package/kits/coder/skills/performance-profiling/references/deep-dive.md +21 -0
  84. package/kits/coder/skills/performance-profiling/scripts/validate.py +56 -0
  85. package/kits/coder/skills/plan-writing/SKILL.md +360 -0
  86. package/kits/coder/skills/plan-writing/assets/.gitkeep +1 -0
  87. package/kits/coder/skills/plan-writing/references/deep-dive.md +21 -0
  88. package/kits/coder/skills/plan-writing/scripts/validate.py +56 -0
  89. package/kits/coder/skills/postgres-patterns/SKILL.md +361 -0
  90. package/kits/coder/skills/prompt-engineering/SKILL.md +277 -0
  91. package/kits/coder/skills/queue-patterns/SKILL.md +359 -0
  92. package/kits/coder/skills/queue-patterns/assets/.gitkeep +1 -0
  93. package/kits/coder/skills/queue-patterns/references/deep-dive.md +21 -0
  94. package/kits/coder/skills/queue-patterns/scripts/validate.py +56 -0
  95. package/kits/coder/skills/react-native-patterns/SKILL.md +393 -0
  96. package/kits/coder/skills/react-patterns/SKILL.md +319 -0
  97. package/kits/coder/skills/realtime-patterns/SKILL.md +506 -0
  98. package/kits/coder/skills/realtime-patterns/assets/.gitkeep +1 -0
  99. package/kits/coder/skills/realtime-patterns/references/deep-dive.md +21 -0
  100. package/kits/coder/skills/realtime-patterns/scripts/validate.py +56 -0
  101. package/kits/coder/skills/redis-patterns/SKILL.md +484 -0
  102. package/kits/coder/skills/security-fundamentals/SKILL.md +363 -0
  103. package/kits/coder/skills/security-fundamentals/assets/.gitkeep +1 -0
  104. package/kits/coder/skills/security-fundamentals/references/deep-dive.md +21 -0
  105. package/kits/coder/skills/security-fundamentals/scripts/security_scan.py +326 -0
  106. package/kits/coder/skills/security-fundamentals/scripts/validate.py +56 -0
  107. package/kits/coder/skills/seo-patterns/SKILL.md +262 -0
  108. package/kits/coder/skills/seo-patterns/scripts/seo_checker.py +211 -0
  109. package/kits/coder/skills/systematic-debugging/SKILL.md +478 -0
  110. package/kits/coder/skills/systematic-debugging/assets/.gitkeep +1 -0
  111. package/kits/coder/skills/systematic-debugging/references/deep-dive.md +21 -0
  112. package/kits/coder/skills/systematic-debugging/scripts/validate.py +56 -0
  113. package/kits/coder/skills/tailwind-patterns/SKILL.md +395 -0
  114. package/kits/coder/skills/terraform-patterns/SKILL.md +470 -0
  115. package/kits/coder/skills/testing-patterns/SKILL.md +285 -0
  116. package/kits/coder/skills/testing-patterns/assets/.gitkeep +1 -0
  117. package/kits/coder/skills/testing-patterns/references/deep-dive.md +21 -0
  118. package/kits/coder/skills/testing-patterns/scripts/test_runner.py +219 -0
  119. package/kits/coder/skills/testing-patterns/scripts/validate.py +56 -0
  120. package/kits/coder/skills/typescript-patterns/SKILL.md +417 -0
  121. package/kits/coder/skills/ui-ux-pro-max/SKILL.md +364 -0
  122. package/kits/coder/skills/ui-ux-pro-max/data/charts.csv +26 -0
  123. package/kits/coder/skills/ui-ux-pro-max/data/colors.csv +97 -0
  124. package/kits/coder/skills/ui-ux-pro-max/data/icons.csv +101 -0
  125. package/kits/coder/skills/ui-ux-pro-max/data/landing.csv +31 -0
  126. package/kits/coder/skills/ui-ux-pro-max/data/products.csv +97 -0
  127. package/kits/coder/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  128. package/kits/coder/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  129. package/kits/coder/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  130. package/kits/coder/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  131. package/kits/coder/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  132. package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  133. package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  134. package/kits/coder/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  135. package/kits/coder/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  136. package/kits/coder/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  137. package/kits/coder/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  138. package/kits/coder/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  139. package/kits/coder/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  140. package/kits/coder/skills/ui-ux-pro-max/data/styles.csv +59 -0
  141. package/kits/coder/skills/ui-ux-pro-max/data/typography.csv +58 -0
  142. package/kits/coder/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  143. package/kits/coder/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  144. package/kits/coder/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  145. package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-314.pyc +0 -0
  146. package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-314.pyc +0 -0
  147. package/kits/coder/skills/ui-ux-pro-max/scripts/core.py +257 -0
  148. package/kits/coder/skills/ui-ux-pro-max/scripts/design_system.py +488 -0
  149. package/kits/coder/skills/ui-ux-pro-max/scripts/search.py +76 -0
  150. package/kits/coder/workflows/.gitkeep +20 -0
  151. package/kits/coder/workflows/create.md +152 -0
  152. package/kits/coder/workflows/debug.md +223 -0
  153. package/kits/coder/workflows/deploy.md +283 -0
  154. package/kits/coder/workflows/orchestrate.md +243 -0
  155. package/kits/coder/workflows/plan.md +134 -0
  156. package/kits/coder/workflows/test.md +237 -0
  157. package/kits/coder/workflows/ui-ux-pro-max.md +109 -0
  158. package/package.json +49 -0
@@ -0,0 +1,285 @@
1
+ ---
2
+ name: testing-patterns
3
+ description: Testing patterns and principles. Unit, integration, mocking strategies. Use when writing tests, reviewing test coverage, or establishing testing conventions.
4
+ allowed-tools: Read, Write, Edit, Glob, Grep, Bash
5
+ version: 2.0
6
+ ---
7
+
8
+ # Testing Patterns - Principles & Best Practices
9
+
10
+ > **Philosophy:** Tests are documentation. Write tests that explain behavior, not implementation.
11
+
12
+ ---
13
+
14
+ ## Test Pyramid
15
+
16
+ ```
17
+ /\ E2E (5-10%)
18
+ / \ Critical user flows
19
+ /----\
20
+ / \ Integration (20-30%)
21
+ /--------\ API, DB, services
22
+ / \
23
+ /------------\ Unit (60-70%)
24
+ Functions, classes, logic
25
+ ```
26
+
27
+ **Rule:** More tests at the base, fewer at the top. Fast, cheap, reliable tests first.
28
+
29
+ ---
30
+
31
+ ## Test Type Selection
32
+
33
+ ```
34
+ What are you testing?
35
+ │
36
+ ā”œā”€ Pure function / business logic?
37
+ │ └─ → Unit test
38
+ │
39
+ ā”œā”€ API endpoint / database query?
40
+ │ └─ → Integration test
41
+ │
42
+ ā”œā”€ Critical user journey?
43
+ │ └─ → E2E test
44
+ │
45
+ ā”œā”€ External service interaction?
46
+ │ └─ → Integration test with mocks
47
+ │
48
+ └─ UI component rendering?
49
+ └─ → Component test (unit-like)
50
+ ```
51
+
52
+ ---
53
+
54
+ ## AAA Pattern (Arrange-Act-Assert)
55
+
56
+ ```typescript
57
+ // āœ… Clear AAA structure
58
+ describe("UserService", () => {
59
+ it("should return user by ID", async () => {
60
+ // Arrange
61
+ const userId = "123";
62
+ const expectedUser = { id: userId, name: "John" };
63
+ mockDb.users.findById.mockResolvedValue(expectedUser);
64
+
65
+ // Act
66
+ const result = await userService.getById(userId);
67
+
68
+ // Assert
69
+ expect(result).toEqual(expectedUser);
70
+ });
71
+ });
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Unit Test Principles (FIRST)
77
+
78
+ | Principle | Meaning | Example |
79
+ | ------------------- | ------------------ | ------------------------ |
80
+ | **F**ast | < 100ms each | No I/O, no network |
81
+ | **I**solated | No dependencies | Mock external calls |
82
+ | **R**epeatable | Same result always | No random, no time |
83
+ | **S**elf-validating | Boolean pass/fail | No manual verification |
84
+ | **T**imely | Written with code | TDD or immediately after |
85
+
86
+ ### What to Unit Test
87
+
88
+ | āœ… Test | āŒ Don't Test |
89
+ | -------------- | ------------------------ |
90
+ | Business logic | Framework code |
91
+ | Edge cases | Third-party libraries |
92
+ | Error handling | Simple getters/setters |
93
+ | Calculations | Constructor-only classes |
94
+ | Validations | Private methods directly |
95
+
96
+ ---
97
+
98
+ ## Integration Test Principles
99
+
100
+ ### What to Integration Test
101
+
102
+ | Area | Focus | Example |
103
+ | ------------ | --------------------- | -------------------- |
104
+ | **API** | Request/Response | Correct status codes |
105
+ | **Database** | Queries, transactions | Data persistence |
106
+ | **Services** | Inter-service calls | Message passing |
107
+ | **Auth** | Token validation | Protected routes |
108
+
109
+ ### Setup/Teardown Pattern
110
+
111
+ ```typescript
112
+ describe("UserAPI", () => {
113
+ beforeAll(async () => {
114
+ // Connect to test database
115
+ await db.connect();
116
+ });
117
+
118
+ beforeEach(async () => {
119
+ // Reset state before each test
120
+ await db.clear();
121
+ await seedTestData();
122
+ });
123
+
124
+ afterEach(async () => {
125
+ // Clean up test artifacts
126
+ await cleanupFiles();
127
+ });
128
+
129
+ afterAll(async () => {
130
+ // Disconnect resources
131
+ await db.disconnect();
132
+ });
133
+ });
134
+ ```
135
+
136
+ ---
137
+
138
+ ## Mocking Strategy
139
+
140
+ ### When to Mock
141
+
142
+ | āœ… Mock | āŒ Don't Mock |
143
+ | ------------------------ | ------------------- |
144
+ | External APIs | Code under test |
145
+ | Database (in unit tests) | Simple dependencies |
146
+ | Time/Date | Pure functions |
147
+ | Network calls | In-memory stores |
148
+ | Third-party services | Internal modules |
149
+
150
+ ### Mock Types
151
+
152
+ | Type | Purpose | Example |
153
+ | -------- | ---------------------------- | ---------------------------- |
154
+ | **Stub** | Return fixed values | `mockFn.mockReturnValue(42)` |
155
+ | **Spy** | Track calls without changing | `jest.spyOn(obj, 'method')` |
156
+ | **Mock** | Replace with expectations | `jest.fn()` |
157
+ | **Fake** | Simplified implementation | In-memory database |
158
+
159
+ ### Mocking Decision Tree
160
+
161
+ ```
162
+ Need to isolate from dependency?
163
+ ā”œā”€ Yes → Is it external (API, DB)?
164
+ │ ā”œā”€ Yes → Mock it
165
+ │ └─ No → Prefer real implementation
166
+ │
167
+ └─ No → Use real dependency
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Test Data Strategies
173
+
174
+ | Strategy | Use Case | Example |
175
+ | ----------- | --------------------- | ----------------------------------------- |
176
+ | **Factory** | Generate varied data | `createUser({ name: 'John' })` |
177
+ | **Fixture** | Predefined datasets | JSON files |
178
+ | **Builder** | Fluent construction | `UserBuilder.default().withRole('admin')` |
179
+ | **Faker** | Random realistic data | `faker.person.fullName()` |
180
+
181
+ ### Factory Pattern Example
182
+
183
+ ```typescript
184
+ // factories/user.factory.ts
185
+ export const createUser = (overrides = {}) => ({
186
+ id: faker.string.uuid(),
187
+ name: faker.person.fullName(),
188
+ email: faker.internet.email(),
189
+ createdAt: new Date(),
190
+ ...overrides,
191
+ });
192
+
193
+ // Usage
194
+ const user = createUser({ role: "admin" });
195
+ ```
196
+
197
+ ---
198
+
199
+ ## TDD Workflow (Red-Green-Refactor)
200
+
201
+ ```
202
+ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
203
+ │ RED │ ──→ │ GREEN │ ──→ │ REFACTOR │
204
+ │ Write │ │ Write │ │ Improve │
205
+ │ failing │ │ minimal │ │ code │
206
+ │ test │ │ code │ │ quality │
207
+ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
208
+ ↑ │
209
+ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
210
+ ```
211
+
212
+ ---
213
+
214
+ ## Test Naming Conventions
215
+
216
+ | Pattern | Example |
217
+ | --------------------------------- | ---------------------------------------- |
218
+ | **should_behavior** | `should returnErrorWhenUserNotFound` |
219
+ | **when_condition** | `whenUserIsNull_throwsError` |
220
+ | **given_when_then** | `givenValidInput_whenSubmit_thenSuccess` |
221
+ | **methodName_condition_expected** | `getUser_withInvalidId_returnsNull` |
222
+
223
+ **Rule:** Test names should describe behavior, not implementation.
224
+
225
+ ---
226
+
227
+ ## Coverage Guidelines
228
+
229
+ | Level | Meaning |
230
+ | -------- | ----------------------------------- |
231
+ | **80%+** | Good coverage for most projects |
232
+ | **90%+** | High coverage, critical systems |
233
+ | **100%** | Often impractical, may waste effort |
234
+
235
+ ### What to Cover
236
+
237
+ | Priority | Area |
238
+ | ---------- | ---------------------------- |
239
+ | **High** | Business logic, calculations |
240
+ | **Medium** | Error paths, edge cases |
241
+ | **Low** | Simple getters, boilerplate |
242
+
243
+ ---
244
+
245
+ ## Anti-Patterns
246
+
247
+ | āŒ Don't | āœ… Do |
248
+ | --------------------------- | -------------------------- |
249
+ | Test implementation details | Test behavior/outcomes |
250
+ | Duplicate test code | Use factories/helpers |
251
+ | Complex test setup | Simplify or split tests |
252
+ | Ignore flaky tests | Fix root cause immediately |
253
+ | Skip cleanup | Reset state every test |
254
+ | Test multiple things | One assertion per test |
255
+ | Hard-code test data | Use factories |
256
+ | Rely on test order | Make tests independent |
257
+
258
+ ---
259
+
260
+ ## Testing Checklist
261
+
262
+ Before pushing code:
263
+
264
+ - [ ] All tests pass?
265
+ - [ ] Coverage meets threshold?
266
+ - [ ] Edge cases covered?
267
+ - [ ] Error paths tested?
268
+ - [ ] Tests are isolated?
269
+ - [ ] No flaky tests?
270
+ - [ ] Test names are descriptive?
271
+
272
+ ---
273
+
274
+ ## Related Skills
275
+
276
+ | Need | Skill |
277
+ | ------------------- | ----------------------- |
278
+ | Clean code | `clean-code` |
279
+ | API testing | `api-patterns` |
280
+ | E2E testing | `webapp-testing` |
281
+ | Performance testing | `performance-profiling` |
282
+
283
+ ---
284
+
285
+ > **Remember:** If you can't understand what code does from its tests, rewrite the tests.
@@ -0,0 +1 @@
1
+ # Assets directory - add templates, images, etc.
@@ -0,0 +1,21 @@
1
+ # Reference Documentation for Testing Patterns
2
+
3
+ [TODO: Add detailed reference content here]
4
+
5
+ ## Overview
6
+
7
+ [Detailed explanation of concepts]
8
+
9
+ ## Deep Dive Topics
10
+
11
+ ### Topic 1
12
+
13
+ [Content]
14
+
15
+ ### Topic 2
16
+
17
+ [Content]
18
+
19
+ ## Examples
20
+
21
+ [Real-world examples]
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test Runner - Unified test execution and coverage
4
+ ==================================================
5
+
6
+ Auto-detects project type and runs appropriate test framework.
7
+
8
+ Usage:
9
+ python .agent/skills/testing-patterns/scripts/test_runner.py <project_path>
10
+ python .agent/skills/testing-patterns/scripts/test_runner.py . --coverage
11
+
12
+ Supports:
13
+ - Node.js: npm test, jest, vitest
14
+ - Python: pytest, unittest
15
+ """
16
+
17
+ import subprocess
18
+ import sys
19
+ import json
20
+ import re
21
+ from pathlib import Path
22
+ from datetime import datetime
23
+
24
+ # Fix console encoding
25
+ try:
26
+ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
27
+ except:
28
+ pass
29
+
30
+
31
+ def detect_test_framework(project_path: Path) -> dict:
32
+ """Detect test framework and commands."""
33
+ result = {
34
+ "type": "unknown",
35
+ "framework": None,
36
+ "cmd": None,
37
+ "coverage_cmd": None
38
+ }
39
+
40
+ # Node.js project
41
+ package_json = project_path / "package.json"
42
+ if package_json.exists():
43
+ result["type"] = "node"
44
+ try:
45
+ pkg = json.loads(package_json.read_text(encoding='utf-8'))
46
+ scripts = pkg.get("scripts", {})
47
+ deps = {**pkg.get("dependencies", {}), **pkg.get("devDependencies", {})}
48
+
49
+ if "test" in scripts:
50
+ result["framework"] = "npm test"
51
+ result["cmd"] = ["npm", "test"]
52
+
53
+ if "vitest" in deps:
54
+ result["framework"] = "vitest"
55
+ result["coverage_cmd"] = ["npx", "vitest", "run", "--coverage"]
56
+ elif "jest" in deps:
57
+ result["framework"] = "jest"
58
+ result["coverage_cmd"] = ["npx", "jest", "--coverage"]
59
+ elif "vitest" in deps:
60
+ result["framework"] = "vitest"
61
+ result["cmd"] = ["npx", "vitest", "run"]
62
+ result["coverage_cmd"] = ["npx", "vitest", "run", "--coverage"]
63
+ elif "jest" in deps:
64
+ result["framework"] = "jest"
65
+ result["cmd"] = ["npx", "jest"]
66
+ result["coverage_cmd"] = ["npx", "jest", "--coverage"]
67
+
68
+ except:
69
+ pass
70
+
71
+ # Python project
72
+ if (project_path / "pyproject.toml").exists() or (project_path / "requirements.txt").exists():
73
+ result["type"] = "python"
74
+ result["framework"] = "pytest"
75
+ result["cmd"] = ["python", "-m", "pytest", "-v"]
76
+ result["coverage_cmd"] = ["python", "-m", "pytest", "--cov", "--cov-report=term-missing"]
77
+
78
+ return result
79
+
80
+
81
+ def run_tests(cmd: list, cwd: Path) -> dict:
82
+ """Run tests and return results."""
83
+ result = {
84
+ "passed": False,
85
+ "output": "",
86
+ "error": "",
87
+ "tests_run": 0,
88
+ "tests_passed": 0,
89
+ "tests_failed": 0
90
+ }
91
+
92
+ try:
93
+ proc = subprocess.run(
94
+ cmd,
95
+ cwd=str(cwd),
96
+ capture_output=True,
97
+ text=True,
98
+ encoding='utf-8',
99
+ errors='replace',
100
+ timeout=300 # 5 min timeout
101
+ )
102
+
103
+ result["output"] = proc.stdout[:3000] if proc.stdout else ""
104
+ result["error"] = proc.stderr[:500] if proc.stderr else ""
105
+ result["passed"] = proc.returncode == 0
106
+
107
+ # Parse test counts
108
+ output = proc.stdout or ""
109
+
110
+ # Jest/Vitest pattern
111
+ if "passed" in output.lower() and "failed" in output.lower():
112
+ match = re.search(r'(\d+)\s+passed', output, re.IGNORECASE)
113
+ if match:
114
+ result["tests_passed"] = int(match.group(1))
115
+ match = re.search(r'(\d+)\s+failed', output, re.IGNORECASE)
116
+ if match:
117
+ result["tests_failed"] = int(match.group(1))
118
+ result["tests_run"] = result["tests_passed"] + result["tests_failed"]
119
+
120
+ # Pytest pattern
121
+ if "pytest" in str(cmd):
122
+ match = re.search(r'(\d+)\s+passed', output)
123
+ if match:
124
+ result["tests_passed"] = int(match.group(1))
125
+ match = re.search(r'(\d+)\s+failed', output)
126
+ if match:
127
+ result["tests_failed"] = int(match.group(1))
128
+ result["tests_run"] = result["tests_passed"] + result["tests_failed"]
129
+
130
+ except FileNotFoundError:
131
+ result["error"] = f"Command not found: {cmd[0]}"
132
+ except subprocess.TimeoutExpired:
133
+ result["error"] = "Timeout after 300s"
134
+ except Exception as e:
135
+ result["error"] = str(e)
136
+
137
+ return result
138
+
139
+
140
+ def main():
141
+ project_path = Path(sys.argv[1] if len(sys.argv) > 1 else ".").resolve()
142
+ with_coverage = "--coverage" in sys.argv
143
+
144
+ print(f"\n{'='*60}")
145
+ print(f"[AGT-KIT TEST RUNNER] Test Execution")
146
+ print(f"{'='*60}")
147
+ print(f"Project: {project_path}")
148
+ print(f"Coverage: {'enabled' if with_coverage else 'disabled'}")
149
+ print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
150
+
151
+ # Detect framework
152
+ test_info = detect_test_framework(project_path)
153
+ print(f"Type: {test_info['type']}")
154
+ print(f"Framework: {test_info['framework']}")
155
+ print("-"*60)
156
+
157
+ if not test_info["cmd"]:
158
+ print("No test framework found.")
159
+ output = {
160
+ "script": "test_runner",
161
+ "skill": "testing-patterns",
162
+ "project": str(project_path),
163
+ "type": test_info["type"],
164
+ "framework": None,
165
+ "passed": True,
166
+ "message": "No tests configured"
167
+ }
168
+ print(json.dumps(output, indent=2))
169
+ sys.exit(0)
170
+
171
+ # Run tests
172
+ cmd = test_info["coverage_cmd"] if with_coverage and test_info["coverage_cmd"] else test_info["cmd"]
173
+ print(f"Running: {' '.join(cmd)}")
174
+ print("-"*60)
175
+
176
+ result = run_tests(cmd, project_path)
177
+
178
+ # Print output
179
+ if result["output"]:
180
+ lines = result["output"].split("\n")
181
+ for line in lines[:30]:
182
+ print(line)
183
+ if len(lines) > 30:
184
+ print(f"... ({len(lines) - 30} more lines)")
185
+
186
+ # Summary
187
+ print("\n" + "="*60)
188
+ print("SUMMARY")
189
+ print("="*60)
190
+
191
+ if result["passed"]:
192
+ print("āœ… All tests passed")
193
+ else:
194
+ print("āŒ Some tests failed")
195
+ if result["error"]:
196
+ print(f"Error: {result['error'][:200]}")
197
+
198
+ if result["tests_run"] > 0:
199
+ print(f"Tests: {result['tests_run']} total, {result['tests_passed']} passed, {result['tests_failed']} failed")
200
+
201
+ output = {
202
+ "script": "test_runner",
203
+ "skill": "testing-patterns",
204
+ "project": str(project_path),
205
+ "type": test_info["type"],
206
+ "framework": test_info["framework"],
207
+ "tests_run": result["tests_run"],
208
+ "tests_passed": result["tests_passed"],
209
+ "tests_failed": result["tests_failed"],
210
+ "passed": result["passed"]
211
+ }
212
+
213
+ print("\n" + json.dumps(output, indent=2))
214
+
215
+ sys.exit(0 if result["passed"] else 1)
216
+
217
+
218
+ if __name__ == "__main__":
219
+ main()
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Example validator for testing-patterns
4
+
5
+ Usage:
6
+ python validate.py <project_path>
7
+ """
8
+
9
+ import sys
10
+ from pathlib import Path
11
+
12
+
13
+ def validate(project_path: str) -> dict:
14
+ """Main validation logic"""
15
+ results = {
16
+ 'errors': [],
17
+ 'warnings': [],
18
+ 'passed': []
19
+ }
20
+
21
+ # TODO: Add validation logic
22
+ results['passed'].append('Placeholder validation passed')
23
+
24
+ return results
25
+
26
+
27
+ def print_results(results: dict):
28
+ """Pretty print results"""
29
+ print("\nšŸ” Validation Results\n")
30
+
31
+ if results['errors']:
32
+ print(f"āŒ Errors ({len(results['errors'])})")
33
+ for error in results['errors']:
34
+ print(f" - {error}")
35
+
36
+ if results['warnings']:
37
+ print(f"\nāš ļø Warnings ({len(results['warnings'])})")
38
+ for warning in results['warnings']:
39
+ print(f" - {warning}")
40
+
41
+ if results['passed']:
42
+ print(f"\nāœ… Passed ({len(results['passed'])})")
43
+ for passed in results['passed']:
44
+ print(f" - {passed}")
45
+
46
+
47
+ if __name__ == "__main__":
48
+ if len(sys.argv) < 2:
49
+ print("Usage: python validate.py <project_path>")
50
+ sys.exit(1)
51
+
52
+ project_path = sys.argv[1]
53
+ results = validate(project_path)
54
+ print_results(results)
55
+
56
+ sys.exit(1 if results['errors'] else 0)