@snapcommit/cli 3.3.0 → 3.4.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.
- package/dist/commands/cursor-style.js +121 -5
- package/package.json +1 -1
|
@@ -190,7 +190,8 @@ async function executeCommitWithAI(intent) {
|
|
|
190
190
|
const fileSelection = await new Promise((resolve) => {
|
|
191
191
|
rlFileSelect.question(chalk_1.default.cyan('Select files: ') +
|
|
192
192
|
chalk_1.default.gray('(Enter=all, 1-3=specific, 1,3,5=multiple): '), (ans) => {
|
|
193
|
-
|
|
193
|
+
// Don't close - just resolve and let it clean up
|
|
194
|
+
setImmediate(() => rlFileSelect.close());
|
|
194
195
|
resolve(ans.trim());
|
|
195
196
|
});
|
|
196
197
|
});
|
|
@@ -253,7 +254,8 @@ async function executeCommitWithAI(intent) {
|
|
|
253
254
|
});
|
|
254
255
|
const response = await new Promise((resolve) => {
|
|
255
256
|
rlCommit.question(chalk_1.default.gray('→ Press Enter to commit, or edit message: '), (ans) => {
|
|
256
|
-
|
|
257
|
+
// Don't close - just resolve and let it clean up
|
|
258
|
+
setImmediate(() => rlCommit.close());
|
|
257
259
|
resolve(ans.trim());
|
|
258
260
|
});
|
|
259
261
|
});
|
|
@@ -290,16 +292,90 @@ async function executeCommitWithAI(intent) {
|
|
|
290
292
|
// Push if requested
|
|
291
293
|
const shouldPush = intent.shouldPush || intent.gitCommands?.some((cmd) => cmd.includes('push'));
|
|
292
294
|
if (shouldPush) {
|
|
295
|
+
// STEP 1: Pull first to avoid conflicts (like Cursor does!)
|
|
296
|
+
try {
|
|
297
|
+
const currentBranch = (0, child_process_1.execSync)('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }).trim();
|
|
298
|
+
const hasRemote = (0, child_process_1.execSync)(`git ls-remote --heads origin ${currentBranch}`, { encoding: 'utf-8' }).trim();
|
|
299
|
+
if (hasRemote) {
|
|
300
|
+
console.log(chalk_1.default.blue('⚡ Syncing with remote...'));
|
|
301
|
+
try {
|
|
302
|
+
(0, child_process_1.execSync)('git pull --rebase', { encoding: 'utf-8', stdio: 'pipe' });
|
|
303
|
+
console.log(chalk_1.default.green('✓ Synced'));
|
|
304
|
+
}
|
|
305
|
+
catch (pullError) {
|
|
306
|
+
// Handle rebase conflicts
|
|
307
|
+
if (pullError.message.includes('conflict')) {
|
|
308
|
+
console.log(chalk_1.default.yellow('\n⚠️ Merge conflicts detected - resolving...'));
|
|
309
|
+
// Try to auto-resolve conflicts
|
|
310
|
+
const resolved = await tryAdvancedConflictResolution();
|
|
311
|
+
if (resolved) {
|
|
312
|
+
console.log(chalk_1.default.green('✓ Conflicts resolved'));
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
console.log(chalk_1.default.red('\n❌ Cannot auto-resolve conflicts'));
|
|
316
|
+
console.log(chalk_1.default.white('\nConflicted files:'));
|
|
317
|
+
const conflicts = (0, child_process_1.execSync)('git diff --name-only --diff-filter=U', { encoding: 'utf-8' });
|
|
318
|
+
conflicts.split('\n').filter(f => f.trim()).forEach(file => {
|
|
319
|
+
console.log(chalk_1.default.red(` ✗ ${file}`));
|
|
320
|
+
});
|
|
321
|
+
console.log(chalk_1.default.cyan('\nTo resolve manually:'));
|
|
322
|
+
console.log(chalk_1.default.gray(' 1. Fix conflicts in the files above'));
|
|
323
|
+
console.log(chalk_1.default.gray(' 2. Run: ') + chalk_1.default.cyan('git add <files>'));
|
|
324
|
+
console.log(chalk_1.default.gray(' 3. Run: ') + chalk_1.default.cyan('git rebase --continue'));
|
|
325
|
+
console.log(chalk_1.default.gray(' 4. Then try: ') + chalk_1.default.cyan('snap') + chalk_1.default.gray(' and ') + chalk_1.default.cyan('push changes\n'));
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
// Other pull errors
|
|
331
|
+
console.log(chalk_1.default.yellow(`⚠️ Sync issue: ${pullError.message}`));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
// No remote or other issues - continue with push
|
|
338
|
+
}
|
|
339
|
+
// STEP 2: Now push
|
|
293
340
|
try {
|
|
294
341
|
(0, child_process_1.execSync)('git push', { encoding: 'utf-8', stdio: 'pipe' });
|
|
295
342
|
console.log(chalk_1.default.green('✓ Pushed\n'));
|
|
296
343
|
}
|
|
297
|
-
catch (
|
|
298
|
-
|
|
344
|
+
catch (pushError) {
|
|
345
|
+
const errorMsg = pushError.message.toLowerCase();
|
|
346
|
+
if (errorMsg.includes('no configured push destination')) {
|
|
299
347
|
console.log(chalk_1.default.gray('✓ Committed locally (no remote)\n'));
|
|
300
348
|
}
|
|
349
|
+
else if (errorMsg.includes('rejected') && errorMsg.includes('non-fast-forward')) {
|
|
350
|
+
// Need force push - but be safe!
|
|
351
|
+
console.log(chalk_1.default.yellow('\n⚠️ Remote has changes that would be overwritten'));
|
|
352
|
+
console.log(chalk_1.default.white('This requires force push, which can be dangerous.\n'));
|
|
353
|
+
const rlForce = await Promise.resolve().then(() => __importStar(require('readline')));
|
|
354
|
+
const rlForcePush = rlForce.createInterface({
|
|
355
|
+
input: process.stdin,
|
|
356
|
+
output: process.stdout,
|
|
357
|
+
});
|
|
358
|
+
const confirmForce = await new Promise((resolve) => {
|
|
359
|
+
rlForcePush.question(chalk_1.default.cyan('Force push? ') + chalk_1.default.gray('(yes/no): '), (ans) => {
|
|
360
|
+
setImmediate(() => rlForcePush.close());
|
|
361
|
+
resolve(ans.trim().toLowerCase());
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
if (confirmForce === 'yes') {
|
|
365
|
+
try {
|
|
366
|
+
(0, child_process_1.execSync)('git push --force-with-lease', { encoding: 'utf-8', stdio: 'pipe' });
|
|
367
|
+
console.log(chalk_1.default.green('✓ Force pushed (safely)\n'));
|
|
368
|
+
}
|
|
369
|
+
catch (forceError) {
|
|
370
|
+
console.log(chalk_1.default.red(`\n❌ Force push failed: ${forceError.message}\n`));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
console.log(chalk_1.default.gray('\n✗ Push cancelled\n'));
|
|
375
|
+
}
|
|
376
|
+
}
|
|
301
377
|
else {
|
|
302
|
-
console.log(chalk_1.default.yellow(
|
|
378
|
+
console.log(chalk_1.default.yellow(`\n⚠️ Push failed: ${pushError.message}\n`));
|
|
303
379
|
}
|
|
304
380
|
}
|
|
305
381
|
}
|
|
@@ -307,6 +383,46 @@ async function executeCommitWithAI(intent) {
|
|
|
307
383
|
console.log();
|
|
308
384
|
}
|
|
309
385
|
}
|
|
386
|
+
/**
|
|
387
|
+
* Advanced conflict resolution - try multiple strategies
|
|
388
|
+
*/
|
|
389
|
+
async function tryAdvancedConflictResolution() {
|
|
390
|
+
try {
|
|
391
|
+
// Strategy 1: Try accepting ours (our changes)
|
|
392
|
+
try {
|
|
393
|
+
(0, child_process_1.execSync)('git checkout --ours .', { encoding: 'utf-8', stdio: 'pipe' });
|
|
394
|
+
(0, child_process_1.execSync)('git add .', { encoding: 'utf-8', stdio: 'pipe' });
|
|
395
|
+
(0, child_process_1.execSync)('git rebase --continue', { encoding: 'utf-8', stdio: 'pipe' });
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
// Strategy 1 failed
|
|
400
|
+
}
|
|
401
|
+
// Strategy 2: Try accepting theirs (remote changes)
|
|
402
|
+
try {
|
|
403
|
+
(0, child_process_1.execSync)('git rebase --abort', { encoding: 'utf-8', stdio: 'pipe' });
|
|
404
|
+
(0, child_process_1.execSync)('git pull --rebase', { encoding: 'utf-8', stdio: 'pipe' });
|
|
405
|
+
(0, child_process_1.execSync)('git checkout --theirs .', { encoding: 'utf-8', stdio: 'pipe' });
|
|
406
|
+
(0, child_process_1.execSync)('git add .', { encoding: 'utf-8', stdio: 'pipe' });
|
|
407
|
+
(0, child_process_1.execSync)('git rebase --continue', { encoding: 'utf-8', stdio: 'pipe' });
|
|
408
|
+
return true;
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
// Strategy 2 failed
|
|
412
|
+
}
|
|
413
|
+
// Strategy 3: Abort and let user handle
|
|
414
|
+
try {
|
|
415
|
+
(0, child_process_1.execSync)('git rebase --abort', { encoding: 'utf-8', stdio: 'pipe' });
|
|
416
|
+
}
|
|
417
|
+
catch {
|
|
418
|
+
// Already aborted
|
|
419
|
+
}
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
catch {
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
310
426
|
/**
|
|
311
427
|
* Execute Git commands - Cursor-style (clean, fast, auto-fix)
|
|
312
428
|
*/
|