@snapcommit/cli 3.8.24 → 3.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.
- package/dist/commands/cursor-style.js +121 -2
- package/dist/lib/github.js +44 -0
- package/package.json +1 -1
|
@@ -134,8 +134,31 @@ async function showStatus() {
|
|
|
134
134
|
async function executeCommitWithAI(intent) {
|
|
135
135
|
const status = (0, git_1.getGitStatus)();
|
|
136
136
|
const hasChanges = status.staged > 0 || status.unstaged > 0 || status.untracked > 0;
|
|
137
|
-
if (
|
|
138
|
-
|
|
137
|
+
// Check if there are unpushed commits (even if working tree is clean)
|
|
138
|
+
let hasUnpushedCommits = false;
|
|
139
|
+
try {
|
|
140
|
+
const unpushed = (0, child_process_1.execSync)('git log @{u}.. --oneline 2>/dev/null || echo ""', { encoding: 'utf-8' }).trim();
|
|
141
|
+
hasUnpushedCommits = unpushed.length > 0;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// No upstream or other error - assume we need to push
|
|
145
|
+
hasUnpushedCommits = true;
|
|
146
|
+
}
|
|
147
|
+
// If no changes AND no unpushed commits, nothing to do
|
|
148
|
+
if (!hasChanges && !hasUnpushedCommits) {
|
|
149
|
+
console.log(chalk_1.default.gray('\n✓ Branch clean - nothing to commit or push\n'));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// If no changes but there are unpushed commits, just push
|
|
153
|
+
if (!hasChanges && hasUnpushedCommits) {
|
|
154
|
+
console.log(chalk_1.default.blue('\n🔄 Pushing unpushed commits...\n'));
|
|
155
|
+
try {
|
|
156
|
+
(0, child_process_1.execSync)('git push', { encoding: 'utf-8', stdio: 'inherit' });
|
|
157
|
+
console.log(chalk_1.default.green('\n✓ Pushed successfully\n'));
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
console.log(chalk_1.default.red(`\n❌ Push failed: ${error.message}\n`));
|
|
161
|
+
}
|
|
139
162
|
return;
|
|
140
163
|
}
|
|
141
164
|
// Count files
|
|
@@ -977,6 +1000,102 @@ async function executeGitHubCommand(intent) {
|
|
|
977
1000
|
await github.markPRReady(readyPrNum);
|
|
978
1001
|
console.log(chalk_1.default.green(`✓ PR #${readyPrNum} is now ready for review\n`));
|
|
979
1002
|
break;
|
|
1003
|
+
case 'merge_queue_add':
|
|
1004
|
+
case 'merge_queue_enable_auto':
|
|
1005
|
+
// GitHub native merge queue (requires branch protection rules)
|
|
1006
|
+
let queuePrNum = intent.target || intent.options?.number;
|
|
1007
|
+
// Auto-detect PR if not specified
|
|
1008
|
+
if (!queuePrNum) {
|
|
1009
|
+
queuePrNum = await github.findPRNumber('current');
|
|
1010
|
+
if (!queuePrNum) {
|
|
1011
|
+
console.log(chalk_1.default.red('\n❌ No PR found for current branch\n'));
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
// GitHub merge queue = enable auto-merge
|
|
1016
|
+
console.log(chalk_1.default.blue(`\n🔄 Adding PR #${queuePrNum} to merge queue...\n`));
|
|
1017
|
+
console.log(chalk_1.default.gray(' ℹ️ This enables auto-merge (GitHub merge queue requires branch protection)\n'));
|
|
1018
|
+
try {
|
|
1019
|
+
await github.enableAutoMerge(queuePrNum, 'MERGE');
|
|
1020
|
+
console.log(chalk_1.default.green(`✓ PR #${queuePrNum} will auto-merge when:\n`));
|
|
1021
|
+
console.log(chalk_1.default.gray(' • All checks pass'));
|
|
1022
|
+
console.log(chalk_1.default.gray(' • Required reviews are approved'));
|
|
1023
|
+
console.log(chalk_1.default.gray(' • Branch is up to date\n'));
|
|
1024
|
+
}
|
|
1025
|
+
catch (error) {
|
|
1026
|
+
if (error.message.includes('not enabled')) {
|
|
1027
|
+
console.log(chalk_1.default.yellow('\n⚠️ Merge queue not enabled for this repository\n'));
|
|
1028
|
+
console.log(chalk_1.default.white('To enable:'));
|
|
1029
|
+
console.log(chalk_1.default.gray(' 1. Go to repo Settings → Branches'));
|
|
1030
|
+
console.log(chalk_1.default.gray(' 2. Edit branch protection rules'));
|
|
1031
|
+
console.log(chalk_1.default.gray(' 3. Enable "Require merge queue"\n'));
|
|
1032
|
+
}
|
|
1033
|
+
else {
|
|
1034
|
+
throw error;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
break;
|
|
1038
|
+
case 'merge_queue_status':
|
|
1039
|
+
// Show auto-merge status for current PR
|
|
1040
|
+
let statusPrNum = intent.target || intent.options?.number;
|
|
1041
|
+
if (!statusPrNum) {
|
|
1042
|
+
statusPrNum = await github.findPRNumber('current');
|
|
1043
|
+
if (!statusPrNum) {
|
|
1044
|
+
console.log(chalk_1.default.red('\n❌ No PR found for current branch\n'));
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
console.log(chalk_1.default.blue(`\n🔍 Checking merge queue status for PR #${statusPrNum}...\n`));
|
|
1049
|
+
try {
|
|
1050
|
+
const prDetails = await github.getPullRequest(statusPrNum);
|
|
1051
|
+
const autoMergeEnabled = prDetails.auto_merge !== null;
|
|
1052
|
+
if (autoMergeEnabled) {
|
|
1053
|
+
console.log(chalk_1.default.green('✓ PR is in merge queue (auto-merge enabled)\n'));
|
|
1054
|
+
console.log(chalk_1.default.white('Status:'));
|
|
1055
|
+
console.log(chalk_1.default.gray(` • Merge method: ${prDetails.auto_merge.merge_method.toUpperCase()}`));
|
|
1056
|
+
console.log(chalk_1.default.gray(` • Waiting for: ${prDetails.mergeable_state}`));
|
|
1057
|
+
// Check CI status
|
|
1058
|
+
const ciStatus = await github.getCommitStatus();
|
|
1059
|
+
if (ciStatus.status.state === 'success') {
|
|
1060
|
+
console.log(chalk_1.default.green(' • CI: ✓ Passed'));
|
|
1061
|
+
}
|
|
1062
|
+
else if (ciStatus.status.state === 'pending') {
|
|
1063
|
+
console.log(chalk_1.default.yellow(' • CI: ⏳ Running'));
|
|
1064
|
+
}
|
|
1065
|
+
else {
|
|
1066
|
+
console.log(chalk_1.default.red(' • CI: ❌ Failed'));
|
|
1067
|
+
}
|
|
1068
|
+
console.log();
|
|
1069
|
+
}
|
|
1070
|
+
else {
|
|
1071
|
+
console.log(chalk_1.default.gray('✓ PR is not in merge queue\n'));
|
|
1072
|
+
console.log(chalk_1.default.white('To add to queue:'));
|
|
1073
|
+
console.log(chalk_1.default.cyan(' enable auto-merge when CI passes\n'));
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
catch (error) {
|
|
1077
|
+
console.log(chalk_1.default.red(`\n❌ Failed to check status: ${error.message}\n`));
|
|
1078
|
+
}
|
|
1079
|
+
break;
|
|
1080
|
+
case 'merge_queue_remove':
|
|
1081
|
+
// Disable auto-merge
|
|
1082
|
+
let removePrNum = intent.target || intent.options?.number;
|
|
1083
|
+
if (!removePrNum) {
|
|
1084
|
+
removePrNum = await github.findPRNumber('current');
|
|
1085
|
+
if (!removePrNum) {
|
|
1086
|
+
console.log(chalk_1.default.red('\n❌ No PR found for current branch\n'));
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
console.log(chalk_1.default.blue(`\n🔄 Removing PR #${removePrNum} from merge queue...\n`));
|
|
1091
|
+
try {
|
|
1092
|
+
await github.disableAutoMerge(removePrNum);
|
|
1093
|
+
console.log(chalk_1.default.green(`✓ PR #${removePrNum} removed from merge queue\n`));
|
|
1094
|
+
}
|
|
1095
|
+
catch (error) {
|
|
1096
|
+
console.log(chalk_1.default.red(`\n❌ Failed: ${error.message}\n`));
|
|
1097
|
+
}
|
|
1098
|
+
break;
|
|
980
1099
|
default:
|
|
981
1100
|
console.log(chalk_1.default.yellow(`\n⚠️ Action not supported: ${intent.action}\n`));
|
|
982
1101
|
}
|
package/dist/lib/github.js
CHANGED
|
@@ -25,6 +25,7 @@ exports.rerunWorkflow = rerunWorkflow;
|
|
|
25
25
|
exports.getPullRequestFiles = getPullRequestFiles;
|
|
26
26
|
exports.addLabels = addLabels;
|
|
27
27
|
exports.enableAutoMerge = enableAutoMerge;
|
|
28
|
+
exports.disableAutoMerge = disableAutoMerge;
|
|
28
29
|
exports.createDraftPullRequest = createDraftPullRequest;
|
|
29
30
|
exports.markPRReady = markPRReady;
|
|
30
31
|
exports.getPRStack = getPRStack;
|
|
@@ -481,6 +482,49 @@ async function enableAutoMerge(prNumber, mergeMethod = 'MERGE') {
|
|
|
481
482
|
}
|
|
482
483
|
return await response.json();
|
|
483
484
|
}
|
|
485
|
+
/**
|
|
486
|
+
* Disable auto-merge for a PR
|
|
487
|
+
*/
|
|
488
|
+
async function disableAutoMerge(prNumber) {
|
|
489
|
+
const repo = getCurrentRepo();
|
|
490
|
+
if (!repo) {
|
|
491
|
+
throw new Error('Not a GitHub repository');
|
|
492
|
+
}
|
|
493
|
+
// GraphQL query for disabling auto-merge
|
|
494
|
+
const token = (0, github_connect_1.getGitHubToken)();
|
|
495
|
+
if (!token) {
|
|
496
|
+
throw new Error('GitHub not connected');
|
|
497
|
+
}
|
|
498
|
+
// First get PR node ID
|
|
499
|
+
const pr = await getPullRequest(prNumber);
|
|
500
|
+
const nodeId = pr.node_id;
|
|
501
|
+
const query = `
|
|
502
|
+
mutation {
|
|
503
|
+
disablePullRequestAutoMerge(input: {
|
|
504
|
+
pullRequestId: "${nodeId}"
|
|
505
|
+
}) {
|
|
506
|
+
pullRequest {
|
|
507
|
+
id
|
|
508
|
+
autoMergeRequest {
|
|
509
|
+
enabledAt
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
`;
|
|
515
|
+
const response = await fetch('https://api.github.com/graphql', {
|
|
516
|
+
method: 'POST',
|
|
517
|
+
headers: {
|
|
518
|
+
Authorization: `Bearer ${token}`,
|
|
519
|
+
'Content-Type': 'application/json',
|
|
520
|
+
},
|
|
521
|
+
body: JSON.stringify({ query }),
|
|
522
|
+
});
|
|
523
|
+
if (!response.ok) {
|
|
524
|
+
throw new Error('Failed to disable auto-merge');
|
|
525
|
+
}
|
|
526
|
+
return await response.json();
|
|
527
|
+
}
|
|
484
528
|
/**
|
|
485
529
|
* Create a draft PR (for stacked PRs)
|
|
486
530
|
*/
|