digiqagent 1.2.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 (33) hide show
  1. package/.cursor-plugin/plugin.json +29 -0
  2. package/README.md +197 -0
  3. package/agents/code-reviewer.md +48 -0
  4. package/bin/cli.js +210 -0
  5. package/package.json +41 -0
  6. package/skills/playwright-test-generator/SKILL.md +563 -0
  7. package/skills/playwright-test-generator/interaction-test-patterns.md +987 -0
  8. package/skills/playwright-test-generator/page-object-patterns.md +833 -0
  9. package/skills/postman-collection-generator/SKILL.md +310 -0
  10. package/skills/postman-collection-generator/collection-patterns.md +493 -0
  11. package/skills/postman-test-suite-generator/SKILL.md +653 -0
  12. package/skills/postman-test-suite-generator/test-scenario-patterns.md +612 -0
  13. package/skills/receiving-code-review/SKILL.md +213 -0
  14. package/skills/requesting-code-review/SKILL.md +105 -0
  15. package/skills/requesting-code-review/code-reviewer.md +146 -0
  16. package/skills/review-prompts/code-quality-reviewer-prompt.md +26 -0
  17. package/skills/review-prompts/spec-reviewer-prompt.md +61 -0
  18. package/skills/swagger-generator/SKILL.md +238 -0
  19. package/skills/swagger-generator/openapi-patterns.md +667 -0
  20. package/skills/systematic-debugging/CREATION-LOG.md +119 -0
  21. package/skills/systematic-debugging/SKILL.md +296 -0
  22. package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  23. package/skills/systematic-debugging/condition-based-waiting.md +115 -0
  24. package/skills/systematic-debugging/defense-in-depth.md +122 -0
  25. package/skills/systematic-debugging/find-polluter.sh +63 -0
  26. package/skills/systematic-debugging/root-cause-tracing.md +169 -0
  27. package/skills/systematic-debugging/test-academic.md +14 -0
  28. package/skills/systematic-debugging/test-pressure-1.md +58 -0
  29. package/skills/systematic-debugging/test-pressure-2.md +68 -0
  30. package/skills/systematic-debugging/test-pressure-3.md +69 -0
  31. package/skills/test-driven-development/SKILL.md +371 -0
  32. package/skills/test-driven-development/testing-anti-patterns.md +299 -0
  33. package/skills/verification-before-completion/SKILL.md +139 -0
