fraim-framework 2.0.26 โ†’ 2.0.30

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 (104) hide show
  1. package/.github/workflows/deploy-fraim.yml +1 -1
  2. package/dist/registry/scripts/build-scripts-generator.js +205 -0
  3. package/dist/registry/scripts/cleanup-branch.js +258 -0
  4. package/dist/registry/scripts/evaluate-code-quality.js +66 -0
  5. package/dist/registry/scripts/exec-with-timeout.js +142 -0
  6. package/dist/registry/scripts/fraim-config.js +61 -0
  7. package/dist/registry/scripts/generate-engagement-emails.js +630 -0
  8. package/dist/registry/scripts/generic-issues-api.js +100 -0
  9. package/dist/registry/scripts/newsletter-helpers.js +731 -0
  10. package/dist/registry/scripts/openapi-generator.js +664 -0
  11. package/dist/registry/scripts/performance/profile-server.js +390 -0
  12. package/dist/registry/scripts/run-thank-you-workflow.js +92 -0
  13. package/dist/registry/scripts/send-newsletter-simple.js +85 -0
  14. package/dist/registry/scripts/send-thank-you-emails.js +54 -0
  15. package/dist/registry/scripts/validate-openapi-limits.js +311 -0
  16. package/dist/registry/scripts/validate-test-coverage.js +262 -0
  17. package/dist/registry/scripts/verify-test-coverage.js +66 -0
  18. package/dist/src/cli/commands/init.js +14 -12
  19. package/dist/src/cli/commands/sync.js +19 -2
  20. package/dist/src/cli/fraim.js +24 -22
  21. package/dist/src/cli/setup/first-run.js +13 -6
  22. package/dist/src/fraim/config-loader.js +0 -8
  23. package/dist/src/fraim/db-service.js +26 -15
  24. package/dist/src/fraim/issues.js +67 -0
  25. package/dist/src/fraim/setup-wizard.js +1 -69
  26. package/dist/src/fraim/types.js +0 -11
  27. package/dist/src/fraim-mcp-server.js +272 -18
  28. package/dist/src/utils/git-utils.js +1 -1
  29. package/dist/src/utils/version-utils.js +32 -0
  30. package/dist/tests/debug-tools.js +79 -0
  31. package/dist/tests/esm-compat.js +11 -0
  32. package/dist/tests/test-chalk-esm-issue.js +159 -0
  33. package/dist/tests/test-chalk-real-world.js +265 -0
  34. package/dist/tests/test-chalk-regression.js +327 -0
  35. package/dist/tests/test-chalk-resolution-issue.js +304 -0
  36. package/dist/tests/test-cli.js +0 -2
  37. package/dist/tests/test-fraim-install-chalk-issue.js +254 -0
  38. package/dist/tests/test-fraim-issues.js +59 -0
  39. package/dist/tests/test-genericization.js +1 -3
  40. package/dist/tests/test-mcp-connection.js +166 -0
  41. package/dist/tests/test-mcp-issue-integration.js +144 -0
  42. package/dist/tests/test-mcp-lifecycle-methods.js +312 -0
  43. package/dist/tests/test-node-compatibility.js +71 -0
  44. package/dist/tests/test-npm-install.js +66 -0
  45. package/dist/tests/test-npm-resolution-diagnostic.js +140 -0
  46. package/dist/tests/test-session-rehydration.js +145 -0
  47. package/dist/tests/test-standalone.js +2 -8
  48. package/dist/tests/test-sync-version-update.js +93 -0
  49. package/dist/tests/test-telemetry.js +190 -0
  50. package/package.json +10 -8
  51. package/registry/agent-guardrails.md +62 -54
  52. package/registry/rules/agent-success-criteria.md +52 -0
  53. package/registry/rules/agent-testing-guidelines.md +502 -502
  54. package/registry/rules/communication.md +121 -121
  55. package/registry/rules/continuous-learning.md +54 -54
  56. package/registry/rules/ephemeral-execution.md +10 -5
  57. package/registry/rules/hitl-ppe-record-analysis.md +302 -302
  58. package/registry/rules/local-development.md +251 -251
  59. package/registry/rules/software-development-lifecycle.md +104 -104
  60. package/registry/rules/successful-debugging-patterns.md +482 -478
  61. package/registry/rules/telemetry.md +67 -0
  62. package/registry/scripts/build-scripts-generator.ts +216 -215
  63. package/registry/scripts/cleanup-branch.ts +303 -284
  64. package/registry/scripts/code-quality-check.sh +559 -559
  65. package/registry/scripts/detect-tautological-tests.sh +38 -38
  66. package/registry/scripts/evaluate-code-quality.ts +1 -1
  67. package/registry/scripts/generate-engagement-emails.ts +744 -744
  68. package/registry/scripts/generic-issues-api.ts +110 -150
  69. package/registry/scripts/newsletter-helpers.ts +874 -874
  70. package/registry/scripts/openapi-generator.ts +695 -693
  71. package/registry/scripts/performance/profile-server.ts +5 -3
  72. package/registry/scripts/prep-issue.sh +468 -455
  73. package/registry/scripts/validate-openapi-limits.ts +366 -365
  74. package/registry/scripts/validate-test-coverage.ts +280 -280
  75. package/registry/scripts/verify-pr-comments.sh +70 -70
  76. package/registry/scripts/verify-test-coverage.ts +1 -1
  77. package/registry/templates/bootstrap/ARCHITECTURE-TEMPLATE.md +53 -53
  78. package/registry/templates/evidence/Implementation-BugEvidence.md +85 -85
  79. package/registry/templates/evidence/Implementation-FeatureEvidence.md +120 -120
  80. package/registry/templates/marketing/HBR-ARTICLE-TEMPLATE.md +66 -0
  81. package/registry/workflows/bootstrap/create-architecture.md +2 -2
  82. package/registry/workflows/bootstrap/evaluate-code-quality.md +3 -3
  83. package/registry/workflows/bootstrap/verify-test-coverage.md +2 -2
  84. package/registry/workflows/customer-development/insight-analysis.md +156 -156
  85. package/registry/workflows/customer-development/interview-preparation.md +421 -421
  86. package/registry/workflows/customer-development/strategic-brainstorming.md +146 -146
  87. package/registry/workflows/customer-development/thank-customers.md +193 -191
  88. package/registry/workflows/customer-development/weekly-newsletter.md +362 -352
  89. package/registry/workflows/improve-fraim/contribute.md +32 -0
  90. package/registry/workflows/improve-fraim/file-issue.md +32 -0
  91. package/registry/workflows/marketing/hbr-article.md +73 -0
  92. package/registry/workflows/performance/analyze-performance.md +63 -59
  93. package/registry/workflows/product-building/design.md +3 -2
  94. package/registry/workflows/product-building/implement.md +4 -3
  95. package/registry/workflows/product-building/prep-issue.md +28 -17
  96. package/registry/workflows/product-building/resolve.md +3 -2
  97. package/registry/workflows/product-building/retrospect.md +3 -2
  98. package/registry/workflows/product-building/spec.md +5 -4
  99. package/registry/workflows/product-building/test.md +3 -2
  100. package/registry/workflows/quality-assurance/iterative-improvement-cycle.md +562 -562
  101. package/registry/workflows/replicate/website-discovery-analysis.md +3 -3
  102. package/registry/workflows/reviewer/review-implementation-vs-design-spec.md +632 -632
  103. package/registry/workflows/reviewer/review-implementation-vs-feature-spec.md +669 -669
  104. package/tsconfig.json +2 -1
