omgkit 2.1.0 → 2.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.
- package/package.json +1 -1
- package/plugin/skills/SKILL_STANDARDS.md +743 -0
- package/plugin/skills/databases/mongodb/SKILL.md +797 -28
- package/plugin/skills/databases/postgresql/SKILL.md +494 -18
- package/plugin/skills/databases/prisma/SKILL.md +776 -30
- package/plugin/skills/databases/redis/SKILL.md +885 -25
- package/plugin/skills/devops/aws/SKILL.md +686 -28
- package/plugin/skills/devops/docker/SKILL.md +466 -18
- package/plugin/skills/devops/github-actions/SKILL.md +684 -29
- package/plugin/skills/devops/kubernetes/SKILL.md +621 -24
- package/plugin/skills/frameworks/django/SKILL.md +920 -20
- package/plugin/skills/frameworks/express/SKILL.md +1361 -35
- package/plugin/skills/frameworks/fastapi/SKILL.md +1260 -33
- package/plugin/skills/frameworks/laravel/SKILL.md +1244 -31
- package/plugin/skills/frameworks/nestjs/SKILL.md +1005 -26
- package/plugin/skills/frameworks/nextjs/SKILL.md +407 -44
- package/plugin/skills/frameworks/rails/SKILL.md +594 -28
- package/plugin/skills/frameworks/react/SKILL.md +1006 -32
- package/plugin/skills/frameworks/spring/SKILL.md +528 -35
- package/plugin/skills/frameworks/vue/SKILL.md +1296 -27
- package/plugin/skills/frontend/accessibility/SKILL.md +1108 -34
- package/plugin/skills/frontend/frontend-design/SKILL.md +1304 -26
- package/plugin/skills/frontend/responsive/SKILL.md +847 -21
- package/plugin/skills/frontend/shadcn-ui/SKILL.md +976 -38
- package/plugin/skills/frontend/tailwindcss/SKILL.md +831 -35
- package/plugin/skills/frontend/threejs/SKILL.md +1298 -29
- package/plugin/skills/languages/javascript/SKILL.md +935 -31
- package/plugin/skills/languages/python/SKILL.md +489 -25
- package/plugin/skills/languages/typescript/SKILL.md +379 -30
- package/plugin/skills/methodology/brainstorming/SKILL.md +597 -23
- package/plugin/skills/methodology/defense-in-depth/SKILL.md +832 -34
- package/plugin/skills/methodology/dispatching-parallel-agents/SKILL.md +665 -31
- package/plugin/skills/methodology/executing-plans/SKILL.md +556 -24
- package/plugin/skills/methodology/finishing-development-branch/SKILL.md +595 -25
- package/plugin/skills/methodology/problem-solving/SKILL.md +429 -61
- package/plugin/skills/methodology/receiving-code-review/SKILL.md +536 -24
- package/plugin/skills/methodology/requesting-code-review/SKILL.md +632 -21
- package/plugin/skills/methodology/root-cause-tracing/SKILL.md +641 -30
- package/plugin/skills/methodology/sequential-thinking/SKILL.md +262 -3
- package/plugin/skills/methodology/systematic-debugging/SKILL.md +571 -32
- package/plugin/skills/methodology/test-driven-development/SKILL.md +779 -24
- package/plugin/skills/methodology/testing-anti-patterns/SKILL.md +691 -29
- package/plugin/skills/methodology/token-optimization/SKILL.md +598 -29
- package/plugin/skills/methodology/verification-before-completion/SKILL.md +543 -22
- package/plugin/skills/methodology/writing-plans/SKILL.md +590 -18
- package/plugin/skills/omega/omega-architecture/SKILL.md +838 -39
- package/plugin/skills/omega/omega-coding/SKILL.md +636 -39
- package/plugin/skills/omega/omega-sprint/SKILL.md +855 -48
- package/plugin/skills/omega/omega-testing/SKILL.md +940 -41
- package/plugin/skills/omega/omega-thinking/SKILL.md +703 -50
- package/plugin/skills/security/better-auth/SKILL.md +1065 -28
- package/plugin/skills/security/oauth/SKILL.md +968 -31
- package/plugin/skills/security/owasp/SKILL.md +894 -33
- package/plugin/skills/testing/playwright/SKILL.md +764 -38
- package/plugin/skills/testing/pytest/SKILL.md +873 -36
- package/plugin/skills/testing/vitest/SKILL.md +980 -35
|
@@ -1,41 +1,611 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: finishing-development-branch
|
|
3
|
-
description:
|
|
3
|
+
description: Complete checklist and best practices for finishing development work and preparing for merge
|
|
4
|
+
category: methodology
|
|
5
|
+
triggers:
|
|
6
|
+
- finish branch
|
|
7
|
+
- complete feature
|
|
8
|
+
- ready for merge
|
|
9
|
+
- wrap up development
|
|
10
|
+
- finalize PR
|
|
11
|
+
- branch completion
|
|
12
|
+
- pre-merge checklist
|
|
4
13
|
---
|
|
5
14
|
|
|
6
|
-
# Finishing Development Branch
|
|
15
|
+
# Finishing Development Branch
|
|
7
16
|
|
|
8
|
-
|
|
17
|
+
Complete your development branch professionally with a **comprehensive checklist** ensuring all quality gates pass and the code is ready for merge. This skill provides frameworks for wrapping up feature work systematically.
|
|
9
18
|
|
|
10
|
-
|
|
11
|
-
- [ ] All tasks done
|
|
12
|
-
- [ ] Tests written
|
|
13
|
-
- [ ] Docs updated
|
|
14
|
-
- [ ] No TODOs left
|
|
19
|
+
## Purpose
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
- [ ] Tests passing
|
|
18
|
-
- [ ] Lint passing
|
|
19
|
-
- [ ] Type check passing
|
|
20
|
-
- [ ] Self-reviewed
|
|
21
|
+
Ship high-quality, merge-ready code:
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
23
|
+
- Ensure all acceptance criteria are met
|
|
24
|
+
- Verify code quality and test coverage
|
|
25
|
+
- Clean up technical debt and TODOs
|
|
26
|
+
- Prepare clean commit history
|
|
27
|
+
- Create comprehensive PR documentation
|
|
28
|
+
- Enable smooth code review process
|
|
29
|
+
- Reduce merge conflicts and issues
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
### 1. The Completion Checklist
|
|
34
|
+
|
|
35
|
+
```markdown
|
|
36
|
+
## Development Branch Completion Checklist
|
|
37
|
+
|
|
38
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
39
|
+
│ BRANCH COMPLETION CHECKLIST │
|
|
40
|
+
├─────────────────────────────────────────────────────────────────────────┤
|
|
41
|
+
│ │
|
|
42
|
+
│ PHASE 1: CODE COMPLETE │
|
|
43
|
+
│ ══════════════════════ │
|
|
44
|
+
│ □ All acceptance criteria implemented │
|
|
45
|
+
│ □ Edge cases handled │
|
|
46
|
+
│ □ Error handling complete │
|
|
47
|
+
│ □ No TODO/FIXME comments left unaddressed │
|
|
48
|
+
│ □ Debug code removed │
|
|
49
|
+
│ │
|
|
50
|
+
│ PHASE 2: QUALITY ASSURANCE │
|
|
51
|
+
│ ═══════════════════════════ │
|
|
52
|
+
│ □ All tests passing │
|
|
53
|
+
│ □ New tests written for new code │
|
|
54
|
+
│ □ Test coverage meets threshold │
|
|
55
|
+
│ □ Lint/format checks passing │
|
|
56
|
+
│ □ Type checking passing │
|
|
57
|
+
│ □ Security scan passing │
|
|
58
|
+
│ │
|
|
59
|
+
│ PHASE 3: DOCUMENTATION │
|
|
60
|
+
│ ═══════════════════════ │
|
|
61
|
+
│ □ README updated if needed │
|
|
62
|
+
│ □ API documentation updated │
|
|
63
|
+
│ □ Inline comments for complex logic │
|
|
64
|
+
│ □ CHANGELOG entry if required │
|
|
65
|
+
│ │
|
|
66
|
+
│ PHASE 4: GIT HYGIENE │
|
|
67
|
+
│ ═════════════════════ │
|
|
68
|
+
│ □ Branch rebased on latest main │
|
|
69
|
+
│ □ Commit history is clean and logical │
|
|
70
|
+
│ □ Commit messages follow conventions │
|
|
71
|
+
│ □ No merge conflicts │
|
|
72
|
+
│ □ Branch pushed to remote │
|
|
73
|
+
│ │
|
|
74
|
+
│ PHASE 5: PR READY │
|
|
75
|
+
│ ══════════════════ │
|
|
76
|
+
│ □ PR description is complete │
|
|
77
|
+
│ □ Screenshots/recordings if UI changes │
|
|
78
|
+
│ □ Breaking changes documented │
|
|
79
|
+
│ □ Reviewers assigned │
|
|
80
|
+
│ □ Labels applied │
|
|
81
|
+
│ │
|
|
82
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Code Completeness Verification
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
/**
|
|
89
|
+
* Verify all code-related requirements are met
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
interface CodeCompletenessCheck {
|
|
93
|
+
category: string;
|
|
94
|
+
checks: Check[];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const codeCompletenessChecks: CodeCompletenessCheck[] = [
|
|
98
|
+
{
|
|
99
|
+
category: 'Acceptance Criteria',
|
|
100
|
+
checks: [
|
|
101
|
+
{ name: 'All user stories implemented', automated: false },
|
|
102
|
+
{ name: 'All requirements from ticket addressed', automated: false },
|
|
103
|
+
{ name: 'Feature works as specified', automated: false }
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
category: 'Edge Cases',
|
|
108
|
+
checks: [
|
|
109
|
+
{ name: 'Empty/null input handled', automated: true },
|
|
110
|
+
{ name: 'Boundary conditions covered', automated: true },
|
|
111
|
+
{ name: 'Error states handled gracefully', automated: true },
|
|
112
|
+
{ name: 'Concurrent access considered', automated: false }
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
category: 'Code Cleanup',
|
|
117
|
+
checks: [
|
|
118
|
+
{ name: 'No console.log statements', automated: true },
|
|
119
|
+
{ name: 'No debugger statements', automated: true },
|
|
120
|
+
{ name: 'No commented-out code', automated: true },
|
|
121
|
+
{ name: 'No hardcoded secrets', automated: true }
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
// Automated checks implementation
|
|
127
|
+
async function runCodeCleanupChecks(files: string[]): Promise<CheckResult[]> {
|
|
128
|
+
const results: CheckResult[] = [];
|
|
129
|
+
|
|
130
|
+
// Check for debug statements
|
|
131
|
+
const debugPatterns = [
|
|
132
|
+
{ pattern: /console\.(log|debug|info)\(/g, message: 'Console statement found' },
|
|
133
|
+
{ pattern: /debugger;/g, message: 'Debugger statement found' },
|
|
134
|
+
{ pattern: /\/\/.*TODO/gi, message: 'TODO comment found' },
|
|
135
|
+
{ pattern: /\/\/.*FIXME/gi, message: 'FIXME comment found' },
|
|
136
|
+
{ pattern: /\/\*[\s\S]*?\*\/|\/\/.*/g, message: 'Commented code block' }
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
for (const file of files) {
|
|
140
|
+
const content = await readFile(file);
|
|
141
|
+
|
|
142
|
+
for (const { pattern, message } of debugPatterns) {
|
|
143
|
+
const matches = content.match(pattern);
|
|
144
|
+
if (matches) {
|
|
145
|
+
results.push({
|
|
146
|
+
file,
|
|
147
|
+
status: 'warning',
|
|
148
|
+
message: `${message}: ${matches.length} occurrences`
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return results;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// TODO scanner
|
|
158
|
+
async function scanForTODOs(directory: string): Promise<TODO[]> {
|
|
159
|
+
const todos: TODO[] = [];
|
|
160
|
+
|
|
161
|
+
const files = await glob('**/*.{ts,tsx,js,jsx}', { cwd: directory });
|
|
162
|
+
|
|
163
|
+
for (const file of files) {
|
|
164
|
+
const content = await readFile(path.join(directory, file));
|
|
165
|
+
const lines = content.split('\n');
|
|
166
|
+
|
|
167
|
+
lines.forEach((line, index) => {
|
|
168
|
+
const todoMatch = line.match(/\/\/\s*(TODO|FIXME|HACK|XXX):?\s*(.*)/i);
|
|
169
|
+
if (todoMatch) {
|
|
170
|
+
todos.push({
|
|
171
|
+
file,
|
|
172
|
+
line: index + 1,
|
|
173
|
+
type: todoMatch[1].toUpperCase(),
|
|
174
|
+
message: todoMatch[2].trim(),
|
|
175
|
+
priority: determinePriority(todoMatch[1])
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return todos;
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 3. Quality Assurance Verification
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
/**
|
|
189
|
+
* Run all quality assurance checks
|
|
190
|
+
*/
|
|
191
|
+
|
|
192
|
+
interface QACheckResult {
|
|
193
|
+
category: string;
|
|
194
|
+
passed: boolean;
|
|
195
|
+
details: string;
|
|
196
|
+
fixCommand?: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async function runQualityChecks(): Promise<QACheckResult[]> {
|
|
200
|
+
const results: QACheckResult[] = [];
|
|
201
|
+
|
|
202
|
+
// 1. Test execution
|
|
203
|
+
const testResult = await runCommand('npm test');
|
|
204
|
+
results.push({
|
|
205
|
+
category: 'Tests',
|
|
206
|
+
passed: testResult.exitCode === 0,
|
|
207
|
+
details: testResult.passed
|
|
208
|
+
? 'All tests passing'
|
|
209
|
+
: `${testResult.failures} test(s) failing`,
|
|
210
|
+
fixCommand: 'npm test -- --watch'
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// 2. Test coverage
|
|
214
|
+
const coverageResult = await runCommand('npm run test:coverage');
|
|
215
|
+
const coverage = parseCoverageOutput(coverageResult.stdout);
|
|
216
|
+
results.push({
|
|
217
|
+
category: 'Coverage',
|
|
218
|
+
passed: coverage.total >= 80,
|
|
219
|
+
details: `Coverage: ${coverage.total}% (threshold: 80%)`,
|
|
220
|
+
fixCommand: 'npm run test:coverage -- --verbose'
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// 3. Linting
|
|
224
|
+
const lintResult = await runCommand('npm run lint');
|
|
225
|
+
results.push({
|
|
226
|
+
category: 'Linting',
|
|
227
|
+
passed: lintResult.exitCode === 0,
|
|
228
|
+
details: lintResult.passed
|
|
229
|
+
? 'No lint errors'
|
|
230
|
+
: `${lintResult.errors} error(s) found`,
|
|
231
|
+
fixCommand: 'npm run lint -- --fix'
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// 4. Type checking
|
|
235
|
+
const typeResult = await runCommand('npm run type-check');
|
|
236
|
+
results.push({
|
|
237
|
+
category: 'Type Check',
|
|
238
|
+
passed: typeResult.exitCode === 0,
|
|
239
|
+
details: typeResult.passed
|
|
240
|
+
? 'No type errors'
|
|
241
|
+
: `${typeResult.errors} type error(s)`,
|
|
242
|
+
fixCommand: 'npm run type-check'
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// 5. Build
|
|
246
|
+
const buildResult = await runCommand('npm run build');
|
|
247
|
+
results.push({
|
|
248
|
+
category: 'Build',
|
|
249
|
+
passed: buildResult.exitCode === 0,
|
|
250
|
+
details: buildResult.passed
|
|
251
|
+
? 'Build successful'
|
|
252
|
+
: 'Build failed',
|
|
253
|
+
fixCommand: 'npm run build'
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// 6. Security scan
|
|
257
|
+
const securityResult = await runCommand('npm audit');
|
|
258
|
+
results.push({
|
|
259
|
+
category: 'Security',
|
|
260
|
+
passed: !securityResult.stdout.includes('high') &&
|
|
261
|
+
!securityResult.stdout.includes('critical'),
|
|
262
|
+
details: securityResult.passed
|
|
263
|
+
? 'No high/critical vulnerabilities'
|
|
264
|
+
: 'Security vulnerabilities found',
|
|
265
|
+
fixCommand: 'npm audit fix'
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
return results;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Generate QA report
|
|
272
|
+
function generateQAReport(results: QACheckResult[]): string {
|
|
273
|
+
const passed = results.filter(r => r.passed);
|
|
274
|
+
const failed = results.filter(r => !r.passed);
|
|
275
|
+
|
|
276
|
+
let report = `## Quality Assurance Report\n\n`;
|
|
277
|
+
|
|
278
|
+
if (failed.length === 0) {
|
|
279
|
+
report += `✅ All ${results.length} checks passed!\n\n`;
|
|
280
|
+
} else {
|
|
281
|
+
report += `❌ ${failed.length}/${results.length} checks failed\n\n`;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
report += `### Results\n\n`;
|
|
285
|
+
for (const result of results) {
|
|
286
|
+
const icon = result.passed ? '✅' : '❌';
|
|
287
|
+
report += `${icon} **${result.category}**: ${result.details}\n`;
|
|
288
|
+
if (!result.passed && result.fixCommand) {
|
|
289
|
+
report += ` Fix: \`${result.fixCommand}\`\n`;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return report;
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### 4. Git Hygiene
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
/**
|
|
301
|
+
* Clean up git history and prepare for merge
|
|
302
|
+
*/
|
|
303
|
+
|
|
304
|
+
interface GitStatus {
|
|
305
|
+
branch: string;
|
|
306
|
+
ahead: number;
|
|
307
|
+
behind: number;
|
|
308
|
+
conflicts: string[];
|
|
309
|
+
uncommitted: string[];
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
async function prepareGitForMerge(): Promise<GitPrepResult> {
|
|
313
|
+
const results: string[] = [];
|
|
314
|
+
|
|
315
|
+
// 1. Fetch latest from remote
|
|
316
|
+
await runCommand('git fetch origin main');
|
|
317
|
+
results.push('Fetched latest from origin/main');
|
|
318
|
+
|
|
319
|
+
// 2. Check current branch status
|
|
320
|
+
const status = await getGitStatus();
|
|
321
|
+
|
|
322
|
+
// 3. Rebase if behind main
|
|
323
|
+
if (status.behind > 0) {
|
|
324
|
+
await runCommand('git rebase origin/main');
|
|
325
|
+
results.push(`Rebased on origin/main (was ${status.behind} commits behind)`);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// 4. Check for conflicts
|
|
329
|
+
const conflicts = await checkMergeConflicts();
|
|
330
|
+
if (conflicts.length > 0) {
|
|
331
|
+
return {
|
|
332
|
+
success: false,
|
|
333
|
+
results,
|
|
334
|
+
error: `Merge conflicts in: ${conflicts.join(', ')}`
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// 5. Push to remote
|
|
339
|
+
await runCommand(`git push origin ${status.branch} --force-with-lease`);
|
|
340
|
+
results.push('Pushed to remote');
|
|
341
|
+
|
|
342
|
+
return { success: true, results };
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Clean commit history
|
|
346
|
+
async function cleanCommitHistory(): Promise<void> {
|
|
347
|
+
// Get commits since branching from main
|
|
348
|
+
const commits = await getCommitsSinceMain();
|
|
349
|
+
|
|
350
|
+
console.log(`\nCommit History (${commits.length} commits):`);
|
|
351
|
+
commits.forEach((c, i) => {
|
|
352
|
+
console.log(` ${i + 1}. ${c.hash.slice(0, 7)} - ${c.message}`);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Check for commits that should be squashed
|
|
356
|
+
const fixupCandidates = commits.filter(c =>
|
|
357
|
+
c.message.toLowerCase().includes('fix') ||
|
|
358
|
+
c.message.toLowerCase().includes('wip') ||
|
|
359
|
+
c.message.toLowerCase().includes('temp')
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
if (fixupCandidates.length > 0) {
|
|
363
|
+
console.log('\n⚠️ Consider squashing these commits:');
|
|
364
|
+
fixupCandidates.forEach(c => {
|
|
365
|
+
console.log(` - ${c.hash.slice(0, 7)}: ${c.message}`);
|
|
366
|
+
});
|
|
367
|
+
console.log('\nRun: git rebase -i HEAD~' + commits.length);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Conventional commit validation
|
|
372
|
+
function validateCommitMessages(commits: Commit[]): ValidationResult[] {
|
|
373
|
+
const conventionalPattern = /^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\(.+\))?: .{1,72}/;
|
|
374
|
+
|
|
375
|
+
return commits.map(commit => ({
|
|
376
|
+
commit: commit.hash,
|
|
377
|
+
message: commit.message,
|
|
378
|
+
valid: conventionalPattern.test(commit.message),
|
|
379
|
+
suggestion: !conventionalPattern.test(commit.message)
|
|
380
|
+
? 'Use conventional commits: type(scope): message'
|
|
381
|
+
: undefined
|
|
382
|
+
}));
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### 5. PR Preparation
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
/**
|
|
390
|
+
* Prepare comprehensive PR documentation
|
|
391
|
+
*/
|
|
392
|
+
|
|
393
|
+
interface PRContext {
|
|
394
|
+
branch: string;
|
|
395
|
+
baseBranch: string;
|
|
396
|
+
commits: Commit[];
|
|
397
|
+
changedFiles: ChangedFile[];
|
|
398
|
+
ticket?: string;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
async function generatePRDescription(context: PRContext): Promise<string> {
|
|
402
|
+
const { commits, changedFiles, ticket } = context;
|
|
403
|
+
|
|
404
|
+
// Analyze changes
|
|
405
|
+
const changeAnalysis = analyzeChanges(changedFiles);
|
|
406
|
+
|
|
407
|
+
// Generate description
|
|
408
|
+
let description = `## Summary\n\n`;
|
|
409
|
+
|
|
410
|
+
// Link to ticket if available
|
|
411
|
+
if (ticket) {
|
|
412
|
+
description += `Closes ${ticket}\n\n`;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// What changed
|
|
416
|
+
description += `## Changes\n\n`;
|
|
417
|
+
for (const commit of commits) {
|
|
418
|
+
description += `- ${commit.message}\n`;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Files changed summary
|
|
422
|
+
description += `\n## Files Changed\n\n`;
|
|
423
|
+
description += `- **Added:** ${changeAnalysis.added} files\n`;
|
|
424
|
+
description += `- **Modified:** ${changeAnalysis.modified} files\n`;
|
|
425
|
+
description += `- **Deleted:** ${changeAnalysis.deleted} files\n`;
|
|
426
|
+
|
|
427
|
+
// Testing section
|
|
428
|
+
description += `\n## Testing\n\n`;
|
|
429
|
+
description += `- [x] Unit tests added/updated\n`;
|
|
430
|
+
description += `- [x] Integration tests pass\n`;
|
|
431
|
+
description += `- [ ] Manual testing completed\n`;
|
|
432
|
+
|
|
433
|
+
// Screenshots placeholder for UI changes
|
|
434
|
+
if (changeAnalysis.hasUIChanges) {
|
|
435
|
+
description += `\n## Screenshots\n\n`;
|
|
436
|
+
description += `<!-- Add screenshots of UI changes -->\n`;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Breaking changes
|
|
440
|
+
if (changeAnalysis.hasBreakingChanges) {
|
|
441
|
+
description += `\n## ⚠️ Breaking Changes\n\n`;
|
|
442
|
+
description += `<!-- Document any breaking changes -->\n`;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Checklist
|
|
446
|
+
description += `\n## Checklist\n\n`;
|
|
447
|
+
description += `- [x] Code follows style guidelines\n`;
|
|
448
|
+
description += `- [x] Self-review completed\n`;
|
|
449
|
+
description += `- [x] Tests added for new functionality\n`;
|
|
450
|
+
description += `- [x] Documentation updated\n`;
|
|
451
|
+
description += `- [x] No unresolved TODOs\n`;
|
|
452
|
+
|
|
453
|
+
return description;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Create PR with gh CLI
|
|
457
|
+
async function createPullRequest(context: PRContext): Promise<string> {
|
|
458
|
+
const description = await generatePRDescription(context);
|
|
459
|
+
const title = generatePRTitle(context);
|
|
460
|
+
|
|
461
|
+
const result = await runCommand(`
|
|
462
|
+
gh pr create \\
|
|
463
|
+
--title "${title}" \\
|
|
464
|
+
--body "${escapeForShell(description)}" \\
|
|
465
|
+
--base ${context.baseBranch} \\
|
|
466
|
+
--head ${context.branch}
|
|
467
|
+
`);
|
|
468
|
+
|
|
469
|
+
return result.stdout.trim(); // Returns PR URL
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### 6. Final Verification Script
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
/**
|
|
477
|
+
* Complete verification before marking PR ready
|
|
478
|
+
*/
|
|
479
|
+
|
|
480
|
+
async function runFinalVerification(): Promise<VerificationReport> {
|
|
481
|
+
console.log('🔍 Running final verification...\n');
|
|
482
|
+
|
|
483
|
+
const report: VerificationReport = {
|
|
484
|
+
passed: true,
|
|
485
|
+
checks: []
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
// Phase 1: Code completeness
|
|
489
|
+
console.log('📝 Phase 1: Code Completeness');
|
|
490
|
+
const todos = await scanForTODOs('.');
|
|
491
|
+
report.checks.push({
|
|
492
|
+
name: 'No blocking TODOs',
|
|
493
|
+
passed: todos.filter(t => t.priority === 'high').length === 0,
|
|
494
|
+
details: todos.length > 0
|
|
495
|
+
? `${todos.length} TODOs found`
|
|
496
|
+
: 'No TODOs'
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
const debugCode = await runCodeCleanupChecks(await getChangedFiles());
|
|
500
|
+
report.checks.push({
|
|
501
|
+
name: 'No debug code',
|
|
502
|
+
passed: debugCode.filter(r => r.status === 'error').length === 0,
|
|
503
|
+
details: debugCode.length > 0
|
|
504
|
+
? 'Debug statements found'
|
|
505
|
+
: 'Clean'
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
// Phase 2: Quality
|
|
509
|
+
console.log('✅ Phase 2: Quality Assurance');
|
|
510
|
+
const qaResults = await runQualityChecks();
|
|
511
|
+
report.checks.push(...qaResults.map(r => ({
|
|
512
|
+
name: r.category,
|
|
513
|
+
passed: r.passed,
|
|
514
|
+
details: r.details
|
|
515
|
+
})));
|
|
516
|
+
|
|
517
|
+
// Phase 3: Git
|
|
518
|
+
console.log('🔀 Phase 3: Git Hygiene');
|
|
519
|
+
const gitResult = await prepareGitForMerge();
|
|
520
|
+
report.checks.push({
|
|
521
|
+
name: 'Git ready for merge',
|
|
522
|
+
passed: gitResult.success,
|
|
523
|
+
details: gitResult.error || 'Ready'
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
// Calculate overall status
|
|
527
|
+
report.passed = report.checks.every(c => c.passed);
|
|
528
|
+
|
|
529
|
+
// Print report
|
|
530
|
+
console.log('\n' + '='.repeat(50));
|
|
531
|
+
console.log('FINAL VERIFICATION REPORT');
|
|
532
|
+
console.log('='.repeat(50) + '\n');
|
|
533
|
+
|
|
534
|
+
for (const check of report.checks) {
|
|
535
|
+
const icon = check.passed ? '✅' : '❌';
|
|
536
|
+
console.log(`${icon} ${check.name}: ${check.details}`);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
console.log('\n' + '='.repeat(50));
|
|
540
|
+
if (report.passed) {
|
|
541
|
+
console.log('✅ ALL CHECKS PASSED - Ready for PR!');
|
|
542
|
+
} else {
|
|
543
|
+
console.log('❌ SOME CHECKS FAILED - Please fix before PR');
|
|
544
|
+
}
|
|
545
|
+
console.log('='.repeat(50));
|
|
546
|
+
|
|
547
|
+
return report;
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
## Use Cases
|
|
552
|
+
|
|
553
|
+
### Complete Feature Branch Workflow
|
|
32
554
|
|
|
33
|
-
## Final Steps
|
|
34
555
|
```bash
|
|
556
|
+
# 1. Run final verification
|
|
557
|
+
npm run verify
|
|
558
|
+
|
|
559
|
+
# 2. Clean up commit history
|
|
560
|
+
git log --oneline main..HEAD # Review commits
|
|
561
|
+
git rebase -i main # Squash/fixup as needed
|
|
562
|
+
|
|
563
|
+
# 3. Rebase on latest main
|
|
35
564
|
git fetch origin main
|
|
36
565
|
git rebase origin/main
|
|
566
|
+
|
|
567
|
+
# 4. Run tests one more time
|
|
37
568
|
npm test
|
|
38
569
|
npm run build
|
|
39
|
-
|
|
40
|
-
|
|
570
|
+
|
|
571
|
+
# 5. Push changes
|
|
572
|
+
git push origin feature-branch --force-with-lease
|
|
573
|
+
|
|
574
|
+
# 6. Create PR
|
|
575
|
+
gh pr create --title "feat: add user authentication" --body-file pr-template.md
|
|
576
|
+
|
|
577
|
+
# 7. Request review
|
|
578
|
+
gh pr ready
|
|
579
|
+
gh pr edit --add-reviewer teammate1,teammate2
|
|
41
580
|
```
|
|
581
|
+
|
|
582
|
+
## Best Practices
|
|
583
|
+
|
|
584
|
+
### Do's
|
|
585
|
+
|
|
586
|
+
- **Run all checks locally** before pushing
|
|
587
|
+
- **Rebase on latest main** to avoid conflicts
|
|
588
|
+
- **Squash WIP commits** into meaningful units
|
|
589
|
+
- **Write clear commit messages** following conventions
|
|
590
|
+
- **Include screenshots** for UI changes
|
|
591
|
+
- **Link to tickets** in PR description
|
|
592
|
+
- **Self-review your diff** before requesting review
|
|
593
|
+
- **Test in a clean environment** if possible
|
|
594
|
+
|
|
595
|
+
### Don'ts
|
|
596
|
+
|
|
597
|
+
- Don't push broken code
|
|
598
|
+
- Don't leave TODOs unaddressed
|
|
599
|
+
- Don't skip tests to save time
|
|
600
|
+
- Don't force push without `--force-with-lease`
|
|
601
|
+
- Don't create PRs without descriptions
|
|
602
|
+
- Don't forget to update documentation
|
|
603
|
+
- Don't leave debug statements in code
|
|
604
|
+
- Don't ignore linting warnings
|
|
605
|
+
|
|
606
|
+
## References
|
|
607
|
+
|
|
608
|
+
- [Conventional Commits](https://www.conventionalcommits.org/)
|
|
609
|
+
- [GitHub Flow](https://guides.github.com/introduction/flow/)
|
|
610
|
+
- [Git Rebase Documentation](https://git-scm.com/docs/git-rebase)
|
|
611
|
+
- [GitHub CLI Documentation](https://cli.github.com/manual/)
|