awesome-slash 2.4.2

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 (95) hide show
  1. package/.claude-plugin/marketplace.json +54 -0
  2. package/.claude-plugin/plugin.json +11 -0
  3. package/.mcp.json +8 -0
  4. package/CHANGELOG.md +261 -0
  5. package/LICENSE +21 -0
  6. package/README.md +363 -0
  7. package/SECURITY.md +101 -0
  8. package/adapters/README.md +256 -0
  9. package/adapters/codex/README.md +272 -0
  10. package/adapters/codex/install.sh +179 -0
  11. package/adapters/opencode/README.md +301 -0
  12. package/adapters/opencode/install.sh +223 -0
  13. package/lib/patterns/review-patterns.js +511 -0
  14. package/lib/patterns/slop-patterns.js +647 -0
  15. package/lib/platform/detect-platform.js +535 -0
  16. package/lib/platform/verify-tools.js +235 -0
  17. package/lib/state/workflow-state.js +635 -0
  18. package/lib/state/workflow-state.schema.json +282 -0
  19. package/lib/utils/context-optimizer.js +227 -0
  20. package/mcp-server/index.js +303 -0
  21. package/mcp-server/package.json +23 -0
  22. package/package.json +63 -0
  23. package/plugins/deslop-around/.claude-plugin/plugin.json +20 -0
  24. package/plugins/deslop-around/commands/deslop-around.md +220 -0
  25. package/plugins/deslop-around/lib/patterns/review-patterns.js +511 -0
  26. package/plugins/deslop-around/lib/patterns/slop-patterns.js +641 -0
  27. package/plugins/deslop-around/lib/platform/detect-platform.js +514 -0
  28. package/plugins/deslop-around/lib/platform/verify-tools.js +235 -0
  29. package/plugins/deslop-around/lib/state/workflow-state.js +635 -0
  30. package/plugins/deslop-around/lib/state/workflow-state.schema.json +282 -0
  31. package/plugins/deslop-around/lib/utils/context-optimizer.js +222 -0
  32. package/plugins/next-task/.claude-plugin/plugin.json +24 -0
  33. package/plugins/next-task/agents/ci-fixer.md +236 -0
  34. package/plugins/next-task/agents/ci-monitor.md +291 -0
  35. package/plugins/next-task/agents/delivery-validator.md +451 -0
  36. package/plugins/next-task/agents/deslop-work.md +272 -0
  37. package/plugins/next-task/agents/docs-updater.md +506 -0
  38. package/plugins/next-task/agents/exploration-agent.md +277 -0
  39. package/plugins/next-task/agents/implementation-agent.md +427 -0
  40. package/plugins/next-task/agents/planning-agent.md +236 -0
  41. package/plugins/next-task/agents/policy-selector.md +248 -0
  42. package/plugins/next-task/agents/review-orchestrator.md +521 -0
  43. package/plugins/next-task/agents/simple-fixer.md +136 -0
  44. package/plugins/next-task/agents/task-discoverer.md +357 -0
  45. package/plugins/next-task/agents/test-coverage-checker.md +447 -0
  46. package/plugins/next-task/agents/worktree-manager.md +419 -0
  47. package/plugins/next-task/commands/delivery-approval.md +331 -0
  48. package/plugins/next-task/commands/next-task.md +627 -0
  49. package/plugins/next-task/commands/update-docs-around.md +418 -0
  50. package/plugins/next-task/hooks/hooks.json +14 -0
  51. package/plugins/next-task/lib/patterns/review-patterns.js +511 -0
  52. package/plugins/next-task/lib/patterns/slop-patterns.js +641 -0
  53. package/plugins/next-task/lib/platform/detect-platform.js +514 -0
  54. package/plugins/next-task/lib/platform/verify-tools.js +235 -0
  55. package/plugins/next-task/lib/state/tasks-registry.schema.json +85 -0
  56. package/plugins/next-task/lib/state/workflow-state.js +635 -0
  57. package/plugins/next-task/lib/state/workflow-state.schema.json +282 -0
  58. package/plugins/next-task/lib/state/worktree-status.schema.json +219 -0
  59. package/plugins/next-task/lib/utils/context-optimizer.js +222 -0
  60. package/plugins/project-review/.claude-plugin/plugin.json +20 -0
  61. package/plugins/project-review/commands/project-review-agents.md +286 -0
  62. package/plugins/project-review/commands/project-review-github.md +142 -0
  63. package/plugins/project-review/commands/project-review.md +273 -0
  64. package/plugins/project-review/lib/patterns/review-patterns.js +511 -0
  65. package/plugins/project-review/lib/patterns/slop-patterns.js +641 -0
  66. package/plugins/project-review/lib/platform/detect-platform.js +514 -0
  67. package/plugins/project-review/lib/platform/verify-tools.js +235 -0
  68. package/plugins/project-review/lib/state/workflow-state.js +635 -0
  69. package/plugins/project-review/lib/state/workflow-state.schema.json +282 -0
  70. package/plugins/project-review/lib/utils/context-optimizer.js +222 -0
  71. package/plugins/reality-check/.claude-plugin/plugin.json +23 -0
  72. package/plugins/reality-check/README.md +156 -0
  73. package/plugins/reality-check/agents/code-explorer.md +353 -0
  74. package/plugins/reality-check/agents/doc-analyzer.md +337 -0
  75. package/plugins/reality-check/agents/issue-scanner.md +231 -0
  76. package/plugins/reality-check/agents/plan-synthesizer.md +479 -0
  77. package/plugins/reality-check/commands/scan.md +242 -0
  78. package/plugins/reality-check/commands/set.md +203 -0
  79. package/plugins/reality-check/lib/state/reality-check-state.js +509 -0
  80. package/plugins/reality-check/skills/reality-analysis/SKILL.md +317 -0
  81. package/plugins/ship/.claude-plugin/plugin.json +21 -0
  82. package/plugins/ship/commands/ship-ci-review-loop.md +443 -0
  83. package/plugins/ship/commands/ship-deployment.md +330 -0
  84. package/plugins/ship/commands/ship-error-handling.md +254 -0
  85. package/plugins/ship/commands/ship.md +370 -0
  86. package/plugins/ship/lib/patterns/review-patterns.js +511 -0
  87. package/plugins/ship/lib/patterns/slop-patterns.js +641 -0
  88. package/plugins/ship/lib/platform/detect-platform.js +514 -0
  89. package/plugins/ship/lib/platform/verify-tools.js +235 -0
  90. package/plugins/ship/lib/state/workflow-state.js +635 -0
  91. package/plugins/ship/lib/state/workflow-state.schema.json +282 -0
  92. package/plugins/ship/lib/utils/context-optimizer.js +222 -0
  93. package/scripts/install/claude.sh +50 -0
  94. package/scripts/install/codex.sh +181 -0
  95. package/scripts/install/opencode.sh +211 -0
