@damper/cli 0.8.0 → 0.9.0

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.
@@ -274,17 +274,41 @@ export async function postTaskFlow(options) {
274
274
  console.log(pc.dim('Keeping changes local.\n'));
275
275
  }
276
276
  else if (mergeAction === 'merge') {
277
- // Merge directly to main
277
+ // Merge directly to main — first merge main into feature to resolve conflicts
278
278
  try {
279
279
  const { execa } = await import('execa');
280
- console.log(pc.dim('Switching to main and merging...'));
281
280
  // Fetch latest main
282
281
  await execa('git', ['fetch', 'origin', 'main'], { cwd, stdio: 'pipe' });
283
- // Checkout main in the main project root (not worktree)
284
- await execa('git', ['checkout', 'main'], { cwd: projectRoot, stdio: 'pipe' });
285
- // Merge the feature branch
286
- await execa('git', ['merge', currentBranch, '--no-edit'], { cwd: projectRoot, stdio: 'inherit' });
287
- console.log(pc.green(' Merged to main locally\n'));
282
+ // Step 1: Merge origin/main INTO the feature branch (in worktree)
283
+ console.log(pc.dim('Merging main into feature branch...'));
284
+ let mainMergedIntoFeature = false;
285
+ try {
286
+ await execa('git', ['merge', 'origin/main', '--no-edit'], { cwd, stdio: 'pipe' });
287
+ mainMergedIntoFeature = true;
288
+ console.log(pc.green('✓ Main merged into feature branch (no conflicts)'));
289
+ }
290
+ catch {
291
+ // Merge conflicts — launch Claude to resolve
292
+ console.log(pc.yellow('Merge conflicts detected. Launching Claude to resolve...'));
293
+ await execa('git', ['merge', '--abort'], { cwd, stdio: 'pipe' });
294
+ await launchClaudeForMerge({ cwd, apiKey });
295
+ // Verify merge was completed (origin/main should be ancestor of HEAD)
296
+ try {
297
+ await execa('git', ['merge-base', '--is-ancestor', 'origin/main', 'HEAD'], { cwd, stdio: 'pipe' });
298
+ mainMergedIntoFeature = true;
299
+ console.log(pc.green('✓ Claude resolved merge conflicts'));
300
+ }
301
+ catch {
302
+ console.log(pc.red('Claude did not complete the merge. Skipping merge to main.\n'));
303
+ }
304
+ }
305
+ // Step 2: Merge feature → main (should be clean now)
306
+ if (mainMergedIntoFeature) {
307
+ console.log(pc.dim('Merging feature into main...'));
308
+ await execa('git', ['checkout', 'main'], { cwd: projectRoot, stdio: 'pipe' });
309
+ await execa('git', ['merge', currentBranch, '--no-edit'], { cwd: projectRoot, stdio: 'inherit' });
310
+ console.log(pc.green('✓ Merged to main locally\n'));
311
+ }
288
312
  }
289
313
  catch (err) {
290
314
  console.log(pc.red('Failed to merge. You may need to resolve conflicts manually.\n'));
@@ -406,6 +430,22 @@ export async function postTaskFlow(options) {
406
430
  }
407
431
  console.log();
408
432
  }
433
+ /**
434
+ * Launch Claude to resolve merge conflicts
435
+ */
436
+ async function launchClaudeForMerge(options) {
437
+ const { cwd, apiKey } = options;
438
+ const prompt = 'Merge origin/main into the current branch and resolve any conflicts. Run: git merge origin/main --no-edit. If there are conflicts, resolve them, then stage and commit.';
439
+ await new Promise((resolve) => {
440
+ const child = spawn('claude', [prompt], {
441
+ cwd,
442
+ stdio: 'inherit',
443
+ env: { ...process.env, DAMPER_API_KEY: apiKey },
444
+ });
445
+ child.on('error', () => resolve());
446
+ child.on('close', () => resolve());
447
+ });
448
+ }
409
449
  /**
410
450
  * Check if Claude Code CLI is installed
411
451
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@damper/cli",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "CLI tool for orchestrating Damper task workflows with Claude Code",
5
5
  "author": "Damper <hello@usedamper.com>",
6
6
  "repository": {