@@ -1,284 +1,303 @@
1
- #!/usr/bin/env npx tsx
2
-
3
- import { execSync } from 'child_process';
4
- import dotenv from 'dotenv';
5
-
6
- // Load environment variables
7
- dotenv.config({ override: true });
8
-
9
- interface CleanupOptions {
10
- branchName?: string;
11
- force?: boolean;
12
- skipProjectCleanup?: boolean;
13
- skipGit?: boolean;
14
- }
15
-
16
- class BranchCleanup {
17
- private options: CleanupOptions;
18
-
19
- constructor(options: CleanupOptions = {}) {
20
- this.options = {
21
- branchName: options.branchName,
22
- force: options.force || false,
23
- skipProjectCleanup: options.skipProjectCleanup || false,
24
- skipGit: options.skipGit || false,
25
- };
26
- }
27
-
28
- private async insertYourCodeHere(branchName: string): Promise<void> {
29
- const { extractIssueNumber } = require('../../src/utils/git-utils');
30
- const branchPattern = "branch_" + extractIssueNumber(branchName) + "%";
31
- this.log(`Calling MongoDB cleanup script with pattern: ${branchPattern}`);
32
- await this.executeCommand(
33
- `npx tsx scripts/database/cleanup-mongo-schemas.ts "${branchPattern}"`,
34
- 'Run project-specific cleanup script'
35
- );
36
- }
37
-
38
-
39
- private log(message: string, level: 'info' | 'warn' | 'error' | 'success' = 'info') {
40
- const timestamp = new Date().toISOString();
41
- const prefix = {
42
- info: 'โ„น๏ธ ',
43
- warn: 'โš ๏ธ ',
44
- error: 'โŒ',
45
- success: 'โœ…'
46
- }[level];
47
-
48
- console.log(`${prefix} [${timestamp}] ${message}`);
49
- }
50
-
51
- private async executeCommand(command: string, description: string): Promise<string> {
52
- this.log(`Executing: ${description}`);
53
-
54
- try {
55
- const result = execSync(command, {
56
- encoding: 'utf8',
57
- stdio: 'pipe',
58
- cwd: process.cwd()
59
- });
60
- this.log(`Success: ${description}`, 'success');
61
- return result;
62
- } catch (error: any) {
63
- this.log(`Failed: ${description} - ${error.message}`, 'error');
64
- throw error;
65
- }
66
- }
67
-
68
- private async getCurrentBranch(): Promise<string> {
69
- try {
70
- const result = await this.executeCommand('git branch --show-current', 'Get current branch');
71
- return result.trim();
72
- } catch (error) {
73
- this.log('Could not determine current branch', 'warn');
74
- return 'unknown';
75
- }
76
- }
77
-
78
- private async getBranchName(): Promise<string> {
79
- if (this.options.branchName) {
80
- return this.options.branchName;
81
- }
82
-
83
- const currentBranch = await this.getCurrentBranch();
84
- if (currentBranch === 'master' || currentBranch === 'main') {
85
- throw new Error('Cannot cleanup master/main branch. Please specify a feature branch name.');
86
- }
87
-
88
- return currentBranch;
89
- }
90
-
91
- private async checkBranchExists(branchName: string, remote: boolean = false): Promise<boolean> {
92
- try {
93
- const command = remote
94
- ? `git ls-remote --heads origin ${branchName}`
95
- : `git branch --list ${branchName}`;
96
-
97
- const result = await this.executeCommand(command, `Check if ${remote ? 'remote' : 'local'} branch exists`);
98
- return result.trim().length > 0;
99
- } catch (error) {
100
- return false;
101
- }
102
- }
103
-
104
- private async doProjectSpecificCleanup(branchName: string): Promise<void> {
105
- try {
106
- if (this.options.skipProjectCleanup) {
107
- this.log('Skipping project-specific cleanup', 'warn');
108
- return;
109
- }
110
-
111
- this.log('Starting project-specific cleanup...');
112
-
113
- await this.insertYourCodeHere(branchName);
114
-
115
- this.log('Project-specific cleanup completed successfully', 'success');
116
- } catch (error: any) {
117
- this.log(`Project-specific cleanup failed: ${error.message}`, 'error');
118
- if (!this.options.force) {
119
- throw error;
120
- }
121
- }
122
- }
123
-
124
- private async cleanupGitBranches(branchName: string): Promise<void> {
125
- if (this.options.skipGit) {
126
- this.log('Skipping Git cleanup', 'warn');
127
- return;
128
- }
129
-
130
- this.log(`Starting Git branch cleanup for: ${branchName}`);
131
-
132
- // Check if we're on the branch we want to delete
133
- const currentBranch = await this.getCurrentBranch();
134
- if (currentBranch === branchName) {
135
- this.log(`Currently on branch ${branchName}, switching to master first`, 'warn');
136
- await this.executeCommand('git checkout master', 'Switch to master branch');
137
- }
138
-
139
- // Delete remote branch
140
- const remoteExists = await this.checkBranchExists(branchName, true);
141
- if (remoteExists) {
142
- this.log(`Deleting remote branch: origin/${branchName}`);
143
- await this.executeCommand(`git push origin --delete ${branchName}`, `Delete remote branch ${branchName}`);
144
- } else {
145
- this.log(`Remote branch origin/${branchName} does not exist`, 'info');
146
- }
147
-
148
- // Delete local branch
149
- const localExists = await this.checkBranchExists(branchName, false);
150
- if (localExists) {
151
- this.log(`Deleting local branch: ${branchName}`);
152
- await this.executeCommand(`git branch -D ${branchName}`, `Delete local branch ${branchName}`);
153
- } else {
154
- this.log(`Local branch ${branchName} does not exist`, 'info');
155
- }
156
-
157
- // Clean up any untracked files
158
- this.log('Cleaning up untracked files...');
159
- await this.executeCommand('git clean -fd', 'Remove untracked files and directories');
160
-
161
- // Reset any uncommitted changes
162
- this.log('Resetting uncommitted changes...');
163
- await this.executeCommand('git reset --hard HEAD', 'Reset to HEAD');
164
-
165
- this.log('Git branch cleanup completed', 'success');
166
- }
167
-
168
-
169
- private async verifyCleanup(branchName: string): Promise<void> {
170
- this.log('Verifying cleanup...');
171
-
172
- // Verify branch deletion
173
- const remoteExists = await this.checkBranchExists(branchName, true);
174
- const localExists = await this.checkBranchExists(branchName, false);
175
-
176
- if (remoteExists || localExists) {
177
- this.log(`Warning: Branch ${branchName} still exists (remote: ${remoteExists}, local: ${localExists})`, 'warn');
178
- } else {
179
- this.log(`Branch ${branchName} successfully deleted`, 'success');
180
- }
181
-
182
- // Verify we're on master
183
- const currentBranch = await this.getCurrentBranch();
184
- if (currentBranch === 'master' || currentBranch === 'main') {
185
- this.log('Currently on master/main branch', 'success');
186
- } else {
187
- this.log(`Warning: Not on master branch, currently on ${currentBranch}`, 'warn');
188
- }
189
-
190
- this.log('Cleanup verification completed', 'success');
191
- }
192
-
193
- async cleanup(): Promise<void> {
194
- try {
195
- this.log('๐Ÿš€ Starting branch cleanup process...');
196
-
197
- const branchName = await this.getBranchName();
198
- this.log(`Target branch: ${branchName}`);
199
-
200
- // Step 1: Project-specific cleanup
201
- await this.doProjectSpecificCleanup(branchName);
202
-
203
- // Step 2: Git branch cleanup
204
- await this.cleanupGitBranches(branchName);
205
-
206
- // Step 3: Verification
207
- await this.verifyCleanup(branchName);
208
-
209
- this.log('๐ŸŽ‰ Branch cleanup completed successfully!', 'success');
210
-
211
- } catch (error: any) {
212
- this.log(`Cleanup failed: ${error.message}`, 'error');
213
- if (!this.options.force) {
214
- process.exit(1);
215
- }
216
- }
217
- }
218
- }
219
-
220
- // Parse command line arguments
221
- const args = process.argv.slice(2);
222
- const options: CleanupOptions = {};
223
-
224
- // Parse arguments
225
- for (let i = 0; i < args.length; i++) {
226
- const arg = args[i];
227
-
228
- switch (arg) {
229
- case '--branch':
230
- case '-b':
231
- options.branchName = args[++i];
232
- break;
233
- case '--force':
234
- case '-f':
235
- options.force = true;
236
- break;
237
- case '--skip-project-cleanup':
238
- options.skipProjectCleanup = true;
239
- break;
240
- case '--skip-git':
241
- options.skipGit = true;
242
- break;
243
- case '--help':
244
- case '-h':
245
- console.log(`
246
- ๐Ÿงน Branch Cleanup Script
247
-
248
- Usage:
249
- npx tsx .ai-agents/scripts/cleanup-branch.ts [options]
250
-
251
- Options:
252
- --branch, -b <name> Specific branch name to cleanup (default: current branch)
253
- --force, -f Continue even if some operations fail
254
- --skip-project-cleanup Skip project-specific cleanup
255
- --skip-git Skip Git branch deletion
256
- --help, -h Show this help message
257
-
258
- Examples:
259
- # Cleanup current branch with default settings
260
- npx tsx .ai-agents/scripts/cleanup-branch.ts
261
-
262
- # Cleanup specific branch
263
- npx tsx .ai-agents/scripts/cleanup-branch.ts --branch feature/123
264
-
265
- # Force cleanup even if some operations fail
266
- npx tsx .ai-agents/scripts/cleanup-branch.ts --force
267
-
268
- # Skip project-specific cleanup (only do Git cleanup)
269
- npx tsx .ai-agents/scripts/cleanup-branch.ts --skip-project-cleanup
270
-
271
- This script performs the following cleanup operations:
272
- 1. ๐Ÿ—„๏ธ Project-specific cleanup (calls existing cleanup-mongo-schemas.ts with branch-based pattern)
273
- 2. ๐ŸŒฟ Git branch deletion (remote and local)
274
- 3. โœ… Verification of cleanup completion
275
-
276
- โš ๏ธ WARNING: This script will permanently delete branches and data!
277
- `);
278
- process.exit(0);
279
- }
280
- }
281
-
282
- // Run the cleanup
283
- const cleanup = new BranchCleanup(options);
284
- cleanup.cleanup();
1
+ #!/usr/bin/env npx tsx
2
+
3
+ import { execSync } from 'child_process';
4
+ import dotenv from 'dotenv';
5
+
6
+ // Load environment variables
7
+ dotenv.config({ override: true });
8
+
9
+ interface CleanupOptions {
10
+ branchName?: string;
11
+ force?: boolean;
12
+ skipProjectCleanup?: boolean;
13
+ skipGit?: boolean;
14
+ }
15
+
16
+ class BranchCleanup {
17
+ private options: CleanupOptions;
18
+
19
+ constructor(options: CleanupOptions = {}) {
20
+ this.options = {
21
+ branchName: options.branchName,
22
+ force: options.force || false,
23
+ skipProjectCleanup: options.skipProjectCleanup || false,
24
+ skipGit: options.skipGit || false,
25
+ };
26
+ }
27
+
28
+ private async insertYourCodeHere(branchName: string): Promise<void> {
29
+ const { extractIssueNumber } = require('../../src/utils/git-utils');
30
+ const branchPattern = "branch_" + extractIssueNumber(branchName) + "%";
31
+ this.log(`Attempting to fetch and run DB cleanup for pattern: ${branchPattern}`);
32
+
33
+ // Historically this called: npx tsx scripts/database/cleanup-mongo-schemas.ts
34
+ // In FRAIM 2.0, we should fetch it if possible, or skip if it's an internal-only script
35
+ // that doesn't exist in the registry but was incorrectly referenced.
36
+
37
+ // NOTE: In this specific case, cleanup-mongo-schemas.ts is likely an internal script.
38
+ // If it's not in the registry, get_fraim_file will fail.
39
+ // For now, we fix the path to be more agnostic or explicitly documented as a dependency.
40
+
41
+ try {
42
+ // NOTE: Users should define their own cleanup script location in .fraim/config.json
43
+ // or the agent should fetch it. For now, we try to run it from a standard location
44
+ // if it exists, but we don't hardcode it as a requirement for the script to run.
45
+ const cleanupScript = process.env.FRAIM_PROJECT_CLEANUP_SCRIPT || (['scripts', 'database', 'cleanup-mongo-schemas.ts'].join('/'));
46
+ this.log(`Checking for project cleanup script: ${cleanupScript}`);
47
+
48
+ await this.executeCommand(
49
+ `npx tsx ${cleanupScript} "${branchPattern}"`,
50
+ 'Run project-specific cleanup script'
51
+ );
52
+ } catch (e) {
53
+ this.log('Skipping project-specific cleanup (script not found or failed).', 'info');
54
+ }
55
+ }
56
+
57
+
58
+ private log(message: string, level: 'info' | 'warn' | 'error' | 'success' = 'info') {
59
+ const timestamp = new Date().toISOString();
60
+ const prefix = {
61
+ info: 'โ„น๏ธ ',
62
+ warn: 'โš ๏ธ ',
63
+ error: 'โŒ',
64
+ success: 'โœ…'
65
+ }[level];
66
+
67
+ console.log(`${prefix} [${timestamp}] ${message}`);
68
+ }
69
+
70
+ private async executeCommand(command: string, description: string): Promise<string> {
71
+ this.log(`Executing: ${description}`);
72
+
73
+ try {
74
+ const result = execSync(command, {
75
+ encoding: 'utf8',
76
+ stdio: 'pipe',
77
+ cwd: process.cwd()
78
+ });
79
+ this.log(`Success: ${description}`, 'success');
80
+ return result;
81
+ } catch (error: any) {
82
+ this.log(`Failed: ${description} - ${error.message}`, 'error');
83
+ throw error;
84
+ }
85
+ }
86
+
87
+ private async getCurrentBranch(): Promise<string> {
88
+ try {
89
+ const result = await this.executeCommand('git branch --show-current', 'Get current branch');
90
+ return result.trim();
91
+ } catch (error) {
92
+ this.log('Could not determine current branch', 'warn');
93
+ return 'unknown';
94
+ }
95
+ }
96
+
97
+ private async getBranchName(): Promise<string> {
98
+ if (this.options.branchName) {
99
+ return this.options.branchName;
100
+ }
101
+
102
+ const currentBranch = await this.getCurrentBranch();
103
+ if (currentBranch === 'master' || currentBranch === 'main') {
104
+ throw new Error('Cannot cleanup master/main branch. Please specify a feature branch name.');
105
+ }
106
+
107
+ return currentBranch;
108
+ }
109
+
110
+ private async checkBranchExists(branchName: string, remote: boolean = false): Promise<boolean> {
111
+ try {
112
+ const command = remote
113
+ ? `git ls-remote --heads origin ${branchName}`
114
+ : `git branch --list ${branchName}`;
115
+
116
+ const result = await this.executeCommand(command, `Check if ${remote ? 'remote' : 'local'} branch exists`);
117
+ return result.trim().length > 0;
118
+ } catch (error) {
119
+ return false;
120
+ }
121
+ }
122
+
123
+ private async doProjectSpecificCleanup(branchName: string): Promise<void> {
124
+ try {
125
+ if (this.options.skipProjectCleanup) {
126
+ this.log('Skipping project-specific cleanup', 'warn');
127
+ return;
128
+ }
129
+
130
+ this.log('Starting project-specific cleanup...');
131
+
132
+ await this.insertYourCodeHere(branchName);
133
+
134
+ this.log('Project-specific cleanup completed successfully', 'success');
135
+ } catch (error: any) {
136
+ this.log(`Project-specific cleanup failed: ${error.message}`, 'error');
137
+ if (!this.options.force) {
138
+ throw error;
139
+ }
140
+ }
141
+ }
142
+
143
+ private async cleanupGitBranches(branchName: string): Promise<void> {
144
+ if (this.options.skipGit) {
145
+ this.log('Skipping Git cleanup', 'warn');
146
+ return;
147
+ }
148
+
149
+ this.log(`Starting Git branch cleanup for: ${branchName}`);
150
+
151
+ // Check if we're on the branch we want to delete
152
+ const currentBranch = await this.getCurrentBranch();
153
+ if (currentBranch === branchName) {
154
+ this.log(`Currently on branch ${branchName}, switching to master first`, 'warn');
155
+ await this.executeCommand('git checkout master', 'Switch to master branch');
156
+ }
157
+
158
+ // Delete remote branch
159
+ const remoteExists = await this.checkBranchExists(branchName, true);
160
+ if (remoteExists) {
161
+ this.log(`Deleting remote branch: origin/${branchName}`);
162
+ await this.executeCommand(`git push origin --delete ${branchName}`, `Delete remote branch ${branchName}`);
163
+ } else {
164
+ this.log(`Remote branch origin/${branchName} does not exist`, 'info');
165
+ }
166
+
167
+ // Delete local branch
168
+ const localExists = await this.checkBranchExists(branchName, false);
169
+ if (localExists) {
170
+ this.log(`Deleting local branch: ${branchName}`);
171
+ await this.executeCommand(`git branch -D ${branchName}`, `Delete local branch ${branchName}`);
172
+ } else {
173
+ this.log(`Local branch ${branchName} does not exist`, 'info');
174
+ }
175
+
176
+ // Clean up any untracked files
177
+ this.log('Cleaning up untracked files...');
178
+ await this.executeCommand('git clean -fd', 'Remove untracked files and directories');
179
+
180
+ // Reset any uncommitted changes
181
+ this.log('Resetting uncommitted changes...');
182
+ await this.executeCommand('git reset --hard HEAD', 'Reset to HEAD');
183
+
184
+ this.log('Git branch cleanup completed', 'success');
185
+ }
186
+
187
+
188
+ private async verifyCleanup(branchName: string): Promise<void> {
189
+ this.log('Verifying cleanup...');
190
+
191
+ // Verify branch deletion
192
+ const remoteExists = await this.checkBranchExists(branchName, true);
193
+ const localExists = await this.checkBranchExists(branchName, false);
194
+
195
+ if (remoteExists || localExists) {
196
+ this.log(`Warning: Branch ${branchName} still exists (remote: ${remoteExists}, local: ${localExists})`, 'warn');
197
+ } else {
198
+ this.log(`Branch ${branchName} successfully deleted`, 'success');
199
+ }
200
+
201
+ // Verify we're on master
202
+ const currentBranch = await this.getCurrentBranch();
203
+ if (currentBranch === 'master' || currentBranch === 'main') {
204
+ this.log('Currently on master/main branch', 'success');
205
+ } else {
206
+ this.log(`Warning: Not on master branch, currently on ${currentBranch}`, 'warn');
207
+ }
208
+
209
+ this.log('Cleanup verification completed', 'success');
210
+ }
211
+
212
+ async cleanup(): Promise<void> {
213
+ try {
214
+ this.log('๐Ÿš€ Starting branch cleanup process...');
215
+
216
+ const branchName = await this.getBranchName();
217
+ this.log(`Target branch: ${branchName}`);
218
+
219
+ // Step 1: Project-specific cleanup
220
+ await this.doProjectSpecificCleanup(branchName);
221
+
222
+ // Step 2: Git branch cleanup
223
+ await this.cleanupGitBranches(branchName);
224
+
225
+ // Step 3: Verification
226
+ await this.verifyCleanup(branchName);
227
+
228
+ this.log('๐ŸŽ‰ Branch cleanup completed successfully!', 'success');
229
+
230
+ } catch (error: any) {
231
+ this.log(`Cleanup failed: ${error.message}`, 'error');
232
+ if (!this.options.force) {
233
+ process.exit(1);
234
+ }
235
+ }
236
+ }
237
+ }
238
+
239
+ // Parse command line arguments
240
+ const args = process.argv.slice(2);
241
+ const options: CleanupOptions = {};
242
+
243
+ // Parse arguments
244
+ for (let i = 0; i < args.length; i++) {
245
+ const arg = args[i];
246
+
247
+ switch (arg) {
248
+ case '--branch':
249
+ case '-b':
250
+ options.branchName = args[++i];
251
+ break;
252
+ case '--force':
253
+ case '-f':
254
+ options.force = true;
255
+ break;
256
+ case '--skip-project-cleanup':
257
+ options.skipProjectCleanup = true;
258
+ break;
259
+ case '--skip-git':
260
+ options.skipGit = true;
261
+ break;
262
+ case '--help':
263
+ case '-h':
264
+ console.log(`
265
+ ๐Ÿงน Branch Cleanup Script
266
+
267
+ Usage:
268
+ npx tsx scripts/cleanup-branch.ts [options]
269
+
270
+ Options:
271
+ --branch, -b <name> Specific branch name to cleanup (default: current branch)
272
+ --force, -f Continue even if some operations fail
273
+ --skip-project-cleanup Skip project-specific cleanup
274
+ --skip-git Skip Git branch deletion
275
+ --help, -h Show this help message
276
+
277
+ Examples:
278
+ # Cleanup current branch with default settings
279
+ npx tsx <cleanup-script-path>
280
+
281
+ # Cleanup specific branch
282
+ npx tsx <cleanup-script-path> --branch feature/123
283
+
284
+ # Force cleanup even if some operations fail
285
+ npx tsx <cleanup-script-path> --force
286
+
287
+ # Skip project-specific cleanup (only do Git cleanup)
288
+ npx tsx <cleanup-script-path> --skip-project-cleanup
289
+
290
+ This script performs the following cleanup operations:
291
+ 1. ๐Ÿ—„๏ธ Project-specific cleanup (calls configured cleanup script)
292
+ 2. ๐ŸŒฟ Git branch deletion (remote and local)
293
+ 3. โœ… Verification of cleanup completion
294
+
295
+ โš ๏ธ WARNING: This script will permanently delete branches and data!
296
+ `);
297
+ process.exit(0);
298
+ }
299
+ }
300
+
301
+ // Run the cleanup
302
+ const cleanup = new BranchCleanup(options);
303
+ cleanup.cleanup();