edsger 0.19.12 → 0.19.13

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.
@@ -9,10 +9,9 @@ import { execSync } from 'child_process';
9
9
  import { fetchCodeRefineContext, } from './context.js';
10
10
  import { getFeedbacksForPhase, formatFeedbacksForContext, } from '../../services/feedbacks.js';
11
11
  import { createSystemPrompt, createCodeRefinePrompt } from './prompts.js';
12
- import { preparePhaseGitEnvironment, prepareCustomBranchGitEnvironment, hasUncommittedChanges, getUncommittedFiles, syncFeatBranchWithMain, } from '../../utils/git-branch-manager.js';
12
+ import { preparePhaseGitEnvironment, prepareCustomBranchGitEnvironment, hasUncommittedChanges, getUncommittedFiles, } from '../../utils/git-branch-manager.js';
13
13
  import { getFeature } from '../../api/features/get-feature.js';
14
- import { getReviewedBranch, updateBranch, } from '../../services/branches.js';
15
- import { parsePullRequestUrl } from './context.js';
14
+ import { getBranches, getBaseBranchInfo, updateBranch, } from '../../services/branches.js';
16
15
  import { verifyAndResolveComments, } from '../code-refine-verification/index.js';
17
16
  // Maximum number of refine + verification iterations
18
17
  export const MAX_REFINE_ITERATIONS = 10;