@@ -0,0 +1,447 @@
1
+ ---
2
+ name: test-coverage-checker
3
+ description: Validate test coverage quality for new code. Use this agent before the first review round to verify tests exist, are meaningful, and actually exercise the new code (not just path matching).
4
+ tools: Bash(git:*), Read, Grep, Glob
5
+ model: sonnet
6
+ ---
7
+
8
+ # Test Coverage Checker Agent
9
+
10
+ Validate that new work has appropriate, meaningful test coverage.
11
+ This is an advisory agent - it reports coverage gaps but does NOT block the workflow.
12
+
13
+ **Important**: This agent validates test QUALITY, not just test EXISTENCE. A test file
14
+ that exists but doesn't meaningfully exercise the new code is flagged as a gap.
15
+
16
+ ## Scope
17
+
18
+ Analyze files in: `git diff --name-only origin/main..HEAD`
19
+
20
+ ## Phase 1: Get Changed Files
21
+
22
+ ```bash
23
+ # Get base branch
24
+ BASE_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")
25
+
26
+ # Get changed source files (exclude test files)
27
+ CHANGED_SOURCE=$(git diff --name-only origin/${BASE_BRANCH}..HEAD 2>/dev/null | \
28
+ grep -E '\.(js|ts|jsx|tsx|py|rs|go|rb|java|kt|swift|cpp|c|cs)$' | \
29
+ grep -v -E '(test|spec|_test|Test)\.')
30
+
31
+ # Get changed test files
32
+ CHANGED_TESTS=$(git diff --name-only origin/${BASE_BRANCH}..HEAD 2>/dev/null | \
33
+ grep -E '(test|spec|_test|Test)\.')
34
+
35
+ echo "SOURCE_FILES=$CHANGED_SOURCE"
36
+ echo "TEST_FILES=$CHANGED_TESTS"
37
+ ```
38
+
39
+ ## Phase 2: Detect Test Conventions
40
+
41
+ Detect the project's test file naming convention:
42
+
43
+ ```bash
44
+ # Check for common test patterns
45
+ if ls tests/ 2>/dev/null | head -1; then
46
+ echo "TEST_DIR=tests"
47
+ elif ls __tests__/ 2>/dev/null | head -1; then
48
+ echo "TEST_DIR=__tests__"
49
+ elif ls test/ 2>/dev/null | head -1; then
50
+ echo "TEST_DIR=test"
51
+ elif ls spec/ 2>/dev/null | head -1; then
52
+ echo "TEST_DIR=spec"
53
+ fi
54
+
55
+ # Check naming convention
56
+ if ls **/*.test.* 2>/dev/null | head -1; then
57
+ echo "TEST_PATTERN=.test."
58
+ elif ls **/*.spec.* 2>/dev/null | head -1; then
59
+ echo "TEST_PATTERN=.spec."
60
+ elif ls **/test_*.* 2>/dev/null | head -1; then
61
+ echo "TEST_PATTERN=test_"
62
+ fi
63
+ ```
64
+
65
+ ## Phase 3: Map Source to Test Files
66
+
67
+ For each source file, find corresponding test file:
68
+
69
+ ```javascript
70
+ const testMappings = {
71
+ // JavaScript/TypeScript patterns
72
+ 'src/foo.ts': ['tests/foo.test.ts', '__tests__/foo.test.ts', 'src/foo.test.ts', 'src/__tests__/foo.test.ts'],
73
+ 'lib/bar.js': ['tests/bar.test.js', 'lib/bar.test.js', 'test/bar.test.js'],
74
+
75
+ // Python patterns
76
+ 'src/module.py': ['tests/test_module.py', 'test/test_module.py', 'src/test_module.py'],
77
+
78
+ // Rust patterns
79
+ 'src/lib.rs': ['tests/lib_test.rs', 'src/lib_tests.rs'],
80
+
81
+ // Go patterns
82
+ 'pkg/handler.go': ['pkg/handler_test.go']
83
+ };
84
+
85
+ function findTestFile(sourceFile) {
86
+ const basename = sourceFile.split('/').pop().replace(/\.[^.]+$/, '');
87
+ const dir = sourceFile.split('/').slice(0, -1).join('/');
88
+ const ext = sourceFile.split('.').pop();
89
+
90
+ // Generate possible test file locations
91
+ const candidates = [
92
+ `tests/${basename}.test.${ext}`,
93
+ `tests/${basename}.spec.${ext}`,
94
+ `test/${basename}.test.${ext}`,
95
+ `__tests__/${basename}.test.${ext}`,
96
+ `${dir}/${basename}.test.${ext}`,
97
+ `${dir}/${basename}.spec.${ext}`,
98
+ `${dir}/__tests__/${basename}.test.${ext}`,
99
+ // Python style
100
+ `tests/test_${basename}.${ext}`,
101
+ `test/test_${basename}.${ext}`,
102
+ // Go style (test in same dir)
103
+ `${dir}/${basename}_test.${ext}`
104
+ ];
105
+
106
+ return candidates;
107
+ }
108
+ ```
109
+
110
+ ## Phase 4: Check Coverage
111
+
112
+ For each changed source file:
113
+ 1. Find corresponding test file
114
+ 2. Check if test file exists
115
+ 3. If source modified, check if test was also modified
116
+ 4. Analyze new functions/classes for test coverage
117
+
118
+ ```javascript
119
+ const gaps = [];
120
+ const covered = [];
121
+
122
+ for (const sourceFile of changedSourceFiles) {
123
+ const testCandidates = findTestFile(sourceFile);
124
+ const existingTest = testCandidates.find(t => fileExists(t));
125
+
126
+ if (!existingTest) {
127
+ gaps.push({
128
+ file: sourceFile,
129
+ reason: 'No test file found',
130
+ candidates: testCandidates.slice(0, 3)
131
+ });
132
+ continue;
133
+ }
134
+
135
+ // Check if test was updated along with source
136
+ const testModified = changedTestFiles.includes(existingTest);
137
+
138
+ if (!testModified) {
139
+ gaps.push({
140
+ file: sourceFile,
141
+ reason: 'Source modified but test file not updated',
142
+ testFile: existingTest
143
+ });
144
+ } else {
145
+ covered.push({
146
+ file: sourceFile,
147
+ testFile: existingTest
148
+ });
149
+ }
150
+ }
151
+ ```
152
+
153
+ ## Phase 5: Analyze New Exports
154
+
155
+ Check for new functions/classes that might need tests:
156
+
157
+ ```javascript
158
+ async function findNewExports(file) {
159
+ // Get diff for the file
160
+ const diff = await exec(`git diff origin/${BASE_BRANCH}..HEAD -- ${file}`);
161
+
162
+ // Find added function/class declarations
163
+ const newExports = [];
164
+ const patterns = [
165
+ /^\+\s*export\s+(function|const|class|async function)\s+(\w+)/gm,
166
+ /^\+\s*export\s+default\s+(function|class)\s*(\w*)/gm,
167
+ /^\+\s*module\.exports\s*=\s*\{([^}]+)\}/gm,
168
+ /^\+\s*def\s+(\w+)\(/gm, // Python
169
+ /^\+\s*pub\s+fn\s+(\w+)/gm, // Rust
170
+ /^\+\s*func\s+(\w+)/gm // Go
171
+ ];
172
+
173
+ for (const pattern of patterns) {
174
+ let match;
175
+ while ((match = pattern.exec(diff)) !== null) {
176
+ newExports.push(match[2] || match[1]);
177
+ }
178
+ }
179
+
180
+ return newExports;
181
+ }
182
+ ```
183
+
184
+ ## Phase 6: Validate Test Quality
185
+
186
+ **Critical**: Don't just check if test files exist - verify tests actually exercise the new code.
187
+
188
+ ```javascript
189
+ async function validateTestQuality(sourceFile, testFile, newExports) {
190
+ const testContent = await readFile(testFile);
191
+ const sourceContent = await readFile(sourceFile);
192
+ const issues = [];
193
+
194
+ // 1. Check if new exports are actually tested
195
+ for (const exportName of newExports) {
196
+ const testMentions = testContent.match(new RegExp(exportName, 'g'));
197
+ if (!testMentions || testMentions.length === 0) {
198
+ issues.push({
199
+ type: 'untested-export',
200
+ export: exportName,
201
+ message: `New export '${exportName}' is not referenced in test file`
202
+ });
203
+ }
204
+ }
205
+
206
+ // 2. Check for meaningful assertions (not just trivial tests)
207
+ const trivialPatterns = [
208
+ /expect\s*\(\s*true\s*\)/,
209
+ /expect\s*\(\s*1\s*\)\s*\.toBe\s*\(\s*1\s*\)/,
210
+ /assert\s*\(\s*True\s*\)/,
211
+ /\.toBeDefined\s*\(\s*\)/ // Only toBeDefined without other checks
212
+ ];
213
+
214
+ for (const pattern of trivialPatterns) {
215
+ if (pattern.test(testContent)) {
216
+ issues.push({
217
+ type: 'trivial-assertion',
218
+ message: 'Test contains trivial assertions that don\'t validate behavior'
219
+ });
220
+ break;
221
+ }
222
+ }
223
+
224
+ // 3. Check test describes/its match the source functionality
225
+ const describeTitles = testContent.match(/describe\s*\(\s*['"`]([^'"`]+)['"`]/g) || [];
226
+ const itTitles = testContent.match(/it\s*\(\s*['"`]([^'"`]+)['"`]/g) || [];
227
+
228
+ if (describeTitles.length === 0 && itTitles.length === 0) {
229
+ issues.push({
230
+ type: 'no-test-structure',
231
+ message: 'Test file lacks describe/it blocks - may not be a real test'
232
+ });
233
+ }
234
+
235
+ // 4. Check for edge case coverage hints
236
+ const edgeCasePatterns = ['null', 'undefined', 'empty', 'error', 'invalid', 'edge', 'boundary'];
237
+ const hasEdgeCases = edgeCasePatterns.some(p => testContent.toLowerCase().includes(p));
238
+
239
+ if (!hasEdgeCases && newExports.length > 0) {
240
+ issues.push({
241
+ type: 'missing-edge-cases',
242
+ message: 'Tests may lack edge case coverage (no null/error/boundary tests detected)',
243
+ severity: 'warning'
244
+ });
245
+ }
246
+
247
+ // 5. Check if test actually imports/requires the source
248
+ const sourceBasename = sourceFile.split('/').pop().replace(/\.[^.]+$/, '');
249
+ const importPatterns = [
250
+ new RegExp(`from\\s+['"][^'"]*${sourceBasename}['"]`),
251
+ new RegExp(`require\\s*\\(\\s*['"][^'"]*${sourceBasename}['"]`),
252
+ new RegExp(`import\\s+.*${sourceBasename}`)
253
+ ];
254
+
255
+ const importsSource = importPatterns.some(p => p.test(testContent));
256
+ if (!importsSource) {
257
+ issues.push({
258
+ type: 'no-source-import',
259
+ message: `Test file doesn't appear to import '${sourceBasename}'`,
260
+ severity: 'critical'
261
+ });
262
+ }
263
+
264
+ return {
265
+ testFile,
266
+ sourceFile,
267
+ quality: issues.length === 0 ? 'good' : issues.some(i => i.severity === 'critical') ? 'poor' : 'needs-improvement',
268
+ issues
269
+ };
270
+ }
271
+ ```
272
+
273
+ ## Phase 7: Analyze Test Coverage Depth
274
+
275
+ Check if tests cover the actual logic paths in the new code:
276
+
277
+ ```javascript
278
+ async function analyzeTestDepth(sourceFile, testFile, diff) {
279
+ const analysis = {
280
+ sourceComplexity: 'unknown',
281
+ testCoverage: 'unknown',
282
+ suggestions: []
283
+ };
284
+
285
+ // Extract conditionals and branches from new code
286
+ const newBranches = [];
287
+ const branchPatterns = [
288
+ /^\+.*if\s*\(/gm,
289
+ /^\+.*else\s*\{/gm,
290
+ /^\+.*\?\s*.*:/gm, // Ternary
291
+ /^\+.*switch\s*\(/gm,
292
+ /^\+.*case\s+/gm,
293
+ /^\+.*catch\s*\(/gm
294
+ ];
295
+
296
+ for (const pattern of branchPatterns) {
297
+ const matches = diff.match(pattern) || [];
298
+ newBranches.push(...matches);
299
+ }
300
+
301
+ if (newBranches.length > 3) {
302
+ analysis.sourceComplexity = 'high';
303
+ analysis.suggestions.push('New code has multiple branches - ensure each path is tested');
304
+ }
305
+
306
+ // Check for async/await patterns that need error testing
307
+ const hasAsync = /^\+.*async\s+|^\+.*await\s+/m.test(diff);
308
+ if (hasAsync) {
309
+ const testContent = await readFile(testFile);
310
+ const hasAsyncTests = /\.rejects|\.resolves|async.*expect|try.*catch.*expect/i.test(testContent);
311
+
312
+ if (!hasAsyncTests) {
313
+ analysis.suggestions.push('New async code detected - add tests for promise rejection scenarios');
314
+ }
315
+ }
316
+
317
+ return analysis;
318
+ }
319
+ ```
320
+
321
+ ## Output Format (JSON)
322
+
323
+ ```json
324
+ {
325
+ "scope": "new-work-only",
326
+ "coverage": {
327
+ "filesAnalyzed": 5,
328
+ "filesWithTests": 3,
329
+ "filesMissingTests": 2,
330
+ "coveragePercent": 60
331
+ },
332
+ "gaps": [
333
+ {
334
+ "file": "src/new-feature.ts",
335
+ "reason": "No test file found",
336
+ "candidates": ["tests/new-feature.test.ts", "__tests__/new-feature.test.ts"],
337
+ "newExports": ["handleFeature", "FeatureConfig"]
338
+ },
339
+ {
340
+ "file": "src/modified.ts",
341
+ "reason": "Source modified but test file not updated",
342
+ "testFile": "tests/modified.test.ts",
343
+ "newExports": ["newFunction"]
344
+ }
345
+ ],
346
+ "qualityIssues": [
347
+ {
348
+ "file": "src/api-client.ts",
349
+ "testFile": "tests/api-client.test.ts",
350
+ "quality": "needs-improvement",
351
+ "issues": [
352
+ {
353
+ "type": "untested-export",
354
+ "export": "handleRetry",
355
+ "message": "New export 'handleRetry' is not referenced in test file"
356
+ },
357
+ {
358
+ "type": "missing-edge-cases",
359
+ "message": "Tests may lack edge case coverage",
360
+ "severity": "warning"
361
+ }
362
+ ],
363
+ "suggestions": ["New async code detected - add tests for promise rejection scenarios"]
364
+ }
365
+ ],
366
+ "covered": [
367
+ {
368
+ "file": "src/utils.ts",
369
+ "testFile": "tests/utils.test.ts",
370
+ "quality": "good"
371
+ }
372
+ ],
373
+ "summary": {
374
+ "status": "quality-issues-found",
375
+ "recommendation": "2 files missing tests, 1 file has tests but doesn't exercise new code"
376
+ }
377
+ }
378
+ ```
379
+
380
+ ## Report Output
381
+
382
+ ```markdown
383
+ ## Test Coverage Report
384
+
385
+ ### Summary
386
+ | Metric | Value |
387
+ |--------|-------|
388
+ | Files Analyzed | ${filesAnalyzed} |
389
+ | Files with Tests | ${filesWithTests} |
390
+ | Files Missing Tests | ${filesMissingTests} |
391
+ | Tests with Quality Issues | ${qualityIssues.length} |
392
+ | Effective Coverage | ${effectiveCoveragePercent}% |
393
+
394
+ ### Missing Test Files
395
+ ${gaps.map(g => `
396
+ **${g.file}**
397
+ - Reason: ${g.reason}
398
+ - New exports: ${g.newExports?.join(', ') || 'N/A'}
399
+ ${g.candidates ? `- Suggested test location: ${g.candidates[0]}` : ''}
400
+ `).join('\n')}
401
+
402
+ ### Test Quality Issues
403
+ ${qualityIssues.map(q => `
404
+ **${q.file}** → ${q.testFile} (Quality: ${q.quality})
405
+ ${q.issues.map(i => `- ⚠️ ${i.message}`).join('\n')}
406
+ ${q.suggestions?.map(s => `- 💡 ${s}`).join('\n') || ''}
407
+ `).join('\n')}
408
+
409
+ ### Well-Covered Files
410
+ ${covered.filter(c => c.quality === 'good').map(c => `- ✓ ${c.file} → ${c.testFile}`).join('\n')}
411
+
412
+ ### Recommendation
413
+ ${summary.recommendation}
414
+ ```
415
+
416
+ ## Behavior
417
+
418
+ - **Advisory only** - Does NOT block workflow
419
+ - Reports coverage gaps to review-orchestrator
420
+ - Suggestions included in PR description
421
+ - Implementation-agent may optionally add tests based on findings
422
+
423
+ ## Integration Points
424
+
425
+ This agent is called:
426
+ 1. **Before first review round** - In parallel with deslop-work
427
+ 2. Results passed to review-orchestrator for context
428
+
429
+ ## Success Criteria
430
+
431
+ - Correctly identifies test file conventions
432
+ - Maps source files to test files
433
+ - Detects new exports that need testing
434
+ - **Validates tests actually exercise the new code** (not just path matching)
435
+ - **Flags trivial or meaningless tests** (e.g., `expect(true).toBe(true)`)
436
+ - **Checks for edge case coverage** in tests
437
+ - **Verifies tests import the source file** they claim to test
438
+ - Provides actionable recommendations
439
+ - Does NOT block workflow on missing tests
440
+
441
+ ## Model Choice: Sonnet
442
+
443
+ This agent uses **sonnet** because:
444
+ - Test quality validation requires understanding code relationships
445
+ - Pattern detection needs more than simple matching
446
+ - Analyzing test meaningfulness requires moderate reasoning
447
+ - Advisory role means occasional misses are acceptable