@oalacea/daemon 0.5.0 → 0.5.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +46 -38
  2. package/LICENSE +23 -23
  3. package/README.md +147 -141
  4. package/agents/deps-analyzer.js +366 -366
  5. package/agents/detector.js +570 -570
  6. package/agents/fix-engine.js +305 -305
  7. package/agents/lighthouse-scanner.js +405 -405
  8. package/agents/perf-analyzer.js +294 -294
  9. package/agents/perf-front-analyzer.js +229 -229
  10. package/agents/test-generator.js +387 -387
  11. package/agents/test-runner.js +318 -318
  12. package/bin/Dockerfile +75 -74
  13. package/bin/cli.js +449 -449
  14. package/lib/config.js +250 -250
  15. package/lib/docker.js +207 -207
  16. package/lib/reporter.js +297 -297
  17. package/package.json +34 -34
  18. package/prompts/DEPS_EFFICIENCY.md +558 -558
  19. package/prompts/E2E.md +491 -491
  20. package/prompts/EXECUTE.md +1060 -1060
  21. package/prompts/INTEGRATION_API.md +484 -484
  22. package/prompts/INTEGRATION_DB.md +425 -425
  23. package/prompts/PERF_API.md +433 -433
  24. package/prompts/PERF_DB.md +430 -430
  25. package/prompts/PERF_FRONT.md +357 -357
  26. package/prompts/REMEDIATION.md +482 -482
  27. package/prompts/UNIT.md +260 -260
  28. package/scripts/dev.js +106 -106
  29. package/templates/README.md +38 -38
  30. package/templates/k6/load-test.js +54 -54
  31. package/templates/playwright/e2e.spec.ts +61 -61
  32. package/templates/vitest/angular-component.test.ts +38 -38
  33. package/templates/vitest/api.test.ts +51 -51
  34. package/templates/vitest/component.test.ts +27 -27
  35. package/templates/vitest/hook.test.ts +36 -36
  36. package/templates/vitest/solid-component.test.ts +34 -34
  37. package/templates/vitest/svelte-component.test.ts +33 -33
  38. package/templates/vitest/vue-component.test.ts +39 -39
