edsger 0.13.0 → 0.13.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/dist/phases/code-refine/context.d.ts +1 -0
- package/dist/phases/code-refine/context.js +14 -2
- package/dist/phases/code-refine-verification/github.d.ts +7 -0
- package/dist/phases/code-refine-verification/github.js +46 -0
- package/dist/phases/code-refine-verification/index.js +47 -22
- package/dist/phases/code-refine-verification/types.d.ts +1 -0
- package/dist/utils/git-branch-manager.d.ts +4 -0
- package/dist/utils/git-branch-manager.js +61 -0
- package/package.json +1 -1
- package/.claude/settings.local.json +0 -28
- package/dist/api/features/__tests__/regression-prevention.test.d.ts +0 -5
- package/dist/api/features/__tests__/regression-prevention.test.js +0 -338
- package/dist/api/features/__tests__/status-updater.integration.test.d.ts +0 -5
- package/dist/api/features/__tests__/status-updater.integration.test.js +0 -497
- package/dist/commands/workflow/pipeline-runner.d.ts +0 -17
- package/dist/commands/workflow/pipeline-runner.js +0 -393
- package/dist/commands/workflow/runner.d.ts +0 -26
- package/dist/commands/workflow/runner.js +0 -119
- package/dist/commands/workflow/workflow-runner.d.ts +0 -26
- package/dist/commands/workflow/workflow-runner.js +0 -119
- package/dist/phases/code-implementation/analyzer-helpers.d.ts +0 -28
- package/dist/phases/code-implementation/analyzer-helpers.js +0 -177
- package/dist/phases/code-implementation/analyzer.d.ts +0 -32
- package/dist/phases/code-implementation/analyzer.js +0 -629
- package/dist/phases/code-implementation/context-fetcher.d.ts +0 -17
- package/dist/phases/code-implementation/context-fetcher.js +0 -86
- package/dist/phases/code-implementation/mcp-server.d.ts +0 -1
- package/dist/phases/code-implementation/mcp-server.js +0 -93
- package/dist/phases/code-implementation/prompts-improvement.d.ts +0 -5
- package/dist/phases/code-implementation/prompts-improvement.js +0 -108
- package/dist/phases/code-implementation-verification/verifier.d.ts +0 -31
- package/dist/phases/code-implementation-verification/verifier.js +0 -196
- package/dist/phases/code-refine/analyzer.d.ts +0 -41
- package/dist/phases/code-refine/analyzer.js +0 -561
- package/dist/phases/code-refine/context-fetcher.d.ts +0 -94
- package/dist/phases/code-refine/context-fetcher.js +0 -423
- package/dist/phases/code-refine-verification/analysis/llm-analyzer.d.ts +0 -22
- package/dist/phases/code-refine-verification/analysis/llm-analyzer.js +0 -134
- package/dist/phases/code-refine-verification/verifier.d.ts +0 -47
- package/dist/phases/code-refine-verification/verifier.js +0 -597
- package/dist/phases/code-review/analyzer.d.ts +0 -29
- package/dist/phases/code-review/analyzer.js +0 -363
- package/dist/phases/code-review/context-fetcher.d.ts +0 -92
- package/dist/phases/code-review/context-fetcher.js +0 -296
- package/dist/phases/feature-analysis/analyzer-helpers.d.ts +0 -10
- package/dist/phases/feature-analysis/analyzer-helpers.js +0 -47
- package/dist/phases/feature-analysis/analyzer.d.ts +0 -11
- package/dist/phases/feature-analysis/analyzer.js +0 -208
- package/dist/phases/feature-analysis/context-fetcher.d.ts +0 -26
- package/dist/phases/feature-analysis/context-fetcher.js +0 -134
- package/dist/phases/feature-analysis/http-fallback.d.ts +0 -20
- package/dist/phases/feature-analysis/http-fallback.js +0 -95
- package/dist/phases/feature-analysis/mcp-server.d.ts +0 -1
- package/dist/phases/feature-analysis/mcp-server.js +0 -144
- package/dist/phases/feature-analysis/prompts-improvement.d.ts +0 -8
- package/dist/phases/feature-analysis/prompts-improvement.js +0 -109
- package/dist/phases/feature-analysis-verification/verifier.d.ts +0 -37
- package/dist/phases/feature-analysis-verification/verifier.js +0 -147
- package/dist/phases/technical-design/analyzer-helpers.d.ts +0 -25
- package/dist/phases/technical-design/analyzer-helpers.js +0 -39
- package/dist/phases/technical-design/analyzer.d.ts +0 -21
- package/dist/phases/technical-design/analyzer.js +0 -461
- package/dist/phases/technical-design/context-fetcher.d.ts +0 -12
- package/dist/phases/technical-design/context-fetcher.js +0 -39
- package/dist/phases/technical-design/http-fallback.d.ts +0 -17
- package/dist/phases/technical-design/http-fallback.js +0 -151
- package/dist/phases/technical-design/mcp-server.d.ts +0 -1
- package/dist/phases/technical-design/mcp-server.js +0 -157
- package/dist/phases/technical-design/prompts-improvement.d.ts +0 -5
- package/dist/phases/technical-design/prompts-improvement.js +0 -93
- package/dist/phases/technical-design-verification/verifier.d.ts +0 -53
- package/dist/phases/technical-design-verification/verifier.js +0 -170
- package/dist/workflow-runner/config/phase-configs.d.ts +0 -5
- package/dist/workflow-runner/config/phase-configs.js +0 -120
- package/dist/workflow-runner/core/feature-filter.d.ts +0 -16
- package/dist/workflow-runner/core/feature-filter.js +0 -46
- package/dist/workflow-runner/core/index.d.ts +0 -8
- package/dist/workflow-runner/core/index.js +0 -12
- package/dist/workflow-runner/core/pipeline-evaluator.d.ts +0 -24
- package/dist/workflow-runner/core/pipeline-evaluator.js +0 -32
- package/dist/workflow-runner/core/state-manager.d.ts +0 -24
- package/dist/workflow-runner/core/state-manager.js +0 -42
- package/dist/workflow-runner/core/workflow-logger.d.ts +0 -20
- package/dist/workflow-runner/core/workflow-logger.js +0 -65
- package/dist/workflow-runner/executors/phase-executor.d.ts +0 -8
- package/dist/workflow-runner/executors/phase-executor.js +0 -248
- package/dist/workflow-runner/feature-workflow-runner.d.ts +0 -26
- package/dist/workflow-runner/feature-workflow-runner.js +0 -119
- package/dist/workflow-runner/index.d.ts +0 -2
- package/dist/workflow-runner/index.js +0 -2
- package/dist/workflow-runner/pipeline-runner.d.ts +0 -17
- package/dist/workflow-runner/pipeline-runner.js +0 -393
- package/dist/workflow-runner/workflow-processor.d.ts +0 -54
- package/dist/workflow-runner/workflow-processor.js +0 -170
|
@@ -30,8 +30,19 @@ export async function fetchPRReviews(octokit, owner, repo, prNumber, verbose) {
|
|
|
30
30
|
repo,
|
|
31
31
|
pull_number: prNumber,
|
|
32
32
|
});
|
|
33
|
-
// Filter for reviews that request changes
|
|
34
|
-
const requestChangesReviews = reviews
|
|
33
|
+
// Filter for reviews that request changes and map to our interface
|
|
34
|
+
const requestChangesReviews = reviews
|
|
35
|
+
.filter((review) => review.state === 'CHANGES_REQUESTED')
|
|
36
|
+
.map((review) => ({
|
|
37
|
+
id: review.id,
|
|
38
|
+
node_id: review.node_id, // REST API also returns node_id
|
|
39
|
+
user: {
|
|
40
|
+
login: review.user?.login || 'unknown',
|
|
41
|
+
},
|
|
42
|
+
body: review.body ?? null,
|
|
43
|
+
state: review.state,
|
|
44
|
+
submitted_at: review.submitted_at ?? null,
|
|
45
|
+
}));
|
|
35
46
|
if (verbose) {
|
|
36
47
|
console.log(`✅ Found ${requestChangesReviews.length} reviews requesting changes`);
|
|
37
48
|
}
|
|
@@ -117,6 +128,7 @@ export async function fetchPRDataGraphQL(octokit, owner, repo, prNumber, verbose
|
|
|
117
128
|
// Transform GraphQL reviews to our interface
|
|
118
129
|
const reviews = (pullRequest.reviews.nodes || []).map((review) => ({
|
|
119
130
|
id: review.databaseId,
|
|
131
|
+
node_id: review.id, // GraphQL Node ID for mutations
|
|
120
132
|
user: {
|
|
121
133
|
login: review.author?.login || 'unknown',
|
|
122
134
|
},
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Octokit } from '@octokit/rest';
|
|
6
6
|
import { ReviewThread, PRFileChange } from './types.js';
|
|
7
|
+
import { PRReview } from '../code-refine/context.js';
|
|
7
8
|
/**
|
|
8
9
|
* Fetch complete file content from a specific ref (branch/commit)
|
|
9
10
|
*/
|
|
@@ -21,3 +22,9 @@ export declare function fetchUnresolvedReviewThreads(octokit: Octokit, owner: st
|
|
|
21
22
|
* Mark review threads as resolved using GraphQL API
|
|
22
23
|
*/
|
|
23
24
|
export declare function resolveReviewThreads(octokit: Octokit, threads: ReviewThread[], verbose?: boolean): Promise<number>;
|
|
25
|
+
/**
|
|
26
|
+
* Dismiss pull request reviews using GraphQL API
|
|
27
|
+
* This is used to automatically dismiss "CHANGES_REQUESTED" reviews
|
|
28
|
+
* after all feedback has been addressed by code refine
|
|
29
|
+
*/
|
|
30
|
+
export declare function dismissReviews(octokit: Octokit, reviews: PRReview[], resolvedCommentsCount: number, verbose?: boolean): Promise<number>;
|
|
@@ -188,3 +188,49 @@ export async function resolveReviewThreads(octokit, threads, verbose) {
|
|
|
188
188
|
}
|
|
189
189
|
return markedCount;
|
|
190
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Dismiss pull request reviews using GraphQL API
|
|
193
|
+
* This is used to automatically dismiss "CHANGES_REQUESTED" reviews
|
|
194
|
+
* after all feedback has been addressed by code refine
|
|
195
|
+
*/
|
|
196
|
+
export async function dismissReviews(octokit, reviews, resolvedCommentsCount, verbose) {
|
|
197
|
+
let dismissedCount = 0;
|
|
198
|
+
for (const review of reviews) {
|
|
199
|
+
try {
|
|
200
|
+
if (verbose) {
|
|
201
|
+
logInfo(`🔄 Dismissing review ${review.id} by @${review.user.login}...`);
|
|
202
|
+
}
|
|
203
|
+
// Build dismiss message explaining what was resolved
|
|
204
|
+
const message = `All feedback has been addressed by automated code refine.\n\n` +
|
|
205
|
+
`✅ Resolved ${resolvedCommentsCount} review comment(s).\n\n` +
|
|
206
|
+
`Please re-review if you disagree with any changes.`;
|
|
207
|
+
const mutation = `
|
|
208
|
+
mutation($pullRequestReviewId: ID!, $message: String!) {
|
|
209
|
+
dismissPullRequestReview(input: {
|
|
210
|
+
pullRequestReviewId: $pullRequestReviewId
|
|
211
|
+
message: $message
|
|
212
|
+
}) {
|
|
213
|
+
pullRequestReview {
|
|
214
|
+
id
|
|
215
|
+
state
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
`;
|
|
220
|
+
await octokit.graphql(mutation, {
|
|
221
|
+
pullRequestReviewId: review.node_id,
|
|
222
|
+
message,
|
|
223
|
+
});
|
|
224
|
+
dismissedCount++;
|
|
225
|
+
if (verbose) {
|
|
226
|
+
logInfo(`✅ Dismissed review ${review.id} by @${review.user.login}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
if (verbose) {
|
|
231
|
+
logError(`Failed to dismiss review ${review.id} by @${review.user.login}: ${error}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return dismissedCount;
|
|
236
|
+
}
|
|
@@ -7,7 +7,7 @@ import { Octokit } from '@octokit/rest';
|
|
|
7
7
|
import { logInfo, logError } from '../../utils/logger.js';
|
|
8
8
|
import { parsePullRequestUrl, fetchPRReviews } from '../code-refine/context.js';
|
|
9
9
|
import { getFeature } from '../../api/features/get-feature.js';
|
|
10
|
-
import { fetchPRFileChanges, fetchUnresolvedReviewThreads, resolveReviewThreads, } from './github.js';
|
|
10
|
+
import { fetchPRFileChanges, fetchUnresolvedReviewThreads, resolveReviewThreads, dismissReviews, } from './github.js';
|
|
11
11
|
import { analyzeAllThreads } from './llm-analyzer.js';
|
|
12
12
|
// Re-export types for backward compatibility
|
|
13
13
|
export * from './types.js';
|
|
@@ -65,31 +65,52 @@ export async function verifyAndResolveComments(options) {
|
|
|
65
65
|
const addressedThreads = threadAnalysisResults.filter((result) => result.analysis.isAddressed);
|
|
66
66
|
const trulyUnresolvedThreads = threadAnalysisResults.filter((result) => !result.analysis.isAddressed);
|
|
67
67
|
// Auto-resolve threads that LLM determined are addressed
|
|
68
|
+
let totalResolvedComments = 0;
|
|
68
69
|
if (addressedThreads.length > 0) {
|
|
69
70
|
if (verbose) {
|
|
70
71
|
logInfo(`✅ Auto-resolving ${addressedThreads.length} threads that have been addressed...`);
|
|
71
72
|
}
|
|
72
73
|
const resolvedCount = await resolveReviewThreads(octokit, addressedThreads.map((r) => r.thread), verbose);
|
|
74
|
+
totalResolvedComments = resolvedCount;
|
|
73
75
|
if (verbose) {
|
|
74
76
|
logInfo(`✅ Successfully resolved ${resolvedCount} threads`);
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
|
-
// Check reviews - they need to be dismissed
|
|
78
|
-
const
|
|
79
|
+
// Check reviews - they need to be dismissed if all comments are addressed
|
|
80
|
+
const changesRequestedReviews = reviews.filter((review) => review.state === 'CHANGES_REQUESTED');
|
|
79
81
|
if (verbose) {
|
|
80
82
|
logInfo(`📊 Review Threads: ${trulyUnresolvedThreads.length} still unresolved (after LLM analysis)`);
|
|
81
83
|
if (reviews.length > 0) {
|
|
82
|
-
logInfo(`📊 Reviews: ${
|
|
84
|
+
logInfo(`📊 Reviews: ${changesRequestedReviews.length} requesting changes`);
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
|
-
// If all threads are truly resolved
|
|
86
|
-
|
|
87
|
+
// If all threads are truly resolved, dismiss the "CHANGES_REQUESTED" reviews
|
|
88
|
+
let dismissedReviewsCount = 0;
|
|
89
|
+
if (trulyUnresolvedThreads.length === 0 &&
|
|
90
|
+
changesRequestedReviews.length > 0) {
|
|
91
|
+
if (verbose) {
|
|
92
|
+
logInfo(`🔄 All comments addressed. Dismissing ${changesRequestedReviews.length} review(s) requesting changes...`);
|
|
93
|
+
}
|
|
94
|
+
dismissedReviewsCount = await dismissReviews(octokit, changesRequestedReviews, totalResolvedComments, verbose);
|
|
95
|
+
if (verbose) {
|
|
96
|
+
logInfo(`✅ Successfully dismissed ${dismissedReviewsCount} review(s)`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// If all threads are truly resolved (after LLM analysis) AND reviews are dismissed, success
|
|
100
|
+
const allReviewsDismissed = changesRequestedReviews.length === 0 ||
|
|
101
|
+
dismissedReviewsCount === changesRequestedReviews.length;
|
|
102
|
+
if (trulyUnresolvedThreads.length === 0 && allReviewsDismissed) {
|
|
87
103
|
if (verbose) {
|
|
88
104
|
logInfo('✅ All comments have been addressed! All review threads are resolved.');
|
|
89
105
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
106
|
+
let successMessage = 'All review comments have been addressed and resolved';
|
|
107
|
+
if (dismissedReviewsCount > 0) {
|
|
108
|
+
successMessage = `All reviews and review comments have been addressed. ${dismissedReviewsCount} review(s) dismissed.`;
|
|
109
|
+
}
|
|
110
|
+
else if (reviews.length > 0) {
|
|
111
|
+
successMessage =
|
|
112
|
+
'All reviews and review comments have been addressed and resolved';
|
|
113
|
+
}
|
|
93
114
|
return {
|
|
94
115
|
status: 'success',
|
|
95
116
|
message: successMessage,
|
|
@@ -101,15 +122,18 @@ export async function verifyAndResolveComments(options) {
|
|
|
101
122
|
resolvedComments: addressedThreads.length,
|
|
102
123
|
unresolvedComments: 0,
|
|
103
124
|
commentsMarkedResolved: addressedThreads.length,
|
|
125
|
+
dismissedReviews: dismissedReviewsCount,
|
|
104
126
|
},
|
|
105
127
|
};
|
|
106
128
|
}
|
|
107
129
|
else {
|
|
108
130
|
// Verification failed - build detailed info with specific failure reasons from LLM analysis
|
|
131
|
+
// Calculate remaining reviews that weren't dismissed
|
|
132
|
+
const remainingReviewsCount = changesRequestedReviews.length - dismissedReviewsCount;
|
|
109
133
|
if (verbose) {
|
|
110
|
-
if (
|
|
111
|
-
logInfo(`⚠️ ${
|
|
112
|
-
|
|
134
|
+
if (remainingReviewsCount > 0) {
|
|
135
|
+
logInfo(`⚠️ ${remainingReviewsCount} reviews still requesting changes (failed to dismiss)`);
|
|
136
|
+
changesRequestedReviews.forEach((review) => {
|
|
113
137
|
logInfo(` - Review ${review.id} by @${review.user.login}`);
|
|
114
138
|
if (review.body) {
|
|
115
139
|
logInfo(` ${review.body.substring(0, 100)}...`);
|
|
@@ -138,10 +162,10 @@ export async function verifyAndResolveComments(options) {
|
|
|
138
162
|
suggestions.push(`${index + 1}. [${firstComment.path}:${firstComment.line || '?'}] by @${firstComment.author.login}: ${result.analysis.reason}`);
|
|
139
163
|
}
|
|
140
164
|
});
|
|
141
|
-
// Add review-specific suggestions if any
|
|
142
|
-
if (
|
|
143
|
-
suggestions.push(`\n${
|
|
144
|
-
|
|
165
|
+
// Add review-specific suggestions if any reviews failed to dismiss
|
|
166
|
+
if (remainingReviewsCount > 0) {
|
|
167
|
+
suggestions.push(`\n${remainingReviewsCount} review(s) requesting changes could not be automatically dismissed:`);
|
|
168
|
+
changesRequestedReviews.forEach((review) => {
|
|
145
169
|
suggestions.push(` - @${review.user.login}: ${review.body ? review.body.substring(0, 150) : 'No details provided'}${review.body && review.body.length > 150 ? '...' : ''}`);
|
|
146
170
|
});
|
|
147
171
|
}
|
|
@@ -158,7 +182,7 @@ export async function verifyAndResolveComments(options) {
|
|
|
158
182
|
url: firstComment.url,
|
|
159
183
|
};
|
|
160
184
|
});
|
|
161
|
-
const unresolvedReviewDetails =
|
|
185
|
+
const unresolvedReviewDetails = changesRequestedReviews.map((review) => ({
|
|
162
186
|
reviewId: review.id,
|
|
163
187
|
author: review.user.login,
|
|
164
188
|
state: review.state,
|
|
@@ -166,11 +190,11 @@ export async function verifyAndResolveComments(options) {
|
|
|
166
190
|
submittedAt: review.submitted_at,
|
|
167
191
|
}));
|
|
168
192
|
let errorMessage = '';
|
|
169
|
-
if (
|
|
170
|
-
errorMessage = `${
|
|
193
|
+
if (remainingReviewsCount > 0 && trulyUnresolvedThreads.length > 0) {
|
|
194
|
+
errorMessage = `${remainingReviewsCount} reviews and ${trulyUnresolvedThreads.length} review threads still need to be addressed (based on LLM analysis)`;
|
|
171
195
|
}
|
|
172
|
-
else if (
|
|
173
|
-
errorMessage = `${
|
|
196
|
+
else if (remainingReviewsCount > 0) {
|
|
197
|
+
errorMessage = `${remainingReviewsCount} reviews could not be dismissed`;
|
|
174
198
|
}
|
|
175
199
|
else {
|
|
176
200
|
errorMessage = `${trulyUnresolvedThreads.length} review comments still need to be addressed (based on LLM analysis)`;
|
|
@@ -181,11 +205,12 @@ export async function verifyAndResolveComments(options) {
|
|
|
181
205
|
data: {
|
|
182
206
|
featureId,
|
|
183
207
|
totalReviews: reviews.length,
|
|
184
|
-
unresolvedReviews:
|
|
208
|
+
unresolvedReviews: remainingReviewsCount,
|
|
185
209
|
totalComments: unresolvedThreads.length, // Original count before LLM analysis
|
|
186
210
|
resolvedComments: addressedThreads.length, // LLM determined these are addressed
|
|
187
211
|
unresolvedComments: trulyUnresolvedThreads.length, // LLM determined these still need work
|
|
188
212
|
commentsMarkedResolved: addressedThreads.length,
|
|
213
|
+
dismissedReviews: dismissedReviewsCount,
|
|
189
214
|
suggestions,
|
|
190
215
|
unresolvedReviewDetails,
|
|
191
216
|
unresolvedCommentDetails,
|
|
@@ -22,6 +22,10 @@ export declare function resetUncommittedChanges(verbose?: boolean): void;
|
|
|
22
22
|
* Check if a Git branch exists locally
|
|
23
23
|
*/
|
|
24
24
|
export declare function branchExists(branch: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Check if a remote branch exists
|
|
27
|
+
*/
|
|
28
|
+
export declare function remoteBranchExists(branch: string): boolean;
|
|
25
29
|
/**
|
|
26
30
|
* Switch to a specific Git branch, creating it if it doesn't exist
|
|
27
31
|
*/
|
|
@@ -76,6 +76,23 @@ export function branchExists(branch) {
|
|
|
76
76
|
return false;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if a remote branch exists
|
|
81
|
+
*/
|
|
82
|
+
export function remoteBranchExists(branch) {
|
|
83
|
+
try {
|
|
84
|
+
// Fetch remote refs first to ensure we have latest info
|
|
85
|
+
execSync('git fetch origin --prune', { encoding: 'utf-8', stdio: 'pipe' });
|
|
86
|
+
execSync(`git rev-parse --verify origin/${branch}`, {
|
|
87
|
+
encoding: 'utf-8',
|
|
88
|
+
stdio: 'pipe',
|
|
89
|
+
});
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
79
96
|
/**
|
|
80
97
|
* Switch to a specific Git branch, creating it if it doesn't exist
|
|
81
98
|
*/
|
|
@@ -179,6 +196,50 @@ export function switchToFeatureBranchAndRebase(featureBranch, baseBranch = 'main
|
|
|
179
196
|
if (getCurrentBranch() !== featureBranch) {
|
|
180
197
|
switchToBranch(featureBranch, verbose);
|
|
181
198
|
}
|
|
199
|
+
// Sync with remote feature branch if it exists
|
|
200
|
+
// This handles the case where the branch was pushed from another machine
|
|
201
|
+
try {
|
|
202
|
+
// Check for uncommitted changes and reset if found before any git operations
|
|
203
|
+
if (hasUncommittedChanges()) {
|
|
204
|
+
if (verbose) {
|
|
205
|
+
logInfo(`⚠️ Found uncommitted changes. Resetting to clean state before sync...`);
|
|
206
|
+
}
|
|
207
|
+
resetUncommittedChanges(verbose);
|
|
208
|
+
}
|
|
209
|
+
// Fetch to get latest remote state
|
|
210
|
+
execSync('git fetch origin', { encoding: 'utf-8', stdio: 'pipe' });
|
|
211
|
+
// Check if remote feature branch exists
|
|
212
|
+
try {
|
|
213
|
+
execSync(`git rev-parse --verify origin/${featureBranch}`, {
|
|
214
|
+
encoding: 'utf-8',
|
|
215
|
+
stdio: 'pipe',
|
|
216
|
+
});
|
|
217
|
+
// Remote branch exists, sync with it
|
|
218
|
+
if (verbose) {
|
|
219
|
+
logInfo(`📥 Syncing with remote feature branch origin/${featureBranch}...`);
|
|
220
|
+
}
|
|
221
|
+
// Reset local branch to match remote branch
|
|
222
|
+
// This ensures we have all commits from the remote (e.g., from another machine)
|
|
223
|
+
execSync(`git reset --hard origin/${featureBranch}`, {
|
|
224
|
+
encoding: 'utf-8',
|
|
225
|
+
stdio: 'pipe',
|
|
226
|
+
});
|
|
227
|
+
if (verbose) {
|
|
228
|
+
logInfo(`✅ Synced local branch with origin/${featureBranch}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch (e) {
|
|
232
|
+
// Remote branch doesn't exist, that's fine - we'll push later
|
|
233
|
+
if (verbose) {
|
|
234
|
+
logInfo(` Remote branch origin/${featureBranch} doesn't exist yet, will create on push`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
if (verbose) {
|
|
240
|
+
logInfo(`⚠️ Could not sync with remote feature branch, continuing with local branch`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
182
243
|
// Rebase feature branch with latest main
|
|
183
244
|
if (verbose) {
|
|
184
245
|
logInfo(`📥 Rebasing ${featureBranch} with origin/${baseBranch}...`);
|
package/package.json
CHANGED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Read(//Users/steven/development/edsger/**)",
|
|
5
|
-
"Bash(npm run build)",
|
|
6
|
-
"Bash(node:*)",
|
|
7
|
-
"Bash(git add:*)",
|
|
8
|
-
"Bash(git commit:*)",
|
|
9
|
-
"Bash(ls:*)",
|
|
10
|
-
"Bash(cat:*)",
|
|
11
|
-
"Bash(npm run typecheck:*)",
|
|
12
|
-
"Bash(git diff:*)",
|
|
13
|
-
"WebSearch",
|
|
14
|
-
"WebFetch(domain:supabase.com)",
|
|
15
|
-
"Bash(npm install:*)",
|
|
16
|
-
"Bash(grep:*)",
|
|
17
|
-
"Bash(npx supabase gen types typescript --help:*)",
|
|
18
|
-
"Bash(git -C /Users/steven/development/edsger status)",
|
|
19
|
-
"Bash(git -C /Users/steven/development/edsger diff)",
|
|
20
|
-
"Bash(git -C /Users/steven/development/edsger log --oneline -5)",
|
|
21
|
-
"Bash(git -C /Users/steven/development/edsger add supabase/migrations/20251231000000_drop_unused_views.sql)",
|
|
22
|
-
"Bash(git -C /Users/steven/development/edsger commit -m \"$\\(cat <<''EOF''\nchore: drop unused database views\n\nRemove test_report_summary and user_stories_with_context views that are defined but never used in the application.\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
23
|
-
"Bash(git -C /Users/steven/development/edsger commit -m \"$\\(cat <<''EOF''\nchore: drop unused database views\n\nRemove test_report_summary and user_stories_with_context views\nthat are defined but never used in the application.\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")"
|
|
24
|
-
],
|
|
25
|
-
"deny": [],
|
|
26
|
-
"ask": []
|
|
27
|
-
}
|
|
28
|
-
}
|