edsger 0.19.7 → 0.19.9
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 +5 -1
- package/dist/phases/code-refine/context.js +11 -5
- package/dist/phases/code-refine/index.js +34 -13
- package/dist/phases/code-refine-verification/index.js +30 -5
- package/dist/phases/code-review/context.d.ts +5 -1
- package/dist/phases/code-review/context.js +11 -5
- package/dist/phases/code-review/index.js +27 -4
- package/dist/phases/functional-testing/analyzer.js +5 -3
- package/package.json +1 -1
|
@@ -87,8 +87,12 @@ export declare function fetchUserStories(featureId: string, verbose?: boolean):
|
|
|
87
87
|
export declare function fetchTestCases(featureId: string, verbose?: boolean): Promise<any[]>;
|
|
88
88
|
/**
|
|
89
89
|
* Fetch complete code refine context
|
|
90
|
+
* @param featureId - The feature ID
|
|
91
|
+
* @param githubToken - GitHub token for API access
|
|
92
|
+
* @param verbose - Enable verbose logging
|
|
93
|
+
* @param pullRequestUrl - Optional PR URL (for multi-branch features, use branch's PR URL)
|
|
90
94
|
*/
|
|
91
|
-
export declare function fetchCodeRefineContext(featureId: string, githubToken: string, verbose?: boolean): Promise<CodeRefineContext>;
|
|
95
|
+
export declare function fetchCodeRefineContext(featureId: string, githubToken: string, verbose?: boolean, pullRequestUrl?: string): Promise<CodeRefineContext>;
|
|
92
96
|
/**
|
|
93
97
|
* Format code refine context for prompt
|
|
94
98
|
*/
|
|
@@ -304,17 +304,23 @@ async function processGitHubContentImages(reviews, reviewThreads, featureId, ver
|
|
|
304
304
|
}
|
|
305
305
|
/**
|
|
306
306
|
* Fetch complete code refine context
|
|
307
|
+
* @param featureId - The feature ID
|
|
308
|
+
* @param githubToken - GitHub token for API access
|
|
309
|
+
* @param verbose - Enable verbose logging
|
|
310
|
+
* @param pullRequestUrl - Optional PR URL (for multi-branch features, use branch's PR URL)
|
|
307
311
|
*/
|
|
308
|
-
export async function fetchCodeRefineContext(featureId, githubToken, verbose) {
|
|
312
|
+
export async function fetchCodeRefineContext(featureId, githubToken, verbose, pullRequestUrl) {
|
|
309
313
|
// Fetch feature info using shared API
|
|
310
314
|
const feature = await getFeature(featureId, verbose);
|
|
311
|
-
|
|
315
|
+
// Use provided PR URL (from branch) or fall back to feature's PR URL
|
|
316
|
+
const prUrl = pullRequestUrl || feature.pull_request_url;
|
|
317
|
+
if (!prUrl) {
|
|
312
318
|
throw new Error(`Feature ${featureId} does not have a pull request URL. Cannot perform code refine.`);
|
|
313
319
|
}
|
|
314
320
|
// Parse PR URL
|
|
315
|
-
const prInfo = parsePullRequestUrl(
|
|
321
|
+
const prInfo = parsePullRequestUrl(prUrl);
|
|
316
322
|
if (!prInfo) {
|
|
317
|
-
throw new Error(`Invalid pull request URL: ${
|
|
323
|
+
throw new Error(`Invalid pull request URL: ${prUrl}. Expected format: https://github.com/owner/repo/pull/123`);
|
|
318
324
|
}
|
|
319
325
|
const { owner, repo, prNumber } = prInfo;
|
|
320
326
|
// Initialize Octokit with GitHub token
|
|
@@ -338,7 +344,7 @@ export async function fetchCodeRefineContext(featureId, githubToken, verbose) {
|
|
|
338
344
|
featureId,
|
|
339
345
|
featureName: feature.name,
|
|
340
346
|
featureDescription: feature.description ?? null,
|
|
341
|
-
pullRequestUrl:
|
|
347
|
+
pullRequestUrl: prUrl,
|
|
342
348
|
pullRequestNumber: prNumber,
|
|
343
349
|
owner,
|
|
344
350
|
repo,
|
|
@@ -10,7 +10,7 @@ import { getFeedbacksForPhase, formatFeedbacksForContext, } from '../../services
|
|
|
10
10
|
import { createSystemPrompt, createCodeRefinePrompt } from './prompts.js';
|
|
11
11
|
import { preparePhaseGitEnvironment, prepareCustomBranchGitEnvironment, hasUncommittedChanges, getUncommittedFiles, syncFeatBranchWithMain, } from '../../utils/git-branch-manager.js';
|
|
12
12
|
import { getFeature } from '../../api/features/get-feature.js';
|
|
13
|
-
import { getReadyForReviewBranch } from '../../services/branches.js';
|
|
13
|
+
import { getReadyForReviewBranch, } from '../../services/branches.js';
|
|
14
14
|
import { parsePullRequestUrl } from './context.js';
|
|
15
15
|
function userMessage(content) {
|
|
16
16
|
return {
|
|
@@ -88,22 +88,41 @@ export const refineCodeFromPRFeedback = async (options, config) => {
|
|
|
88
88
|
logInfo(`Note: Could not fetch feature branches, using default branch`);
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
+
// Get PR URL from branch (for multi-branch features) or feature
|
|
92
|
+
let pullRequestUrl = null;
|
|
93
|
+
if (currentBranch && currentBranch.pull_request_url) {
|
|
94
|
+
pullRequestUrl = currentBranch.pull_request_url;
|
|
95
|
+
if (verbose) {
|
|
96
|
+
logInfo(`📝 Using PR URL from branch: ${pullRequestUrl}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Fall back to feature's PR URL for single-branch features
|
|
101
|
+
try {
|
|
102
|
+
const feature = await getFeature(featureId, verbose);
|
|
103
|
+
pullRequestUrl = feature.pull_request_url || null;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (verbose) {
|
|
107
|
+
logInfo(`Note: Could not fetch feature PR URL`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
91
111
|
// Sync feat branch with main before preparing git environment
|
|
92
112
|
// This prevents extra commits from appearing in PR when dev branch is rebased
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const prInfo = parsePullRequestUrl(feature.pull_request_url);
|
|
113
|
+
if (pullRequestUrl) {
|
|
114
|
+
try {
|
|
115
|
+
const prInfo = parsePullRequestUrl(pullRequestUrl);
|
|
97
116
|
if (prInfo) {
|
|
98
117
|
await syncFeatBranchWithMain(featureId, githubToken, prInfo.owner, prInfo.repo, 'main', verbose);
|
|
99
118
|
}
|
|
100
119
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (verbose) {
|
|
122
|
+
logInfo(`⚠️ Could not sync feat branch: ${error instanceof Error ? error.message : String(error)}`);
|
|
123
|
+
}
|
|
124
|
+
// Continue even if sync fails - it's not critical
|
|
105
125
|
}
|
|
106
|
-
// Continue even if sync fails - it's not critical
|
|
107
126
|
}
|
|
108
127
|
// Prepare git environment: switch to the appropriate branch
|
|
109
128
|
const cleanupGit = currentBranch
|
|
@@ -114,7 +133,7 @@ export const refineCodeFromPRFeedback = async (options, config) => {
|
|
|
114
133
|
if (verbose) {
|
|
115
134
|
logInfo('Fetching code refine context from GitHub PR...');
|
|
116
135
|
}
|
|
117
|
-
const context = await fetchCodeRefineContext(featureId, githubToken, verbose);
|
|
136
|
+
const context = await fetchCodeRefineContext(featureId, githubToken, verbose, pullRequestUrl || undefined);
|
|
118
137
|
// Check if there are any reviews or comments to address
|
|
119
138
|
if (context.reviews.length === 0 && context.reviewComments.length === 0) {
|
|
120
139
|
if (verbose) {
|
|
@@ -131,13 +150,15 @@ export const refineCodeFromPRFeedback = async (options, config) => {
|
|
|
131
150
|
logInfo(`📋 Found ${context.reviews.length} reviews and ${context.reviewComments.length} comments to address`);
|
|
132
151
|
}
|
|
133
152
|
// Fetch additional feedbacks for code-refine phase
|
|
153
|
+
// For multi-branch features, filter by the current branch to get branch-specific feedbacks
|
|
134
154
|
let feedbacksInfo;
|
|
135
155
|
try {
|
|
136
|
-
const feedbacksContext = await getFeedbacksForPhase({ featureId, verbose }, 'code_refine'
|
|
156
|
+
const feedbacksContext = await getFeedbacksForPhase({ featureId, verbose }, 'code_refine', currentBranch?.id // Pass branch_id if we have a current branch
|
|
157
|
+
);
|
|
137
158
|
if (feedbacksContext.feedbacks.length > 0) {
|
|
138
159
|
feedbacksInfo = await formatFeedbacksForContext(feedbacksContext);
|
|
139
160
|
if (verbose) {
|
|
140
|
-
logInfo(`Added ${feedbacksContext.feedbacks.length} human feedbacks to code refine context`);
|
|
161
|
+
logInfo(`Added ${feedbacksContext.feedbacks.length} human feedbacks to code refine context${currentBranch ? ` (including branch-specific for "${currentBranch.name}")` : ''}`);
|
|
141
162
|
}
|
|
142
163
|
}
|
|
143
164
|
}
|
|
@@ -7,6 +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 { getReadyForReviewBranch, } from '../../services/branches.js';
|
|
10
11
|
import { fetchPRFileChanges, fetchUnresolvedReviewThreads, resolveReviewThreads, dismissReviews, } from './github.js';
|
|
11
12
|
import { analyzeAllThreads } from './llm-analyzer.js';
|
|
12
13
|
// Re-export types for backward compatibility
|
|
@@ -20,15 +21,39 @@ export async function verifyAndResolveComments(options) {
|
|
|
20
21
|
logInfo(`Starting code refine verification for feature ID: ${featureId}`);
|
|
21
22
|
}
|
|
22
23
|
try {
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
// For multi-branch features, find the branch that is ready for review
|
|
25
|
+
let currentBranch = null;
|
|
26
|
+
try {
|
|
27
|
+
currentBranch = await getReadyForReviewBranch({ featureId, verbose });
|
|
28
|
+
if (currentBranch && verbose) {
|
|
29
|
+
logInfo(`📋 Found ready_for_review branch: ${currentBranch.name}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (verbose) {
|
|
34
|
+
logInfo(`Note: Could not fetch feature branches`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Get PR URL from branch (for multi-branch features) or feature
|
|
38
|
+
let pullRequestUrl = null;
|
|
39
|
+
if (currentBranch && currentBranch.pull_request_url) {
|
|
40
|
+
pullRequestUrl = currentBranch.pull_request_url;
|
|
41
|
+
if (verbose) {
|
|
42
|
+
logInfo(`📝 Using PR URL from branch: ${pullRequestUrl}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Fall back to feature's PR URL for single-branch features
|
|
47
|
+
const feature = await getFeature(featureId, verbose);
|
|
48
|
+
pullRequestUrl = feature.pull_request_url || null;
|
|
49
|
+
}
|
|
50
|
+
if (!pullRequestUrl) {
|
|
26
51
|
throw new Error(`Feature ${featureId} does not have a pull request URL. Cannot perform verification.`);
|
|
27
52
|
}
|
|
28
53
|
// Parse PR URL
|
|
29
|
-
const prInfo = parsePullRequestUrl(
|
|
54
|
+
const prInfo = parsePullRequestUrl(pullRequestUrl);
|
|
30
55
|
if (!prInfo) {
|
|
31
|
-
throw new Error(`Invalid pull request URL: ${
|
|
56
|
+
throw new Error(`Invalid pull request URL: ${pullRequestUrl}. Expected format: https://github.com/owner/repo/pull/123`);
|
|
32
57
|
}
|
|
33
58
|
const { owner, repo, prNumber } = prInfo;
|
|
34
59
|
// Initialize Octokit with GitHub token (supports both REST and GraphQL)
|
|
@@ -84,8 +84,12 @@ export declare function fetchUserStories(featureId: string, verbose?: boolean):
|
|
|
84
84
|
export declare function fetchTestCases(featureId: string, verbose?: boolean): Promise<any[]>;
|
|
85
85
|
/**
|
|
86
86
|
* Fetch complete code review context
|
|
87
|
+
* @param featureId - The feature ID
|
|
88
|
+
* @param githubToken - GitHub token for API access
|
|
89
|
+
* @param verbose - Enable verbose logging
|
|
90
|
+
* @param pullRequestUrl - Optional PR URL (for multi-branch features, use branch's PR URL)
|
|
87
91
|
*/
|
|
88
|
-
export declare function fetchCodeReviewContext(featureId: string, githubToken: string, verbose?: boolean): Promise<CodeReviewContext>;
|
|
92
|
+
export declare function fetchCodeReviewContext(featureId: string, githubToken: string, verbose?: boolean, pullRequestUrl?: string): Promise<CodeReviewContext>;
|
|
89
93
|
/**
|
|
90
94
|
* Format code review context for prompt
|
|
91
95
|
*/
|
|
@@ -167,17 +167,23 @@ export async function fetchTestCases(featureId, verbose) {
|
|
|
167
167
|
}
|
|
168
168
|
/**
|
|
169
169
|
* Fetch complete code review context
|
|
170
|
+
* @param featureId - The feature ID
|
|
171
|
+
* @param githubToken - GitHub token for API access
|
|
172
|
+
* @param verbose - Enable verbose logging
|
|
173
|
+
* @param pullRequestUrl - Optional PR URL (for multi-branch features, use branch's PR URL)
|
|
170
174
|
*/
|
|
171
|
-
export async function fetchCodeReviewContext(featureId, githubToken, verbose) {
|
|
175
|
+
export async function fetchCodeReviewContext(featureId, githubToken, verbose, pullRequestUrl) {
|
|
172
176
|
// Fetch feature info using shared API
|
|
173
177
|
const feature = await getFeature(featureId, verbose);
|
|
174
|
-
|
|
178
|
+
// Use provided PR URL (from branch) or fall back to feature's PR URL
|
|
179
|
+
const prUrl = pullRequestUrl || feature.pull_request_url;
|
|
180
|
+
if (!prUrl) {
|
|
175
181
|
throw new Error(`Feature ${featureId} does not have a pull request URL. Cannot perform code review.`);
|
|
176
182
|
}
|
|
177
183
|
// Parse PR URL
|
|
178
|
-
const prInfo = parsePullRequestUrl(
|
|
184
|
+
const prInfo = parsePullRequestUrl(prUrl);
|
|
179
185
|
if (!prInfo) {
|
|
180
|
-
throw new Error(`Invalid pull request URL: ${
|
|
186
|
+
throw new Error(`Invalid pull request URL: ${prUrl}. Expected format: https://github.com/owner/repo/pull/123`);
|
|
181
187
|
}
|
|
182
188
|
const { owner, repo, prNumber } = prInfo;
|
|
183
189
|
// Initialize Octokit with GitHub token
|
|
@@ -199,7 +205,7 @@ export async function fetchCodeReviewContext(featureId, githubToken, verbose) {
|
|
|
199
205
|
featureId,
|
|
200
206
|
featureName: feature.name,
|
|
201
207
|
featureDescription: feature.description ?? null,
|
|
202
|
-
pullRequestUrl:
|
|
208
|
+
pullRequestUrl: prUrl,
|
|
203
209
|
pullRequestNumber: prNumber,
|
|
204
210
|
owner,
|
|
205
211
|
repo,
|
|
@@ -8,7 +8,8 @@ import { Octokit } from '@octokit/rest';
|
|
|
8
8
|
import { fetchCodeReviewContext, formatContextForPrompt, } from './context.js';
|
|
9
9
|
import { getFeedbacksForPhase, formatFeedbacksForContext, } from '../../services/feedbacks.js';
|
|
10
10
|
import { preparePhaseGitEnvironment, prepareCustomBranchGitEnvironment, } from '../../utils/git-branch-manager.js';
|
|
11
|
-
import { getReadyForReviewBranch } from '../../services/branches.js';
|
|
11
|
+
import { getReadyForReviewBranch, } from '../../services/branches.js';
|
|
12
|
+
import { getFeature } from '../../api/features/get-feature.js';
|
|
12
13
|
function userMessage(content) {
|
|
13
14
|
return {
|
|
14
15
|
type: 'user',
|
|
@@ -144,6 +145,26 @@ export const reviewPullRequest = async (options, config) => {
|
|
|
144
145
|
logInfo(`Note: Could not fetch feature branches, using default branch`);
|
|
145
146
|
}
|
|
146
147
|
}
|
|
148
|
+
// Get PR URL from branch (for multi-branch features) or feature
|
|
149
|
+
let pullRequestUrl = null;
|
|
150
|
+
if (currentBranch && currentBranch.pull_request_url) {
|
|
151
|
+
pullRequestUrl = currentBranch.pull_request_url;
|
|
152
|
+
if (verbose) {
|
|
153
|
+
logInfo(`📝 Using PR URL from branch: ${pullRequestUrl}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Fall back to feature's PR URL for single-branch features
|
|
158
|
+
try {
|
|
159
|
+
const feature = await getFeature(featureId, verbose);
|
|
160
|
+
pullRequestUrl = feature.pull_request_url || null;
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
if (verbose) {
|
|
164
|
+
logInfo(`Note: Could not fetch feature PR URL`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
147
168
|
// Prepare git environment: switch to the appropriate branch
|
|
148
169
|
const cleanupGit = currentBranch
|
|
149
170
|
? prepareCustomBranchGitEnvironment(branchName, 'main', verbose)
|
|
@@ -153,7 +174,7 @@ export const reviewPullRequest = async (options, config) => {
|
|
|
153
174
|
if (verbose) {
|
|
154
175
|
logInfo('Fetching code review context from GitHub PR...');
|
|
155
176
|
}
|
|
156
|
-
const context = await fetchCodeReviewContext(featureId, githubToken, verbose);
|
|
177
|
+
const context = await fetchCodeReviewContext(featureId, githubToken, verbose, pullRequestUrl || undefined);
|
|
157
178
|
// Check if there are any files to review
|
|
158
179
|
if (context.files.length === 0) {
|
|
159
180
|
if (verbose) {
|
|
@@ -170,13 +191,15 @@ export const reviewPullRequest = async (options, config) => {
|
|
|
170
191
|
logInfo(`📋 Found ${context.files.length} files to review across ${context.commits.length} commits`);
|
|
171
192
|
}
|
|
172
193
|
// Fetch additional feedbacks for code-review phase
|
|
194
|
+
// For multi-branch features, filter by the current branch to get branch-specific feedbacks
|
|
173
195
|
let feedbacksInfo;
|
|
174
196
|
try {
|
|
175
|
-
const feedbacksContext = await getFeedbacksForPhase({ featureId, verbose }, 'code_review'
|
|
197
|
+
const feedbacksContext = await getFeedbacksForPhase({ featureId, verbose }, 'code_review', currentBranch?.id // Pass branch_id if we have a current branch
|
|
198
|
+
);
|
|
176
199
|
if (feedbacksContext.feedbacks.length > 0) {
|
|
177
200
|
feedbacksInfo = await formatFeedbacksForContext(feedbacksContext);
|
|
178
201
|
if (verbose) {
|
|
179
|
-
logInfo(`Added ${feedbacksContext.feedbacks.length} human feedbacks to code review context`);
|
|
202
|
+
logInfo(`Added ${feedbacksContext.feedbacks.length} human feedbacks to code review context${currentBranch ? ` (including branch-specific for "${currentBranch.name}")` : ''}`);
|
|
180
203
|
}
|
|
181
204
|
}
|
|
182
205
|
}
|
|
@@ -7,7 +7,7 @@ import { fetchFunctionalTestingContext, formatContextForPrompt, } from './contex
|
|
|
7
7
|
import { updateFeatureStatus } from '../../api/features/index.js';
|
|
8
8
|
import { createTestReport, } from './test-report-creator.js';
|
|
9
9
|
import { preparePhaseGitEnvironment, prepareCustomBranchGitEnvironment, } from '../../utils/git-branch-manager.js';
|
|
10
|
-
import { getReadyForReviewBranch } from '../../services/branches.js';
|
|
10
|
+
import { getReadyForReviewBranch, } from '../../services/branches.js';
|
|
11
11
|
function userMessage(content) {
|
|
12
12
|
return {
|
|
13
13
|
type: 'user',
|
|
@@ -57,13 +57,15 @@ export const runFunctionalTesting = async (options, config, checklistContext) =>
|
|
|
57
57
|
}
|
|
58
58
|
const context = await fetchFunctionalTestingContext(featureId, verbose);
|
|
59
59
|
// Fetch feedbacks for functional testing phase
|
|
60
|
+
// For multi-branch features, include branch-specific feedbacks
|
|
60
61
|
let feedbacksInfo;
|
|
61
62
|
try {
|
|
62
|
-
const feedbacksContext = await getFeedbacksForPhase({ featureId, verbose }, 'functional_testing'
|
|
63
|
+
const feedbacksContext = await getFeedbacksForPhase({ featureId, verbose }, 'functional_testing', currentBranch?.id // Pass branch_id if we have a current branch
|
|
64
|
+
);
|
|
63
65
|
if (feedbacksContext.feedbacks.length > 0) {
|
|
64
66
|
feedbacksInfo = await formatFeedbacksForContext(feedbacksContext);
|
|
65
67
|
if (verbose) {
|
|
66
|
-
logInfo(`Added ${feedbacksContext.feedbacks.length} human feedbacks to testing context`);
|
|
68
|
+
logInfo(`Added ${feedbacksContext.feedbacks.length} human feedbacks to testing context${currentBranch ? ` (including branch-specific for "${currentBranch.name}")` : ''}`);
|
|
67
69
|
}
|
|
68
70
|
}
|
|
69
71
|
}
|