edsger 0.21.3 → 0.21.5

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.
@@ -14,7 +14,6 @@ import { markWorkflowPhaseCompleted } from '../../api/features/update-feature.js
14
14
  import { logError, logInfo, logWarning } from '../../utils/logger.js';
15
15
  import { logPhaseResult } from '../../utils/pipeline-logger.js';
16
16
  import { runFeatureAnalysisPhase, runTechnicalDesignPhase, runBranchPlanningPhase, runCodeImplementationPhase, runFunctionalTestingPhase, runCodeRefinePhase, runCodeReviewPhase, } from './executors/phase-executor.js';
17
- import { handlePullRequestCreation } from '../../phases/pull-request/handler.js';
18
17
  /**
19
18
  * Map workflow phase names (underscore format) to phase runner functions
20
19
  * Note: code_refine includes built-in verification loop (similar to technical_design)
@@ -104,8 +103,6 @@ export async function runFeatureWorkflow(options, config) {
104
103
  }
105
104
  // 3. Execute each pending phase in order
106
105
  const results = [];
107
- // Check if workflow includes a pull_request phase
108
- const hasPullRequestPhase = pendingPhases.some((p) => p.phase === 'pull_request');
109
106
  for (const workflowPhase of pendingPhases) {
110
107
  const result = await executePhase(workflowPhase.phase, options, config);
111
108
  results.push(result);
@@ -116,37 +113,8 @@ export async function runFeatureWorkflow(options, config) {
116
113
  }
117
114
  break;
118
115
  }
119
- // Auto-create PR after successful code_implementation if no pull_request phase in workflow
120
- if (workflowPhase.phase === 'code_implementation' &&
121
- result.status === 'success' &&
122
- !hasPullRequestPhase) {
123
- if (verbose) {
124
- logInfo('\nšŸ“ Creating pull request for implemented code...');
125
- }
126
- const prCreated = await handlePullRequestCreation({
127
- featureId,
128
- results,
129
- verbose,
130
- });
131
- const prResult = {
132
- featureId,
133
- phase: 'pull-request',
134
- status: prCreated ? 'success' : 'error',
135
- message: prCreated
136
- ? 'Pull request created successfully'
137
- : 'Pull request creation failed',
138
- data: {},
139
- };
140
- logPhaseResult(prResult, verbose);
141
- results.push(prResult);
142
- // If PR creation failed, stop workflow
143
- if (!prCreated) {
144
- if (verbose) {
145
- logInfo('\nā›” Stopping workflow execution: pull-request failed');
146
- }
147
- break;
148
- }
149
- }
116
+ // Note: PR creation is now handled within the code-implementation phase itself,
117
+ // so we no longer need to create it here after code_implementation succeeds.
150
118
  }
151
119
  if (verbose) {
152
120
  const successCount = results.filter((r) => r.status === 'success').length;
@@ -42,6 +42,7 @@ export function devBranchToFeatBranch(devBranchName) {
42
42
  }
43
43
  /**
44
44
  * Push a branch to remote
45
+ * Falls back to force-with-lease if normal push fails (e.g., after rebase)
45
46
  */
46
47
  async function pushBranch(branchName, verbose) {
47
48
  try {
@@ -66,8 +67,27 @@ async function pushBranch(branchName, verbose) {
66
67
  return { success: true };
67
68
  }
68
69
  catch (retryError) {
69
- const errorMessage = retryError instanceof Error ? retryError.message : String(retryError);
70
- return { success: false, error: errorMessage };
70
+ // If push still fails (likely non-fast-forward after rebase),
71
+ // use force-with-lease for safer force push
72
+ if (verbose) {
73
+ logInfo(`āš ļø Push rejected, attempting force push with lease...`);
74
+ }
75
+ try {
76
+ execSync(`git push --force-with-lease origin ${branchName}`, {
77
+ encoding: 'utf-8',
78
+ stdio: verbose ? 'inherit' : 'pipe',
79
+ });
80
+ if (verbose) {
81
+ logInfo(`āœ… Successfully force pushed ${branchName}`);
82
+ }
83
+ return { success: true };
84
+ }
85
+ catch (forceError) {
86
+ const errorMessage = forceError instanceof Error
87
+ ? forceError.message
88
+ : String(forceError);
89
+ return { success: false, error: errorMessage };
90
+ }
71
91
  }
72
92
  }
73
93
  }
@@ -856,6 +856,7 @@ const parseImplementationResponse = (response, featureId) => {
856
856
  };
857
857
  /**
858
858
  * Push branch to remote repository
859
+ * Falls back to force-with-lease if normal push fails (e.g., after rebase)
859
860
  */
860
861
  async function pushToRemote(branchName, verbose) {
861
862
  try {
@@ -883,11 +884,31 @@ async function pushToRemote(branchName, verbose) {
883
884
  return { success: true };
884
885
  }
885
886
  catch (retryError) {
886
- const errorMessage = retryError instanceof Error ? retryError.message : String(retryError);
887
- return {
888
- success: false,
889
- error: errorMessage,
890
- };
887
+ // If push still fails (likely non-fast-forward after rebase),
888
+ // use force-with-lease for safer force push
889
+ // force-with-lease ensures we don't overwrite others' work by checking remote state
890
+ if (verbose) {
891
+ logInfo(`āš ļø Push rejected, attempting force push with lease...`);
892
+ }
893
+ try {
894
+ execSync(`git push --force-with-lease origin ${branchName}`, {
895
+ encoding: 'utf-8',
896
+ stdio: verbose ? 'inherit' : 'pipe',
897
+ });
898
+ if (verbose) {
899
+ logInfo(`āœ… Successfully force pushed ${branchName}`);
900
+ }
901
+ return { success: true };
902
+ }
903
+ catch (forceError) {
904
+ const errorMessage = forceError instanceof Error
905
+ ? forceError.message
906
+ : String(forceError);
907
+ return {
908
+ success: false,
909
+ error: errorMessage,
910
+ };
911
+ }
891
912
  }
892
913
  }
893
914
  }
@@ -85,6 +85,7 @@ const switchToBranch = (branch, verbose) => {
85
85
  };
86
86
  /**
87
87
  * Push current branch to remote
88
+ * Falls back to force-with-lease if normal push fails (e.g., after rebase)
88
89
  */
89
90
  const pushBranch = (branch, verbose) => {
90
91
  try {
@@ -97,7 +98,22 @@ const pushBranch = (branch, verbose) => {
97
98
  }
98
99
  }
99
100
  catch (error) {
100
- throw new Error(`Failed to push branch: ${error}`);
101
+ // If push fails (likely non-fast-forward after rebase),
102
+ // use force-with-lease for safer force push
103
+ if (verbose) {
104
+ console.log(`āš ļø Push rejected, attempting force push with lease...`);
105
+ }
106
+ try {
107
+ execSync(`git push --force-with-lease origin ${branch}`, {
108
+ encoding: 'utf-8',
109
+ });
110
+ if (verbose) {
111
+ console.log(`āœ… Successfully force pushed ${branch}`);
112
+ }
113
+ }
114
+ catch (forceError) {
115
+ throw new Error(`Failed to push branch: ${forceError}`);
116
+ }
101
117
  }
102
118
  };
103
119
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edsger",
3
- "version": "0.21.3",
3
+ "version": "0.21.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "edsger": "dist/index.js"