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.
- package/.claude-plugin/marketplace.json +54 -0
- package/.claude-plugin/plugin.json +11 -0
- package/.mcp.json +8 -0
- package/CHANGELOG.md +261 -0
- package/LICENSE +21 -0
- package/README.md +363 -0
- package/SECURITY.md +101 -0
- package/adapters/README.md +256 -0
- package/adapters/codex/README.md +272 -0
- package/adapters/codex/install.sh +179 -0
- package/adapters/opencode/README.md +301 -0
- package/adapters/opencode/install.sh +223 -0
- package/lib/patterns/review-patterns.js +511 -0
- package/lib/patterns/slop-patterns.js +647 -0
- package/lib/platform/detect-platform.js +535 -0
- package/lib/platform/verify-tools.js +235 -0
- package/lib/state/workflow-state.js +635 -0
- package/lib/state/workflow-state.schema.json +282 -0
- package/lib/utils/context-optimizer.js +227 -0
- package/mcp-server/index.js +303 -0
- package/mcp-server/package.json +23 -0
- package/package.json +63 -0
- package/plugins/deslop-around/.claude-plugin/plugin.json +20 -0
- package/plugins/deslop-around/commands/deslop-around.md +220 -0
- package/plugins/deslop-around/lib/patterns/review-patterns.js +511 -0
- package/plugins/deslop-around/lib/patterns/slop-patterns.js +641 -0
- package/plugins/deslop-around/lib/platform/detect-platform.js +514 -0
- package/plugins/deslop-around/lib/platform/verify-tools.js +235 -0
- package/plugins/deslop-around/lib/state/workflow-state.js +635 -0
- package/plugins/deslop-around/lib/state/workflow-state.schema.json +282 -0
- package/plugins/deslop-around/lib/utils/context-optimizer.js +222 -0
- package/plugins/next-task/.claude-plugin/plugin.json +24 -0
- package/plugins/next-task/agents/ci-fixer.md +236 -0
- package/plugins/next-task/agents/ci-monitor.md +291 -0
- package/plugins/next-task/agents/delivery-validator.md +451 -0
- package/plugins/next-task/agents/deslop-work.md +272 -0
- package/plugins/next-task/agents/docs-updater.md +506 -0
- package/plugins/next-task/agents/exploration-agent.md +277 -0
- package/plugins/next-task/agents/implementation-agent.md +427 -0
- package/plugins/next-task/agents/planning-agent.md +236 -0
- package/plugins/next-task/agents/policy-selector.md +248 -0
- package/plugins/next-task/agents/review-orchestrator.md +521 -0
- package/plugins/next-task/agents/simple-fixer.md +136 -0
- package/plugins/next-task/agents/task-discoverer.md +357 -0
- package/plugins/next-task/agents/test-coverage-checker.md +447 -0
- package/plugins/next-task/agents/worktree-manager.md +419 -0
- package/plugins/next-task/commands/delivery-approval.md +331 -0
- package/plugins/next-task/commands/next-task.md +627 -0
- package/plugins/next-task/commands/update-docs-around.md +418 -0
- package/plugins/next-task/hooks/hooks.json +14 -0
- package/plugins/next-task/lib/patterns/review-patterns.js +511 -0
- package/plugins/next-task/lib/patterns/slop-patterns.js +641 -0
- package/plugins/next-task/lib/platform/detect-platform.js +514 -0
- package/plugins/next-task/lib/platform/verify-tools.js +235 -0
- package/plugins/next-task/lib/state/tasks-registry.schema.json +85 -0
- package/plugins/next-task/lib/state/workflow-state.js +635 -0
- package/plugins/next-task/lib/state/workflow-state.schema.json +282 -0
- package/plugins/next-task/lib/state/worktree-status.schema.json +219 -0
- package/plugins/next-task/lib/utils/context-optimizer.js +222 -0
- package/plugins/project-review/.claude-plugin/plugin.json +20 -0
- package/plugins/project-review/commands/project-review-agents.md +286 -0
- package/plugins/project-review/commands/project-review-github.md +142 -0
- package/plugins/project-review/commands/project-review.md +273 -0
- package/plugins/project-review/lib/patterns/review-patterns.js +511 -0
- package/plugins/project-review/lib/patterns/slop-patterns.js +641 -0
- package/plugins/project-review/lib/platform/detect-platform.js +514 -0
- package/plugins/project-review/lib/platform/verify-tools.js +235 -0
- package/plugins/project-review/lib/state/workflow-state.js +635 -0
- package/plugins/project-review/lib/state/workflow-state.schema.json +282 -0
- package/plugins/project-review/lib/utils/context-optimizer.js +222 -0
- package/plugins/reality-check/.claude-plugin/plugin.json +23 -0
- package/plugins/reality-check/README.md +156 -0
- package/plugins/reality-check/agents/code-explorer.md +353 -0
- package/plugins/reality-check/agents/doc-analyzer.md +337 -0
- package/plugins/reality-check/agents/issue-scanner.md +231 -0
- package/plugins/reality-check/agents/plan-synthesizer.md +479 -0
- package/plugins/reality-check/commands/scan.md +242 -0
- package/plugins/reality-check/commands/set.md +203 -0
- package/plugins/reality-check/lib/state/reality-check-state.js +509 -0
- package/plugins/reality-check/skills/reality-analysis/SKILL.md +317 -0
- package/plugins/ship/.claude-plugin/plugin.json +21 -0
- package/plugins/ship/commands/ship-ci-review-loop.md +443 -0
- package/plugins/ship/commands/ship-deployment.md +330 -0
- package/plugins/ship/commands/ship-error-handling.md +254 -0
- package/plugins/ship/commands/ship.md +370 -0
- package/plugins/ship/lib/patterns/review-patterns.js +511 -0
- package/plugins/ship/lib/patterns/slop-patterns.js +641 -0
- package/plugins/ship/lib/platform/detect-platform.js +514 -0
- package/plugins/ship/lib/platform/verify-tools.js +235 -0
- package/plugins/ship/lib/state/workflow-state.js +635 -0
- package/plugins/ship/lib/state/workflow-state.schema.json +282 -0
- package/plugins/ship/lib/utils/context-optimizer.js +222 -0
- package/scripts/install/claude.sh +50 -0
- package/scripts/install/codex.sh +181 -0
- package/scripts/install/opencode.sh +211 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Optimizer Utilities
|
|
3
|
+
* Provides optimized git commands to minimize token usage while gathering context
|
|
4
|
+
*
|
|
5
|
+
* Target: Keep command execution under 50k tokens
|
|
6
|
+
*
|
|
7
|
+
* @author Avi Fenesh
|
|
8
|
+
* @license MIT
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Escape shell special characters for safe command interpolation
|
|
13
|
+
* @param {string} str - String to escape
|
|
14
|
+
* @returns {string} Escaped string safe for shell use
|
|
15
|
+
*/
|
|
16
|
+
function escapeShell(str) {
|
|
17
|
+
if (typeof str !== 'string') return '';
|
|
18
|
+
// Escape characters that have special meaning in shell
|
|
19
|
+
return str.replace(/["$`\\!]/g, '\\$&');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Escape single quotes for shell (replace ' with '\''
|
|
24
|
+
* @param {string} str - String to escape
|
|
25
|
+
* @returns {string} Escaped string safe for single-quoted shell use
|
|
26
|
+
*/
|
|
27
|
+
function escapeSingleQuotes(str) {
|
|
28
|
+
if (typeof str !== 'string') return '';
|
|
29
|
+
return str.replace(/'/g, "'\\''");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Validate and sanitize file extension
|
|
34
|
+
* @param {string} ext - Extension to validate
|
|
35
|
+
* @returns {string} Safe extension (alphanumeric only)
|
|
36
|
+
*/
|
|
37
|
+
function sanitizeExtension(ext) {
|
|
38
|
+
if (typeof ext !== 'string') return 'ts';
|
|
39
|
+
const safe = ext.replace(/[^a-zA-Z0-9]/g, '');
|
|
40
|
+
return safe || 'ts';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Git command optimization utilities for context efficiency
|
|
45
|
+
*/
|
|
46
|
+
const contextOptimizer = {
|
|
47
|
+
/**
|
|
48
|
+
* Get recent commits with minimal formatting
|
|
49
|
+
* @param {number} limit - Number of commits to retrieve (default: 10)
|
|
50
|
+
* @returns {string} Git command
|
|
51
|
+
*/
|
|
52
|
+
recentCommits: (limit = 10) =>
|
|
53
|
+
`git log --oneline --no-decorate -${limit} --format="%h %s"`,
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get compact git status (untracked files excluded)
|
|
57
|
+
* @returns {string} Git command
|
|
58
|
+
*/
|
|
59
|
+
compactStatus: () =>
|
|
60
|
+
'git status -uno --porcelain',
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get file changes between refs
|
|
64
|
+
* @param {string} ref - Reference to compare from (default: 'HEAD~5')
|
|
65
|
+
* @returns {string} Git command
|
|
66
|
+
*/
|
|
67
|
+
fileChanges: (ref = 'HEAD~5') =>
|
|
68
|
+
`git diff ${ref}..HEAD --name-status`,
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get current branch name
|
|
72
|
+
* @returns {string} Git command
|
|
73
|
+
*/
|
|
74
|
+
currentBranch: () =>
|
|
75
|
+
'git branch --show-current',
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Get remote information (limited to 2 lines)
|
|
79
|
+
* @returns {string} Git command
|
|
80
|
+
*/
|
|
81
|
+
remoteInfo: () =>
|
|
82
|
+
'git remote -v | head -2',
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Check if there are stashed changes
|
|
86
|
+
* @returns {string} Git command
|
|
87
|
+
*/
|
|
88
|
+
hasStashes: () =>
|
|
89
|
+
'git stash list --oneline | wc -l',
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get worktree list in porcelain format
|
|
93
|
+
* @returns {string} Git command
|
|
94
|
+
*/
|
|
95
|
+
worktreeList: () =>
|
|
96
|
+
'git worktree list --porcelain',
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get the age of a specific line (for TODO checking)
|
|
100
|
+
* @param {string} file - File path
|
|
101
|
+
* @param {number} line - Line number
|
|
102
|
+
* @returns {string} Git command
|
|
103
|
+
*/
|
|
104
|
+
lineAge: (file, line) => {
|
|
105
|
+
// Validate line is a positive integer
|
|
106
|
+
const lineNum = parseInt(line, 10);
|
|
107
|
+
if (!Number.isInteger(lineNum) || lineNum < 1) {
|
|
108
|
+
throw new Error('Line must be a positive integer');
|
|
109
|
+
}
|
|
110
|
+
// Escape file path for safe shell usage
|
|
111
|
+
const safeFile = escapeShell(file);
|
|
112
|
+
return `git blame -L ${lineNum},${lineNum} "${safeFile}" --porcelain | grep '^committer-time' | cut -d' ' -f2`;
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Find source files by extension
|
|
117
|
+
* @param {string} extension - File extension (e.g., 'ts', 'py', 'rs')
|
|
118
|
+
* @returns {string} Git command
|
|
119
|
+
*/
|
|
120
|
+
findSourceFiles: (extension = 'ts') => {
|
|
121
|
+
const safeExt = sanitizeExtension(extension);
|
|
122
|
+
return `git ls-files | grep '\\.${safeExt}$'`;
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Get diff stat summary
|
|
127
|
+
* @param {string} ref - Reference to compare from (default: 'HEAD~5')
|
|
128
|
+
* @returns {string} Git command
|
|
129
|
+
*/
|
|
130
|
+
diffStat: (ref = 'HEAD~5') =>
|
|
131
|
+
`git diff ${ref}..HEAD --stat | head -20`,
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Get contributors list (limited to top 10)
|
|
135
|
+
* @returns {string} Git command
|
|
136
|
+
*/
|
|
137
|
+
contributors: () =>
|
|
138
|
+
'git shortlog -sn --no-merges | head -10',
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get last commit message
|
|
142
|
+
* @returns {string} Git command
|
|
143
|
+
*/
|
|
144
|
+
lastCommitMessage: () =>
|
|
145
|
+
'git log -1 --format=%s',
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get files changed in last commit
|
|
149
|
+
* @returns {string} Git command
|
|
150
|
+
*/
|
|
151
|
+
lastCommitFiles: () =>
|
|
152
|
+
'git diff-tree --no-commit-id --name-only -r HEAD',
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get branch list (local only, limited)
|
|
156
|
+
* @param {number} limit - Number of branches (default: 10)
|
|
157
|
+
* @returns {string} Git command
|
|
158
|
+
*/
|
|
159
|
+
branches: (limit = 10) =>
|
|
160
|
+
`git branch --format='%(refname:short)' | head -${limit}`,
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Get tags list (limited)
|
|
164
|
+
* @param {number} limit - Number of tags (default: 10)
|
|
165
|
+
* @returns {string} Git command
|
|
166
|
+
*/
|
|
167
|
+
tags: (limit = 10) =>
|
|
168
|
+
`git tag --sort=-creatordate | head -${limit}`,
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Get count of commits on current branch since branching from main
|
|
172
|
+
* @param {string} mainBranch - Main branch name (default: 'main')
|
|
173
|
+
* @returns {string} Git command
|
|
174
|
+
*/
|
|
175
|
+
commitsSinceBranch: (mainBranch = 'main') =>
|
|
176
|
+
`git rev-list --count ${mainBranch}..HEAD`,
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Check if working directory is clean
|
|
180
|
+
* @returns {string} Git command
|
|
181
|
+
*/
|
|
182
|
+
isClean: () =>
|
|
183
|
+
'git status --porcelain | wc -l',
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Get merge base with main branch
|
|
187
|
+
* @param {string} mainBranch - Main branch name (default: 'main')
|
|
188
|
+
* @returns {string} Git command
|
|
189
|
+
*/
|
|
190
|
+
mergeBase: (mainBranch = 'main') =>
|
|
191
|
+
`git merge-base ${mainBranch} HEAD`,
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Get files modified in current branch (since branching)
|
|
195
|
+
* @param {string} mainBranch - Main branch name (default: 'main')
|
|
196
|
+
* @returns {string} Git command
|
|
197
|
+
*/
|
|
198
|
+
branchChangedFiles: (mainBranch = 'main') =>
|
|
199
|
+
`git diff ${mainBranch}...HEAD --name-only`,
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get commit count by author
|
|
203
|
+
* @param {string} author - Author name or email
|
|
204
|
+
* @returns {string} Git command
|
|
205
|
+
*/
|
|
206
|
+
authorCommitCount: (author) => {
|
|
207
|
+
const safeAuthor = escapeShell(author);
|
|
208
|
+
return `git log --author="${safeAuthor}" --oneline | wc -l`;
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Check if file exists in repository
|
|
213
|
+
* @param {string} file - File path
|
|
214
|
+
* @returns {string} Git command
|
|
215
|
+
*/
|
|
216
|
+
fileExists: (file) => {
|
|
217
|
+
const safeFile = escapeSingleQuotes(file);
|
|
218
|
+
return `git ls-files | grep -q '${safeFile}' && echo 'true' || echo 'false'`;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
module.exports = contextOptimizer;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "project-review",
|
|
3
|
+
"version": "2.3.1",
|
|
4
|
+
"description": "Multi-agent iterative code review until zero issues remain",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Avi Fenesh",
|
|
7
|
+
"email": "[email protected]",
|
|
8
|
+
"url": "https://github.com/avifenesh"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/avifenesh/awesome-slash#project-review",
|
|
11
|
+
"repository": "https://github.com/avifenesh/awesome-slash",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"code-review",
|
|
15
|
+
"quality",
|
|
16
|
+
"multi-agent",
|
|
17
|
+
"framework-specific",
|
|
18
|
+
"iterative"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# Phase 2: Multi-Agent Review - Reference
|
|
2
|
+
|
|
3
|
+
This file contains detailed agent coordination for `/project-review`.
|
|
4
|
+
|
|
5
|
+
**Parent document**: `project-review.md`
|
|
6
|
+
|
|
7
|
+
## Agent Specialization
|
|
8
|
+
|
|
9
|
+
### File Filtering by Agent
|
|
10
|
+
|
|
11
|
+
Each agent reviews only relevant files:
|
|
12
|
+
|
|
13
|
+
| Agent | File Patterns |
|
|
14
|
+
|-------|--------------|
|
|
15
|
+
| security-expert | Auth, validation, API endpoints, config |
|
|
16
|
+
| performance-engineer | Hot paths, algorithms, loops, queries |
|
|
17
|
+
| test-quality-guardian | Test files only |
|
|
18
|
+
| architecture-reviewer | All source files |
|
|
19
|
+
| database-specialist | Models, queries, migrations |
|
|
20
|
+
| api-designer | API routes, controllers, handlers |
|
|
21
|
+
| frontend-specialist | Components, state management |
|
|
22
|
+
| devops-reviewer | CI/CD configs, Dockerfiles |
|
|
23
|
+
|
|
24
|
+
## Agent Coordination
|
|
25
|
+
|
|
26
|
+
Use Task tool to launch agents in parallel:
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
const agents = [];
|
|
30
|
+
|
|
31
|
+
// Always active agents
|
|
32
|
+
agents.push(Task({
|
|
33
|
+
subagent_type: "Explore",
|
|
34
|
+
prompt: `You are security-expert. Review ${SCOPE} for security issues.
|
|
35
|
+
|
|
36
|
+
Framework: ${FRAMEWORK}
|
|
37
|
+
Patterns: ${frameworkPatterns?.security}
|
|
38
|
+
|
|
39
|
+
Focus on:
|
|
40
|
+
- SQL injection, XSS, CSRF vulnerabilities
|
|
41
|
+
- Authentication and authorization flaws
|
|
42
|
+
- Secrets exposure, insecure configurations
|
|
43
|
+
- Input validation, output encoding
|
|
44
|
+
|
|
45
|
+
Provide findings in evidence-based format with file:line.`
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
agents.push(Task({
|
|
49
|
+
subagent_type: "Explore",
|
|
50
|
+
prompt: `You are performance-engineer. Review ${SCOPE} for performance issues.
|
|
51
|
+
|
|
52
|
+
Framework: ${FRAMEWORK}
|
|
53
|
+
Patterns: ${frameworkPatterns?.performance}
|
|
54
|
+
|
|
55
|
+
Focus on:
|
|
56
|
+
- N+1 queries, inefficient algorithms
|
|
57
|
+
- Memory leaks, unnecessary allocations
|
|
58
|
+
- Blocking operations, missing async
|
|
59
|
+
- Bundle size, lazy loading
|
|
60
|
+
|
|
61
|
+
Provide findings in evidence-based format.`
|
|
62
|
+
}));
|
|
63
|
+
|
|
64
|
+
// Conditional agents
|
|
65
|
+
if (HAS_TESTS) {
|
|
66
|
+
agents.push(Task({
|
|
67
|
+
subagent_type: "Explore",
|
|
68
|
+
prompt: `You are test-quality-guardian. Review test files.
|
|
69
|
+
|
|
70
|
+
Framework: ${FRAMEWORK}
|
|
71
|
+
|
|
72
|
+
Focus on:
|
|
73
|
+
- Test coverage for new code
|
|
74
|
+
- Edge case coverage
|
|
75
|
+
- Test design and maintainability
|
|
76
|
+
- Mocking appropriateness
|
|
77
|
+
|
|
78
|
+
Provide findings in evidence-based format.`
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (FILE_COUNT > 50) {
|
|
83
|
+
agents.push(Task({
|
|
84
|
+
subagent_type: "Explore",
|
|
85
|
+
prompt: `You are architecture-reviewer. Review ${SCOPE} for design issues.
|
|
86
|
+
|
|
87
|
+
Framework: ${FRAMEWORK}
|
|
88
|
+
|
|
89
|
+
Focus on:
|
|
90
|
+
- Code organization and modularity
|
|
91
|
+
- Design pattern violations
|
|
92
|
+
- Dependency management
|
|
93
|
+
- SOLID principles
|
|
94
|
+
|
|
95
|
+
Provide findings in evidence-based format.`
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (HAS_DB) {
|
|
100
|
+
agents.push(Task({
|
|
101
|
+
subagent_type: "Explore",
|
|
102
|
+
prompt: `You are database-specialist. Review ${SCOPE} for database issues.
|
|
103
|
+
|
|
104
|
+
Framework: ${FRAMEWORK}
|
|
105
|
+
|
|
106
|
+
Focus on:
|
|
107
|
+
- Query optimization, N+1 queries
|
|
108
|
+
- Missing indexes
|
|
109
|
+
- Transaction handling
|
|
110
|
+
- Connection pooling
|
|
111
|
+
|
|
112
|
+
Provide findings in evidence-based format.`
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (HAS_API) {
|
|
117
|
+
agents.push(Task({
|
|
118
|
+
subagent_type: "Explore",
|
|
119
|
+
prompt: `You are api-designer. Review ${SCOPE} for API issues.
|
|
120
|
+
|
|
121
|
+
Framework: ${FRAMEWORK}
|
|
122
|
+
|
|
123
|
+
Focus on:
|
|
124
|
+
- REST best practices
|
|
125
|
+
- Error handling and status codes
|
|
126
|
+
- Rate limiting, pagination
|
|
127
|
+
- API versioning
|
|
128
|
+
|
|
129
|
+
Provide findings in evidence-based format.`
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Finding Consolidation
|
|
135
|
+
|
|
136
|
+
After all agents complete:
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
function consolidateFindings(agentResults) {
|
|
140
|
+
const allFindings = [];
|
|
141
|
+
|
|
142
|
+
for (const result of agentResults) {
|
|
143
|
+
if (result.findings) {
|
|
144
|
+
allFindings.push(...result.findings);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Deduplicate by file:line
|
|
149
|
+
const seen = new Set();
|
|
150
|
+
const deduped = allFindings.filter(f => {
|
|
151
|
+
const key = `${f.file}:${f.line}`;
|
|
152
|
+
if (seen.has(key)) return false;
|
|
153
|
+
seen.add(key);
|
|
154
|
+
return true;
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Sort by severity
|
|
158
|
+
const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
159
|
+
deduped.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
|
160
|
+
|
|
161
|
+
// Group by file
|
|
162
|
+
const byFile = {};
|
|
163
|
+
for (const f of deduped) {
|
|
164
|
+
if (!byFile[f.file]) byFile[f.file] = [];
|
|
165
|
+
byFile[f.file].push(f);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
all: deduped,
|
|
170
|
+
byFile,
|
|
171
|
+
counts: {
|
|
172
|
+
critical: deduped.filter(f => f.severity === 'critical').length,
|
|
173
|
+
high: deduped.filter(f => f.severity === 'high').length,
|
|
174
|
+
medium: deduped.filter(f => f.severity === 'medium').length,
|
|
175
|
+
low: deduped.filter(f => f.severity === 'low').length
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Framework-Specific Patterns
|
|
182
|
+
|
|
183
|
+
### React Patterns
|
|
184
|
+
|
|
185
|
+
```javascript
|
|
186
|
+
const reactPatterns = {
|
|
187
|
+
hooks_rules: {
|
|
188
|
+
description: "React hooks must be called at top level",
|
|
189
|
+
pattern: /use[A-Z]\w+\(/,
|
|
190
|
+
context: "inside conditionals or loops"
|
|
191
|
+
},
|
|
192
|
+
state_management: {
|
|
193
|
+
description: "Avoid prop drilling, use context or state management",
|
|
194
|
+
pattern: /props\.\w+\.\w+\.\w+/
|
|
195
|
+
},
|
|
196
|
+
performance: {
|
|
197
|
+
description: "Use memo/useMemo for expensive computations",
|
|
198
|
+
pattern: /\.map\(.*=>.*\.map\(/
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Express Patterns
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
const expressPatterns = {
|
|
207
|
+
error_handling: {
|
|
208
|
+
description: "Express routes must have error handling",
|
|
209
|
+
pattern: /app\.(get|post|put|delete)\(/,
|
|
210
|
+
check: "next(err) in catch block"
|
|
211
|
+
},
|
|
212
|
+
async_handlers: {
|
|
213
|
+
description: "Async handlers need try-catch or wrapper",
|
|
214
|
+
pattern: /async\s*\(req,\s*res/
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Django Patterns
|
|
220
|
+
|
|
221
|
+
```javascript
|
|
222
|
+
const djangoPatterns = {
|
|
223
|
+
n_plus_one: {
|
|
224
|
+
description: "Use select_related/prefetch_related",
|
|
225
|
+
pattern: /\.objects\.(all|filter)\(\)/
|
|
226
|
+
},
|
|
227
|
+
raw_queries: {
|
|
228
|
+
description: "Avoid raw SQL, use ORM",
|
|
229
|
+
pattern: /\.raw\(|connection\.cursor\(\)/
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Pattern Application
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
function applyPatterns(findings, frameworkPatterns) {
|
|
238
|
+
if (!frameworkPatterns) return findings;
|
|
239
|
+
|
|
240
|
+
for (const pattern of Object.values(frameworkPatterns)) {
|
|
241
|
+
// Check each finding against framework patterns
|
|
242
|
+
for (const finding of findings) {
|
|
243
|
+
if (pattern.pattern.test(finding.codeQuote)) {
|
|
244
|
+
finding.frameworkContext = pattern.description;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return findings;
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Review Output Format
|
|
254
|
+
|
|
255
|
+
```markdown
|
|
256
|
+
## Agent Reports
|
|
257
|
+
|
|
258
|
+
### security-expert
|
|
259
|
+
**Files Reviewed**: X
|
|
260
|
+
**Issues Found**: Y (Z critical, A high)
|
|
261
|
+
|
|
262
|
+
Findings:
|
|
263
|
+
1. [Finding details with file:line]
|
|
264
|
+
2. [Finding details with file:line]
|
|
265
|
+
|
|
266
|
+
### performance-engineer
|
|
267
|
+
**Files Reviewed**: X
|
|
268
|
+
**Issues Found**: Y
|
|
269
|
+
|
|
270
|
+
Findings:
|
|
271
|
+
1. [Finding details with file:line]
|
|
272
|
+
|
|
273
|
+
[... per agent]
|
|
274
|
+
|
|
275
|
+
## Consolidated Summary
|
|
276
|
+
|
|
277
|
+
**Total Issues**: X
|
|
278
|
+
- Critical: Y (must fix)
|
|
279
|
+
- High: Z (should fix)
|
|
280
|
+
- Medium: A (consider)
|
|
281
|
+
- Low: B (nice to have)
|
|
282
|
+
|
|
283
|
+
**Top Files by Issue Count**:
|
|
284
|
+
1. src/api/users.ts: 5 issues
|
|
285
|
+
2. src/auth/session.ts: 3 issues
|
|
286
|
+
```
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Phase 8: GitHub Issue Creation - Reference
|
|
2
|
+
|
|
3
|
+
This file contains GitHub integration for `/project-review`.
|
|
4
|
+
|
|
5
|
+
**Parent document**: `project-review.md`
|
|
6
|
+
|
|
7
|
+
## Pre-Conditions
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Check if git and gh are available
|
|
11
|
+
GIT_AVAILABLE=$(command -v git >/dev/null 2>&1 && echo "true" || echo "false")
|
|
12
|
+
GH_AVAILABLE=$(command -v gh >/dev/null 2>&1 && echo "true" || echo "false")
|
|
13
|
+
|
|
14
|
+
# Check if this is a GitHub repository
|
|
15
|
+
IS_GITHUB_REPO="false"
|
|
16
|
+
if [ "$GIT_AVAILABLE" = "true" ]; then
|
|
17
|
+
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
|
|
18
|
+
if echo "$REMOTE_URL" | grep -q "github.com"; then
|
|
19
|
+
IS_GITHUB_REPO="true"
|
|
20
|
+
fi
|
|
21
|
+
fi
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Creating GitHub Issues
|
|
25
|
+
|
|
26
|
+
If `git` and `gh` are available, create issues for **non-security** deferred items:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
if [ "$GH_AVAILABLE" = "true" ] && [ "$IS_GITHUB_REPO" = "true" ]; then
|
|
30
|
+
echo "Creating GitHub issues for deferred items..."
|
|
31
|
+
|
|
32
|
+
# DO NOT create public issues for security-sensitive findings
|
|
33
|
+
for issue in "${DEFERRED_NON_SECURITY_ISSUES[@]}"; do
|
|
34
|
+
gh issue create \
|
|
35
|
+
--title "${issue.title}" \
|
|
36
|
+
--body "${issue.body}"
|
|
37
|
+
done
|
|
38
|
+
|
|
39
|
+
echo "Created ${#DEFERRED_NON_SECURITY_ISSUES[@]} GitHub issues"
|
|
40
|
+
fi
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Issue Format
|
|
44
|
+
|
|
45
|
+
Each created issue includes:
|
|
46
|
+
|
|
47
|
+
```markdown
|
|
48
|
+
## Issue from /project-review
|
|
49
|
+
|
|
50
|
+
**Severity**: [Critical|High|Medium|Low]
|
|
51
|
+
**Category**: [Performance|Architecture|Code Quality|Enhancement]
|
|
52
|
+
**Effort**: [Small|Medium|Large] (~X hours)
|
|
53
|
+
|
|
54
|
+
### Description
|
|
55
|
+
[Description of the issue]
|
|
56
|
+
|
|
57
|
+
### Current Behavior
|
|
58
|
+
\`\`\`[language]
|
|
59
|
+
[Code showing the problem]
|
|
60
|
+
\`\`\`
|
|
61
|
+
|
|
62
|
+
### Proposed Fix
|
|
63
|
+
[Specific remediation approach]
|
|
64
|
+
|
|
65
|
+
### Impact
|
|
66
|
+
[Why this matters]
|
|
67
|
+
|
|
68
|
+
### Files
|
|
69
|
+
- [List of affected files]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Security Issue Handling
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
╔══════════════════════════════════════════════════════════════════╗
|
|
76
|
+
║ ⚠️ SECURITY ISSUES MUST NOT BE PUBLIC ║
|
|
77
|
+
╠══════════════════════════════════════════════════════════════════╣
|
|
78
|
+
║ ║
|
|
79
|
+
║ The following must NOT be created as GitHub issues: ║
|
|
80
|
+
║ - Token/credential exposure ║
|
|
81
|
+
║ - Authentication vulnerabilities ║
|
|
82
|
+
║ - Authorization bypasses ║
|
|
83
|
+
║ - Injection vulnerabilities ║
|
|
84
|
+
║ - Any exploitable security finding ║
|
|
85
|
+
║ ║
|
|
86
|
+
║ For security issues: ║
|
|
87
|
+
║ 1. Fix immediately if possible ║
|
|
88
|
+
║ 2. Keep documented internally only ║
|
|
89
|
+
║ 3. Note in completion report (no details) ║
|
|
90
|
+
║ ║
|
|
91
|
+
╚══════════════════════════════════════════════════════════════════╝
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## TECHNICAL_DEBT.md Cleanup
|
|
95
|
+
|
|
96
|
+
After all issues are handled, remove TECHNICAL_DEBT.md:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
if [ "$GH_AVAILABLE" = "true" ] && [ "$IS_GITHUB_REPO" = "true" ]; then
|
|
100
|
+
if [ -f "TECHNICAL_DEBT.md" ]; then
|
|
101
|
+
rm TECHNICAL_DEBT.md
|
|
102
|
+
git add TECHNICAL_DEBT.md
|
|
103
|
+
git commit -m "chore: remove TECHNICAL_DEBT.md - issues tracked in GitHub
|
|
104
|
+
|
|
105
|
+
Created GitHub issues for all deferred non-security items.
|
|
106
|
+
Security-sensitive issues kept internal."
|
|
107
|
+
echo "Removed TECHNICAL_DEBT.md - issues now in GitHub"
|
|
108
|
+
fi
|
|
109
|
+
else
|
|
110
|
+
echo "TECHNICAL_DEBT.md retained - no GitHub integration"
|
|
111
|
+
fi
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Cleanup Conditions
|
|
115
|
+
|
|
116
|
+
**Remove TECHNICAL_DEBT.md when ALL true:**
|
|
117
|
+
1. `git` is available
|
|
118
|
+
2. `gh` CLI is available and authenticated
|
|
119
|
+
3. Repository has GitHub remote
|
|
120
|
+
4. All non-security issues created as GitHub issues
|
|
121
|
+
|
|
122
|
+
**Keep TECHNICAL_DEBT.md when ANY true:**
|
|
123
|
+
1. No GitHub integration available
|
|
124
|
+
2. `gh` CLI not authenticated
|
|
125
|
+
3. User requested `--create-tech-debt` flag
|
|
126
|
+
4. Security issues exist
|
|
127
|
+
|
|
128
|
+
## Final Commit
|
|
129
|
+
|
|
130
|
+
If issues were created:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
git add -A
|
|
134
|
+
git commit -m "chore: project-review complete - issues tracked in GitHub
|
|
135
|
+
|
|
136
|
+
Created X GitHub issues for deferred items:
|
|
137
|
+
- #N: [issue title]
|
|
138
|
+
- #N: [issue title]
|
|
139
|
+
|
|
140
|
+
Security-sensitive issues (Y total) kept internal.
|
|
141
|
+
Fixed Z issues in this review session."
|
|
142
|
+
```
|