@@ -75,8 +74,12 @@ export const refineCodeFromPRFeedback = async (options, config) => {
75
74
  // (status = 'reviewed' after code-review phase) and use its branch_name for refine
76
75
  let branchName = `dev/${featureId}`; // Default for single-branch features
77
76
  let currentBranch = null;
77
+ let allBranches = [];
78
+ let baseBranchForRebase = 'main'; // Default base branch for rebase
78
79
  try {
79
- currentBranch = await getReviewedBranch({ featureId, verbose });
80
+ // Get all branches to determine base branch info
81
+ allBranches = await getBranches({ featureId, verbose });
82
+ currentBranch = allBranches.find((b) => b.status === 'reviewed') || null;
80
83
  if (currentBranch && currentBranch.branch_name) {
81
84
  // Use branch_name directly (already stored as dev/...)
82
85
  branchName = currentBranch.branch_name;
@@ -84,6 +87,22 @@ export const refineCodeFromPRFeedback = async (options, config) => {
84
87
  logInfo(`📋 Found reviewed branch: ${currentBranch.name}`);
85
88
  logInfo(` Using dev branch: ${branchName}`);
86
89
  }
90
+ // Determine the correct base branch for rebase using base_branch_id
91
+ const baseBranchInfo = await getBaseBranchInfo(currentBranch, allBranches, 'main');
92
+ if (baseBranchInfo.baseBranchMerged) {
93
+ // Base branch is merged (or no base branch) - rebase from main
94
+ baseBranchForRebase = 'main';
95
+ if (verbose && currentBranch.base_branch_id) {
96
+ logInfo(` Base branch is merged, will rebase from main`);
97
+ }
98
+ }
99
+ else {
100
+ // Base branch not merged - rebase from base branch's dev branch
101
+ baseBranchForRebase = baseBranchInfo.baseBranch;
102
+ if (verbose) {
103
+ logInfo(` Will rebase from base branch: ${baseBranchForRebase}`);
104
+ }
105
+ }
87
106
  }
88
107
  else if (verbose) {
89
108
  logInfo(`â„šī¸ No reviewed branch found, using default: ${branchName}`);
@@ -114,25 +133,9 @@ export const refineCodeFromPRFeedback = async (options, config) => {
114
133
  }
115
134
  }
116
135
  }
117
- // Sync feat branch with main before preparing git environment
118
- // This prevents extra commits from appearing in PR when dev branch is rebased
119
- if (pullRequestUrl) {
120
- try {
121
- const prInfo = parsePullRequestUrl(pullRequestUrl);
122
- if (prInfo) {
123
- await syncFeatBranchWithMain(featureId, githubToken, prInfo.owner, prInfo.repo, 'main', verbose);
124
- }
125
- }
126
- catch (error) {
127
- if (verbose) {
128
- logInfo(`âš ī¸ Could not sync feat branch: ${error instanceof Error ? error.message : String(error)}`);
129
- }
130
- // Continue even if sync fails - it's not critical
131
- }
132
- }
133
- // Prepare git environment: switch to the appropriate branch
136
+ // Prepare git environment: switch to the appropriate branch and rebase from correct base
134
137
  const cleanupGit = currentBranch
135
- ? prepareCustomBranchGitEnvironment(branchName, 'main', verbose)
138
+ ? prepareCustomBranchGitEnvironment(branchName, baseBranchForRebase, verbose)
136
139
  : preparePhaseGitEnvironment(featureId, 'main', verbose);
137
140
  try {
138
141
  // Fetch initial code refine context (PR reviews and comments)
@@ -8,7 +8,7 @@ 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, updateBranch, } from '../../services/branches.js';
11
+ import { getBranches, getBaseBranchInfo, updateBranch, } from '../../services/branches.js';
12
12
  import { getFeature } from '../../api/features/get-feature.js';
13
13
  function userMessage(content) {
14
14
  return {
@@ -126,8 +126,12 @@ export const reviewPullRequest = async (options, config) => {
126
126
  // and use its branch_name for review (branch_name is stored as dev/...)
127
127
  let branchName = `dev/${featureId}`; // Default for single-branch features
128
128
  let currentBranch = null;
129
+ let allBranches = [];
130
+ let baseBranchForRebase = 'main'; // Default base branch for rebase
129
131
  try {
130
- currentBranch = await getReadyForReviewBranch({ featureId, verbose });
132
+ // Get all branches to determine base branch info
133
+ allBranches = await getBranches({ featureId, verbose });
134
+ currentBranch = allBranches.find((b) => b.status === 'ready_for_review') || null;
131
135
  if (currentBranch && currentBranch.branch_name) {
132
136
  // Use branch_name directly (already stored as dev/...)
133
137
  branchName = currentBranch.branch_name;
@@ -135,6 +139,22 @@ export const reviewPullRequest = async (options, config) => {
135
139
  logInfo(`📋 Found ready_for_review branch: ${currentBranch.name}`);
136
140
  logInfo(` Using dev branch: ${branchName}`);
137
141
  }
142
+ // Determine the correct base branch for rebase using base_branch_id
143
+ const baseBranchInfo = await getBaseBranchInfo(currentBranch, allBranches, 'main');
144
+ if (baseBranchInfo.baseBranchMerged) {
145
+ // Base branch is merged (or no base branch) - rebase from main
146
+ baseBranchForRebase = 'main';
147
+ if (verbose && currentBranch.base_branch_id) {
148
+ logInfo(` Base branch is merged, will rebase from main`);
149
+ }
150
+ }
151
+ else {
152
+ // Base branch not merged - rebase from base branch's dev branch
153
+ baseBranchForRebase = baseBranchInfo.baseBranch;
154
+ if (verbose) {
155
+ logInfo(` Will rebase from base branch: ${baseBranchForRebase}`);
156
+ }
157
+ }
138
158
  }
139
159
  else if (verbose) {
140
160
  logInfo(`â„šī¸ No ready_for_review branch found, using default: ${branchName}`);
@@ -165,9 +185,9 @@ export const reviewPullRequest = async (options, config) => {
165
185
  }
166
186
  }
167
187
  }
168
- // Prepare git environment: switch to the appropriate branch
188
+ // Prepare git environment: switch to the appropriate branch and rebase from correct base
169
189
  const cleanupGit = currentBranch
170
- ? prepareCustomBranchGitEnvironment(branchName, 'main', verbose)
190
+ ? prepareCustomBranchGitEnvironment(branchName, baseBranchForRebase, verbose)
171
191
  : preparePhaseGitEnvironment(featureId, 'main', verbose);
172
192
  try {
173
193
  // Fetch code review context (PR data, files, commits)
@@ -62,9 +62,10 @@ export declare function allBranchesCompleted(options: PipelinePhaseOptions): Pro
62
62
  /**
63
63
  * Get the base branch information for a branch.
64
64
  * Returns:
65
- * - If base_branch_id is set and that branch is merged: use main
66
- * - If base_branch_id is set and that branch is not merged: use that branch's branch_name
67
- * - If base_branch_id is null: use main
65
+ * - If base_branch_id is null: use main (first branch in chain)
66
+ * - If base_branch_id is set and that branch is merged: use base branch's feat branch
67
+ * (merged means dev merged to feat, not to main)
68
+ * - If base_branch_id is set and that branch is not merged: use base branch's dev branch
68
69
  */
69
70
  export declare function getBaseBranchInfo(branch: Branch, allBranches: Branch[], mainBranch?: string): Promise<{
70
71
  baseBranch: string;
@@ -159,12 +159,13 @@ export async function allBranchesCompleted(options) {
159
159
  /**
160
160
  * Get the base branch information for a branch.
161
161
  * Returns:
162
- * - If base_branch_id is set and that branch is merged: use main
163
- * - If base_branch_id is set and that branch is not merged: use that branch's branch_name
164
- * - If base_branch_id is null: use main
162
+ * - If base_branch_id is null: use main (first branch in chain)
163
+ * - If base_branch_id is set and that branch is merged: use base branch's feat branch
164
+ * (merged means dev merged to feat, not to main)
165
+ * - If base_branch_id is set and that branch is not merged: use base branch's dev branch
165
166
  */
166
167
  export async function getBaseBranchInfo(branch, allBranches, mainBranch = 'main') {
167
- // No base branch - start from main
168
+ // No base branch - start from main (first branch in chain)
168
169
  if (!branch.base_branch_id) {
169
170
  return {
170
171
  baseBranch: mainBranch,
@@ -182,10 +183,23 @@ export async function getBaseBranchInfo(branch, allBranches, mainBranch = 'main'
182
183
  baseBranchMerged: true,
183
184
  };
184
185
  }
185
- // Check if base branch is merged
186
+ // Check if base branch is merged (dev merged to feat)
186
187
  if (baseBranch.status === 'merged') {
187
- // Base branch is merged to main - we should base on main and rebase if needed
188
- return { baseBranch: mainBranch, needsRebase: true, baseBranchMerged: true };
188
+ // Base branch's dev is merged to feat - rebase from base branch's feat branch
189
+ // Convert dev/xxx/1-name to feat/xxx/1-name
190
+ if (!baseBranch.branch_name) {
191
+ return {
192
+ baseBranch: mainBranch,
193
+ needsRebase: false,
194
+ baseBranchMerged: true,
195
+ };
196
+ }
197
+ const featBranchName = baseBranch.branch_name.replace(/^dev\//, 'feat/');
198
+ return {
199
+ baseBranch: featBranchName,
200
+ needsRebase: true,
201
+ baseBranchMerged: true,
202
+ };
189
203
  }
190
204
  // Base branch is not merged - we should base on that branch
191
205
  if (!baseBranch.branch_name) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edsger",
3
- "version": "0.19.12",
3
+ "version": "0.19.13",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "edsger": "dist/index.js"