package/prompts/UNIT.md CHANGED
@@ -1,260 +1,260 @@
1
- # Unit Test Generation Guide
2
-
3
- This prompt is included by EXECUTE.md. It provides detailed guidance for generating unit tests.
4
-
5
- ---
6
-
7
- ## Component Test Patterns
8
-
9
- ### Presentational Components
10
-
11
- ```typescript
12
- // Button component test
13
- describe('Button', () => {
14
- it('should render with default props', () => {
15
- render(<Button>Click me</Button>);
16
- expect(screen.getByRole('button')).toHaveTextContent('Click me');
17
- });
18
-
19
- it('should apply variant classes', () => {
20
- render(<Button variant="danger">Delete</Button>);
21
- expect(screen.getByRole('button')).toHaveClass('btn-danger');
22
- });
23
-
24
- it('should be disabled when loading', () => {
25
- render(<Button loading>Submit</Button>);
26
- expect(screen.getByRole('button')).toBeDisabled();
27
- expect(screen.getByTestId('spinner')).toBeInTheDocument();
28
- });
29
- });
30
- ```
31
-
32
- ### Container Components
33
-
34
- ```typescript
35
- // UserList component test
36
- describe('UserList', () => {
37
- it('should show loading state', () => {
38
- vi.mocked(useUsers).mockReturnValue({ data: null, loading: true });
39
- render(<UserList />);
40
- expect(screen.getByTestId('skeleton')).toBeInTheDocument();
41
- });
42
-
43
- it('should show error state', () => {
44
- vi.mocked(useUsers).mockReturnValue({
45
- data: null,
46
- loading: false,
47
- error: new Error('Failed to fetch')
48
- });
49
- render(<UserList />);
50
- expect(screen.getByText('Failed to fetch')).toBeInTheDocument();
51
- });
52
-
53
- it('should render users', () => {
54
- vi.mocked(useUsers).mockReturnValue({
55
- data: [{ id: '1', name: 'John' }],
56
- loading: false,
57
- error: null
58
- });
59
- render(<UserList />);
60
- expect(screen.getByText('John')).toBeInTheDocument();
61
- });
62
- });
63
- ```
64
-
65
- ---
66
-
67
- ## Hook Test Patterns
68
-
69
- ```typescript
70
- import { renderHook, act, waitFor } from '@testing-library/react';
71
-
72
- describe('useDebounce', () => {
73
- vi.useFakeTimers();
74
-
75
- it('should debounce value changes', async () => {
76
- const { result } = renderHook(() => useDebounce('test', 500));
77
-
78
- // Immediate value
79
- expect(result.current).toBe('test');
80
-
81
- // Change value immediately
82
- act(() => {
83
- result.current.setValue('test2');
84
- });
85
- expect(result.current.value).toBe('test'); // Not debounced yet
86
-
87
- // Fast-forward
88
- act(() => {
89
- vi.advanceTimersByTime(500);
90
- });
91
- expect(result.current.value).toBe('test2');
92
- });
93
- });
94
- ```
95
-
96
- ---
97
-
98
- ## Utility Function Patterns
99
-
100
- ```typescript
101
- describe('formatCurrency', () => {
102
- it('should format positive numbers', () => {
103
- expect(formatCurrency(1234.56)).toBe('$1,234.56');
104
- });
105
-
106
- it('should format zero', () => {
107
- expect(formatCurrency(0)).toBe('$0.00');
108
- });
109
-
110
- it('should handle negative numbers', () => {
111
- expect(formatCurrency(-100)).toBe('-$100.00');
112
- });
113
-
114
- it('should round to 2 decimal places', () => {
115
- expect(formatCurrency(1.999)).toBe('$2.00');
116
- });
117
- });
118
- ```
119
-
120
- ---
121
-
122
- ## Validator Test Patterns (Zod)
123
-
124
- ```typescript
125
- import { z } from 'zod';
126
- import { userSchema } from './schema';
127
-
128
- describe('userSchema', () => {
129
- const validData = {
130
- email: 'test@example.com',
131
- age: 25,
132
- name: 'John Doe'
133
- };
134
-
135
- it('should accept valid data', () => {
136
- expect(() => userSchema.parse(validData)).not.toThrow();
137
- });
138
-
139
- it('should reject invalid email', () => {
140
- expect(() =>
141
- userSchema.parse({ ...validData, email: 'invalid' })
142
- ).toThrow(z.ZodError);
143
- });
144
-
145
- it('should reject negative age', () => {
146
- expect(() =>
147
- userSchema.parse({ ...validData, age: -1 })
148
- ).toThrow(z.ZodError);
149
- });
150
-
151
- it('should reject missing required fields', () => {
152
- expect(() => userSchema.parse({})).toThrow(z.ZodError);
153
- });
154
- });
155
- ```
156
-
157
- ---
158
-
159
- ## Store Test Patterns (Zustand)
160
-
161
- ```typescript
162
- import { create } from 'zustand';
163
- import { useAuthStore } from './authStore';
164
-
165
- describe('useAuthStore', () => {
166
- beforeEach(() => {
167
- useAuthStore.getState().reset();
168
- });
169
-
170
- it('should set user on login', () => {
171
- const user = { id: '1', name: 'John' };
172
- useAuthStore.getState().login(user);
173
- expect(useAuthStore.getState().user).toEqual(user);
174
- expect(useAuthStore.getState().isAuthenticated).toBe(true);
175
- });
176
-
177
- it('should clear user on logout', () => {
178
- useAuthStore.getState().login({ id: '1', name: 'John' });
179
- useAuthStore.getState().logout();
180
- expect(useAuthStore.getState().user).toBeNull();
181
- expect(useAuthStore.getState().isAuthenticated).toBe(false);
182
- });
183
- });
184
- ```
185
-
186
- ---
187
-
188
- ## Mock Patterns
189
-
190
- ### Mocking React Query
191
-
192
- ```typescript
193
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
194
-
195
- function createTestQueryClient() {
196
- return new QueryClient({
197
- defaultOptions: {
198
- queries: { retry: false },
199
- mutations: { retry: false }
200
- }
201
- });
202
- }
203
-
204
- function Wrapper({ children }) {
205
- return (
206
- <QueryClientProvider client={createTestQueryClient()}>
207
- {children}
208
- </QueryClientProvider>
209
- );
210
- }
211
-
212
- describe('MyComponent', () => {
213
- it('should work with React Query', () => {
214
- render(<MyComponent />, { wrapper: Wrapper });
215
- });
216
- });
217
- ```
218
-
219
- ### Mocking Next.js Router
220
-
221
- ```typescript
222
- import { useRouter } from 'next/navigation';
223
-
224
- vi.mock('next/navigation', () => ({
225
- useRouter: () => ({
226
- push: vi.fn(),
227
- replace: vi.fn(),
228
- prefetch: vi.fn(),
229
- back: vi.fn(),
230
- pathname: '/test'
231
- }),
232
- useSearchParams: () => new URLSearchParams('foo=bar'),
233
- usePathname: () => '/test'
234
- }));
235
- ```
236
-
237
- ### Mocking Fetch
238
-
239
- ```typescript
240
- global.fetch = vi.fn(() =>
241
- Promise.resolve({
242
- ok: true,
243
- json: () => Promise.resolve({ data: 'test' })
244
- })
245
- ) as ReturnType<typeof vi.fn>;
246
-
247
- // Or use MSW for more complex scenarios
248
- import { http, HttpResponse } from 'msw';
249
- import { setupServer } from 'msw/node';
250
-
251
- const server = setupServer(
252
- http.get('/api/users', () => {
253
- return HttpResponse.json({ users: [] });
254
- })
255
- );
256
-
257
- beforeAll(() => server.listen());
258
- afterEach(() => server.resetHandlers());
259
- afterAll(() => server.close());
260
- ```
1
+ # Unit Test Generation Guide
2
+
3
+ This prompt is included by EXECUTE.md. It provides detailed guidance for generating unit tests.
4
+
5
+ ---
6
+
7
+ ## Component Test Patterns
8
+
9
+ ### Presentational Components
10
+
11
+ ```typescript
12
+ // Button component test
13
+ describe('Button', () => {
14
+ it('should render with default props', () => {
15
+ render(<Button>Click me</Button>);
16
+ expect(screen.getByRole('button')).toHaveTextContent('Click me');
17
+ });
18
+
19
+ it('should apply variant classes', () => {
20
+ render(<Button variant="danger">Delete</Button>);
21
+ expect(screen.getByRole('button')).toHaveClass('btn-danger');
22
+ });
23
+
24
+ it('should be disabled when loading', () => {
25
+ render(<Button loading>Submit</Button>);
26
+ expect(screen.getByRole('button')).toBeDisabled();
27
+ expect(screen.getByTestId('spinner')).toBeInTheDocument();
28
+ });
29
+ });
30
+ ```
31
+
32
+ ### Container Components
33
+
34
+ ```typescript
35
+ // UserList component test
36
+ describe('UserList', () => {
37
+ it('should show loading state', () => {
38
+ vi.mocked(useUsers).mockReturnValue({ data: null, loading: true });
39
+ render(<UserList />);
40
+ expect(screen.getByTestId('skeleton')).toBeInTheDocument();
41
+ });
42
+
43
+ it('should show error state', () => {
44
+ vi.mocked(useUsers).mockReturnValue({
45
+ data: null,
46
+ loading: false,
47
+ error: new Error('Failed to fetch')
48
+ });
49
+ render(<UserList />);
50
+ expect(screen.getByText('Failed to fetch')).toBeInTheDocument();
51
+ });
52
+
53
+ it('should render users', () => {
54
+ vi.mocked(useUsers).mockReturnValue({
55
+ data: [{ id: '1', name: 'John' }],
56
+ loading: false,
57
+ error: null
58
+ });
59
+ render(<UserList />);
60
+ expect(screen.getByText('John')).toBeInTheDocument();
61
+ });
62
+ });
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Hook Test Patterns
68
+
69
+ ```typescript
70
+ import { renderHook, act, waitFor } from '@testing-library/react';
71
+
72
+ describe('useDebounce', () => {
73
+ vi.useFakeTimers();
74
+
75
+ it('should debounce value changes', async () => {
76
+ const { result } = renderHook(() => useDebounce('test', 500));
77
+
78
+ // Immediate value
79
+ expect(result.current).toBe('test');
80
+
81
+ // Change value immediately
82
+ act(() => {
83
+ result.current.setValue('test2');
84
+ });
85
+ expect(result.current.value).toBe('test'); // Not debounced yet
86
+
87
+ // Fast-forward
88
+ act(() => {
89
+ vi.advanceTimersByTime(500);
90
+ });
91
+ expect(result.current.value).toBe('test2');
92
+ });
93
+ });
94
+ ```
95
+
96
+ ---
97
+
98
+ ## Utility Function Patterns
99
+
100
+ ```typescript
101
+ describe('formatCurrency', () => {
102
+ it('should format positive numbers', () => {
103
+ expect(formatCurrency(1234.56)).toBe('$1,234.56');
104
+ });
105
+
106
+ it('should format zero', () => {
107
+ expect(formatCurrency(0)).toBe('$0.00');
108
+ });
109
+
110
+ it('should handle negative numbers', () => {
111
+ expect(formatCurrency(-100)).toBe('-$100.00');
112
+ });
113
+
114
+ it('should round to 2 decimal places', () => {
115
+ expect(formatCurrency(1.999)).toBe('$2.00');
116
+ });
117
+ });
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Validator Test Patterns (Zod)
123
+
124
+ ```typescript
125
+ import { z } from 'zod';
126
+ import { userSchema } from './schema';
127
+
128
+ describe('userSchema', () => {
129
+ const validData = {
130
+ email: 'test@example.com',
131
+ age: 25,
132
+ name: 'John Doe'
133
+ };
134
+
135
+ it('should accept valid data', () => {
136
+ expect(() => userSchema.parse(validData)).not.toThrow();
137
+ });
138
+
139
+ it('should reject invalid email', () => {
140
+ expect(() =>
141
+ userSchema.parse({ ...validData, email: 'invalid' })
142
+ ).toThrow(z.ZodError);
143
+ });
144
+
145
+ it('should reject negative age', () => {
146
+ expect(() =>
147
+ userSchema.parse({ ...validData, age: -1 })
148
+ ).toThrow(z.ZodError);
149
+ });
150
+
151
+ it('should reject missing required fields', () => {
152
+ expect(() => userSchema.parse({})).toThrow(z.ZodError);
153
+ });
154
+ });
155
+ ```
156
+
157
+ ---
158
+
159
+ ## Store Test Patterns (Zustand)
160
+
161
+ ```typescript
162
+ import { create } from 'zustand';
163
+ import { useAuthStore } from './authStore';
164
+
165
+ describe('useAuthStore', () => {
166
+ beforeEach(() => {
167
+ useAuthStore.getState().reset();
168
+ });
169
+
170
+ it('should set user on login', () => {
171
+ const user = { id: '1', name: 'John' };
172
+ useAuthStore.getState().login(user);
173
+ expect(useAuthStore.getState().user).toEqual(user);
174
+ expect(useAuthStore.getState().isAuthenticated).toBe(true);
175
+ });
176
+
177
+ it('should clear user on logout', () => {
178
+ useAuthStore.getState().login({ id: '1', name: 'John' });
179
+ useAuthStore.getState().logout();
180
+ expect(useAuthStore.getState().user).toBeNull();
181
+ expect(useAuthStore.getState().isAuthenticated).toBe(false);
182
+ });
183
+ });
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Mock Patterns
189
+
190
+ ### Mocking React Query
191
+
192
+ ```typescript
193
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
194
+
195
+ function createTestQueryClient() {
196
+ return new QueryClient({
197
+ defaultOptions: {
198
+ queries: { retry: false },
199
+ mutations: { retry: false }
200
+ }
201
+ });
202
+ }
203
+
204
+ function Wrapper({ children }) {
205
+ return (
206
+ <QueryClientProvider client={createTestQueryClient()}>
207
+ {children}
208
+ </QueryClientProvider>
209
+ );
210
+ }
211
+
212
+ describe('MyComponent', () => {
213
+ it('should work with React Query', () => {
214
+ render(<MyComponent />, { wrapper: Wrapper });
215
+ });
216
+ });
217
+ ```
218
+
219
+ ### Mocking Next.js Router
220
+
221
+ ```typescript
222
+ import { useRouter } from 'next/navigation';
223
+
224
+ vi.mock('next/navigation', () => ({
225
+ useRouter: () => ({
226
+ push: vi.fn(),
227
+ replace: vi.fn(),
228
+ prefetch: vi.fn(),
229
+ back: vi.fn(),
230
+ pathname: '/test'
231
+ }),
232
+ useSearchParams: () => new URLSearchParams('foo=bar'),
233
+ usePathname: () => '/test'
234
+ }));
235
+ ```
236
+
237
+ ### Mocking Fetch
238
+
239
+ ```typescript
240
+ global.fetch = vi.fn(() =>
241
+ Promise.resolve({
242
+ ok: true,
243
+ json: () => Promise.resolve({ data: 'test' })
244
+ })
245
+ ) as ReturnType<typeof vi.fn>;
246
+
247
+ // Or use MSW for more complex scenarios
248
+ import { http, HttpResponse } from 'msw';
249
+ import { setupServer } from 'msw/node';
250
+
251
+ const server = setupServer(
252
+ http.get('/api/users', () => {
253
+ return HttpResponse.json({ users: [] });
254
+ })
255
+ );
256
+
257
+ beforeAll(() => server.listen());
258
+ afterEach(() => server.resetHandlers());
259
+ afterAll(() => server.close());
260
+ ```