@@ -0,0 +1,493 @@
1
+ # Postman Collection Patterns
2
+
3
+ Reference patterns for structuring Postman collections. Copy and adapt when generating collections.
4
+
5
+ ## Auth Flow — Login, Store Token, Use in Requests
6
+
7
+ A complete authentication flow with token capture and reuse.
8
+
9
+ ### Login Request
10
+
11
+ ```json
12
+ {
13
+ "name": "Login",
14
+ "event": [
15
+ {
16
+ "listen": "test",
17
+ "script": {
18
+ "type": "text/javascript",
19
+ "exec": [
20
+ "if (pm.response.code === 200) {",
21
+ " const response = pm.response.json();",
22
+ " pm.environment.set('authToken', response.accessToken || response.token);",
23
+ " if (response.refreshToken) {",
24
+ " pm.environment.set('refreshToken', response.refreshToken);",
25
+ " }",
26
+ " if (response.user) {",
27
+ " pm.environment.set('userId', response.user.id);",
28
+ " pm.environment.set('userEmail', response.user.email);",
29
+ " }",
30
+ " // Store expiry for auto-refresh logic",
31
+ " if (response.expiresIn) {",
32
+ " pm.environment.set('tokenExpiry', Date.now() + (response.expiresIn * 1000));",
33
+ " }",
34
+ "}"
35
+ ]
36
+ }
37
+ }
38
+ ],
39
+ "request": {
40
+ "method": "POST",
41
+ "header": [
42
+ { "key": "Content-Type", "value": "application/json" }
43
+ ],
44
+ "url": {
45
+ "raw": "{{baseUrl}}/api/auth/login",
46
+ "host": ["{{baseUrl}}"],
47
+ "path": ["api", "auth", "login"]
48
+ },
49
+ "body": {
50
+ "mode": "raw",
51
+ "raw": "{\n \"email\": \"admin@example.com\",\n \"password\": \"SecureP@ss123\"\n}"
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ ### Register Request
58
+
59
+ ```json
60
+ {
61
+ "name": "Register",
62
+ "event": [
63
+ {
64
+ "listen": "test",
65
+ "script": {
66
+ "type": "text/javascript",
67
+ "exec": [
68
+ "if (pm.response.code === 201) {",
69
+ " const response = pm.response.json();",
70
+ " pm.environment.set('newUserId', response.id || response.user?.id);",
71
+ "}"
72
+ ]
73
+ }
74
+ }
75
+ ],
76
+ "request": {
77
+ "method": "POST",
78
+ "header": [
79
+ { "key": "Content-Type", "value": "application/json" }
80
+ ],
81
+ "url": {
82
+ "raw": "{{baseUrl}}/api/auth/register",
83
+ "host": ["{{baseUrl}}"],
84
+ "path": ["api", "auth", "register"]
85
+ },
86
+ "body": {
87
+ "mode": "raw",
88
+ "raw": "{\n \"name\": \"Jane Smith\",\n \"email\": \"jane.smith@example.com\",\n \"password\": \"SecureP@ss123\"\n}"
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ ### Refresh Token Request
95
+
96
+ ```json
97
+ {
98
+ "name": "Refresh Token",
99
+ "event": [
100
+ {
101
+ "listen": "test",
102
+ "script": {
103
+ "type": "text/javascript",
104
+ "exec": [
105
+ "if (pm.response.code === 200) {",
106
+ " const response = pm.response.json();",
107
+ " pm.environment.set('authToken', response.accessToken || response.token);",
108
+ " if (response.refreshToken) {",
109
+ " pm.environment.set('refreshToken', response.refreshToken);",
110
+ " }",
111
+ "}"
112
+ ]
113
+ }
114
+ }
115
+ ],
116
+ "request": {
117
+ "method": "POST",
118
+ "header": [
119
+ { "key": "Content-Type", "value": "application/json" }
120
+ ],
121
+ "url": {
122
+ "raw": "{{baseUrl}}/api/auth/refresh",
123
+ "host": ["{{baseUrl}}"],
124
+ "path": ["api", "auth", "refresh"]
125
+ },
126
+ "body": {
127
+ "mode": "raw",
128
+ "raw": "{\n \"refreshToken\": \"{{refreshToken}}\"\n}"
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ ## CRUD Operation Ordering
135
+
136
+ Follow this sequence within each resource folder for a natural workflow:
137
+
138
+ ```
139
+ 1. POST /api/resources → Create resource (capture ID)
140
+ 2. GET /api/resources → List resources (verify created item appears)
141
+ 3. GET /api/resources/:id → Get by ID (verify details)
142
+ 4. PUT /api/resources/:id → Update resource
143
+ 5. GET /api/resources/:id → Get by ID (verify update applied)
144
+ 6. DELETE /api/resources/:id → Delete resource
145
+ 7. GET /api/resources/:id → Get by ID (verify 404)
146
+ ```
147
+
148
+ ### Create Request with ID Capture
149
+
150
+ ```json
151
+ {
152
+ "name": "Create Product",
153
+ "event": [
154
+ {
155
+ "listen": "test",
156
+ "script": {
157
+ "type": "text/javascript",
158
+ "exec": [
159
+ "if (pm.response.code === 201) {",
160
+ " const response = pm.response.json();",
161
+ " const id = response.id || response.data?.id;",
162
+ " pm.environment.set('productId', id);",
163
+ " console.log('Created product with ID:', id);",
164
+ "}"
165
+ ]
166
+ }
167
+ }
168
+ ],
169
+ "request": {
170
+ "method": "POST",
171
+ "header": [
172
+ { "key": "Content-Type", "value": "application/json" },
173
+ { "key": "Authorization", "value": "Bearer {{authToken}}" }
174
+ ],
175
+ "url": {
176
+ "raw": "{{baseUrl}}/api/products",
177
+ "host": ["{{baseUrl}}"],
178
+ "path": ["api", "products"]
179
+ },
180
+ "body": {
181
+ "mode": "raw",
182
+ "raw": "{\n \"name\": \"Wireless Bluetooth Headphones\",\n \"description\": \"Premium noise-cancelling headphones with 30-hour battery\",\n \"price\": 149.99,\n \"category\": \"electronics\",\n \"sku\": \"WBH-2025-001\"\n}"
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
188
+ ### Get by ID Using Captured Variable
189
+
190
+ ```json
191
+ {
192
+ "name": "Get Product by ID",
193
+ "request": {
194
+ "method": "GET",
195
+ "header": [
196
+ { "key": "Authorization", "value": "Bearer {{authToken}}" }
197
+ ],
198
+ "url": {
199
+ "raw": "{{baseUrl}}/api/products/{{productId}}",
200
+ "host": ["{{baseUrl}}"],
201
+ "path": ["api", "products", "{{productId}}"]
202
+ }
203
+ }
204
+ }
205
+ ```
206
+
207
+ ### Update Request
208
+
209
+ ```json
210
+ {
211
+ "name": "Update Product",
212
+ "request": {
213
+ "method": "PUT",
214
+ "header": [
215
+ { "key": "Content-Type", "value": "application/json" },
216
+ { "key": "Authorization", "value": "Bearer {{authToken}}" }
217
+ ],
218
+ "url": {
219
+ "raw": "{{baseUrl}}/api/products/{{productId}}",
220
+ "host": ["{{baseUrl}}"],
221
+ "path": ["api", "products", "{{productId}}"]
222
+ },
223
+ "body": {
224
+ "mode": "raw",
225
+ "raw": "{\n \"name\": \"Wireless Bluetooth Headphones Pro\",\n \"price\": 179.99\n}"
226
+ }
227
+ }
228
+ }
229
+ ```
230
+
231
+ ### Delete Request
232
+
233
+ ```json
234
+ {
235
+ "name": "Delete Product",
236
+ "request": {
237
+ "method": "DELETE",
238
+ "header": [
239
+ { "key": "Authorization", "value": "Bearer {{authToken}}" }
240
+ ],
241
+ "url": {
242
+ "raw": "{{baseUrl}}/api/products/{{productId}}",
243
+ "host": ["{{baseUrl}}"],
244
+ "path": ["api", "products", "{{productId}}"]
245
+ }
246
+ }
247
+ }
248
+ ```
249
+
250
+ ## Chained Request Patterns
251
+
252
+ When one request depends on another's output, chain them with environment variables.
253
+
254
+ ### Pattern: Create Parent -> Create Child -> List Children
255
+
256
+ ```
257
+ 1. POST /api/projects → capture {{projectId}}
258
+ 2. POST /api/projects/:id/tasks → capture {{taskId}}, uses {{projectId}}
259
+ 3. GET /api/projects/:id/tasks → list tasks, uses {{projectId}}
260
+ ```
261
+
262
+ **Create child with parent reference:**
263
+ ```json
264
+ {
265
+ "name": "Create Task for Project",
266
+ "event": [
267
+ {
268
+ "listen": "test",
269
+ "script": {
270
+ "type": "text/javascript",
271
+ "exec": [
272
+ "if (pm.response.code === 201) {",
273
+ " pm.environment.set('taskId', pm.response.json().id);",
274
+ "}"
275
+ ]
276
+ }
277
+ }
278
+ ],
279
+ "request": {
280
+ "method": "POST",
281
+ "header": [
282
+ { "key": "Content-Type", "value": "application/json" },
283
+ { "key": "Authorization", "value": "Bearer {{authToken}}" }
284
+ ],
285
+ "url": {
286
+ "raw": "{{baseUrl}}/api/projects/{{projectId}}/tasks",
287
+ "host": ["{{baseUrl}}"],
288
+ "path": ["api", "projects", "{{projectId}}", "tasks"]
289
+ },
290
+ "body": {
291
+ "mode": "raw",
292
+ "raw": "{\n \"title\": \"Implement user authentication\",\n \"priority\": \"high\",\n \"assigneeId\": \"{{userId}}\"\n}"
293
+ }
294
+ }
295
+ }
296
+ ```
297
+
298
+ ### Pattern: Dynamic Pre-Request Data Generation
299
+
300
+ ```json
301
+ {
302
+ "name": "Create User with Unique Email",
303
+ "event": [
304
+ {
305
+ "listen": "prerequest",
306
+ "script": {
307
+ "type": "text/javascript",
308
+ "exec": [
309
+ "const timestamp = Date.now();",
310
+ "pm.environment.set('uniqueEmail', `user_${timestamp}@example.com`);",
311
+ "pm.environment.set('uniqueName', `TestUser_${timestamp}`);"
312
+ ]
313
+ }
314
+ },
315
+ {
316
+ "listen": "test",
317
+ "script": {
318
+ "type": "text/javascript",
319
+ "exec": [
320
+ "if (pm.response.code === 201) {",
321
+ " pm.environment.set('createdUserId', pm.response.json().id);",
322
+ "}"
323
+ ]
324
+ }
325
+ }
326
+ ],
327
+ "request": {
328
+ "method": "POST",
329
+ "header": [
330
+ { "key": "Content-Type", "value": "application/json" }
331
+ ],
332
+ "url": {
333
+ "raw": "{{baseUrl}}/api/users",
334
+ "host": ["{{baseUrl}}"],
335
+ "path": ["api", "users"]
336
+ },
337
+ "body": {
338
+ "mode": "raw",
339
+ "raw": "{\n \"name\": \"{{uniqueName}}\",\n \"email\": \"{{uniqueEmail}}\",\n \"password\": \"SecureP@ss123\"\n}"
340
+ }
341
+ }
342
+ }
343
+ ```
344
+
345
+ ## File Upload Request
346
+
347
+ ### Single File Upload
348
+
349
+ ```json
350
+ {
351
+ "name": "Upload Avatar",
352
+ "request": {
353
+ "method": "POST",
354
+ "header": [
355
+ { "key": "Authorization", "value": "Bearer {{authToken}}" }
356
+ ],
357
+ "url": {
358
+ "raw": "{{baseUrl}}/api/users/{{userId}}/avatar",
359
+ "host": ["{{baseUrl}}"],
360
+ "path": ["api", "users", "{{userId}}", "avatar"]
361
+ },
362
+ "body": {
363
+ "mode": "formdata",
364
+ "formdata": [
365
+ {
366
+ "key": "file",
367
+ "type": "file",
368
+ "src": "/path/to/avatar.png",
369
+ "description": "User avatar image (PNG or JPEG, max 5MB)"
370
+ },
371
+ {
372
+ "key": "description",
373
+ "value": "Profile avatar",
374
+ "type": "text"
375
+ }
376
+ ]
377
+ }
378
+ }
379
+ }
380
+ ```
381
+
382
+ ### Multiple File Upload
383
+
384
+ ```json
385
+ {
386
+ "name": "Upload Attachments",
387
+ "request": {
388
+ "method": "POST",
389
+ "header": [
390
+ { "key": "Authorization", "value": "Bearer {{authToken}}" }
391
+ ],
392
+ "url": {
393
+ "raw": "{{baseUrl}}/api/documents/upload",
394
+ "host": ["{{baseUrl}}"],
395
+ "path": ["api", "documents", "upload"]
396
+ },
397
+ "body": {
398
+ "mode": "formdata",
399
+ "formdata": [
400
+ {
401
+ "key": "files",
402
+ "type": "file",
403
+ "src": ["/path/to/doc1.pdf", "/path/to/doc2.pdf"]
404
+ },
405
+ {
406
+ "key": "folder",
407
+ "value": "invoices",
408
+ "type": "text"
409
+ }
410
+ ]
411
+ }
412
+ }
413
+ }
414
+ ```
415
+
416
+ ## List with Query Parameters
417
+
418
+ ```json
419
+ {
420
+ "name": "List Users (Filtered & Paginated)",
421
+ "request": {
422
+ "method": "GET",
423
+ "header": [
424
+ { "key": "Authorization", "value": "Bearer {{authToken}}" }
425
+ ],
426
+ "url": {
427
+ "raw": "{{baseUrl}}/api/users?page=1&limit=20&sortBy=createdAt&sortOrder=desc&status=active",
428
+ "host": ["{{baseUrl}}"],
429
+ "path": ["api", "users"],
430
+ "query": [
431
+ { "key": "page", "value": "1", "description": "Page number" },
432
+ { "key": "limit", "value": "20", "description": "Items per page" },
433
+ { "key": "sortBy", "value": "createdAt", "description": "Sort field" },
434
+ { "key": "sortOrder", "value": "desc", "description": "Sort direction (asc/desc)" },
435
+ { "key": "status", "value": "active", "description": "Filter by status" },
436
+ { "key": "search", "value": "", "description": "Search by name or email", "disabled": true }
437
+ ]
438
+ }
439
+ }
440
+ }
441
+ ```
442
+
443
+ ## Collection-Level Pre-Request Script
444
+
445
+ Apply to the collection root to run before every request:
446
+
447
+ ```javascript
448
+ // Set timestamp for requests that need it
449
+ pm.environment.set("currentTimestamp", new Date().toISOString());
450
+
451
+ // Generate correlation ID for request tracing
452
+ pm.environment.set("correlationId", pm.variables.replaceIn("{{$guid}}"));
453
+ ```
454
+
455
+ ## Folder Structure Template
456
+
457
+ Standard folder hierarchy for a typical API:
458
+
459
+ ```json
460
+ {
461
+ "item": [
462
+ {
463
+ "name": "Auth",
464
+ "item": [
465
+ { "name": "Register" },
466
+ { "name": "Login" },
467
+ { "name": "Refresh Token" },
468
+ { "name": "Logout" },
469
+ { "name": "Forgot Password" },
470
+ { "name": "Reset Password" }
471
+ ]
472
+ },
473
+ {
474
+ "name": "Users",
475
+ "item": [
476
+ { "name": "Create User" },
477
+ { "name": "List Users" },
478
+ { "name": "Get User by ID" },
479
+ { "name": "Update User" },
480
+ { "name": "Delete User" },
481
+ { "name": "Upload Avatar" }
482
+ ]
483
+ },
484
+ {
485
+ "name": "System",
486
+ "item": [
487
+ { "name": "Health Check" },
488
+ { "name": "Get API Version" }
489
+ ]
490
+ }
491
+ ]
492
+ }
493
+ ```