@snapcommit/cli 2.0.5 → 2.2.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 +216 -239
- package/package.json +1 -1
|
@@ -1,8 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Cursor-style natural language Git assistant
|
|
4
|
-
*
|
|
4
|
+
* Fast, simple, auto-fixes errors, handles ALL Git + GitHub operations
|
|
5
5
|
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
6
39
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
40
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
41
|
};
|
|
@@ -10,135 +43,216 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
43
|
exports.executeCursorStyle = executeCursorStyle;
|
|
11
44
|
const chalk_1 = __importDefault(require("chalk"));
|
|
12
45
|
const child_process_1 = require("child_process");
|
|
13
|
-
const readline_1 = __importDefault(require("readline"));
|
|
14
46
|
const git_1 = require("../utils/git");
|
|
15
47
|
const auth_1 = require("../lib/auth");
|
|
48
|
+
const github_connect_1 = require("./github-connect");
|
|
49
|
+
const github = __importStar(require("../lib/github"));
|
|
16
50
|
async function executeCursorStyle(userInput) {
|
|
17
51
|
if (!(0, git_1.isGitRepo)()) {
|
|
18
52
|
console.log(chalk_1.default.red('\n❌ Not a git repository\n'));
|
|
19
53
|
return;
|
|
20
54
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
console.log(chalk_1.default.red('❌ Could not understand the request\n'));
|
|
55
|
+
const input = userInput.toLowerCase().trim();
|
|
56
|
+
// FAST PATH: Simple commit/push (no AI needed)
|
|
57
|
+
if (input.includes('commit') || input.includes('push') || input.includes('save')) {
|
|
58
|
+
await handleCommitAndPush();
|
|
26
59
|
return;
|
|
27
60
|
}
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
61
|
+
// COMPLEX PATH: Use AI for everything else (branch, merge, rebase, undo, GitHub, etc.)
|
|
62
|
+
await handleComplexCommand(userInput);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Fast path: Commit and push (no AI interpretation needed)
|
|
66
|
+
*/
|
|
67
|
+
async function handleCommitAndPush() {
|
|
68
|
+
const status = (0, git_1.getGitStatus)();
|
|
69
|
+
const hasChanges = status.staged > 0 || status.unstaged > 0 || status.untracked > 0;
|
|
70
|
+
if (!hasChanges) {
|
|
71
|
+
console.log(chalk_1.default.gray('\n✓ Branch clean\n'));
|
|
72
|
+
return;
|
|
38
73
|
}
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
74
|
+
// Stage all
|
|
75
|
+
try {
|
|
76
|
+
(0, git_1.stageAllChanges)();
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.log(chalk_1.default.red(`❌ ${error.message}\n`));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Generate AI commit message
|
|
83
|
+
const diff = (0, git_1.getGitDiff)(true);
|
|
84
|
+
const commitMessage = await generateCommitMessage(diff);
|
|
85
|
+
// Commit
|
|
86
|
+
try {
|
|
87
|
+
(0, child_process_1.execSync)(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
88
|
+
console.log(chalk_1.default.green(`✓ ${commitMessage.split('\n')[0]}`));
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.log(chalk_1.default.red(`❌ Commit failed\n`));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
// Push
|
|
95
|
+
try {
|
|
96
|
+
(0, child_process_1.execSync)('git push', { encoding: 'utf-8', stdio: 'pipe' });
|
|
97
|
+
console.log(chalk_1.default.green('✓ Pushed\n'));
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (error.message.includes('no configured push destination')) {
|
|
101
|
+
console.log(chalk_1.default.gray('✓ Committed locally (no remote)\n'));
|
|
51
102
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
plan.commitMessage = await editMessage(plan.commitMessage);
|
|
103
|
+
else {
|
|
104
|
+
console.log(chalk_1.default.yellow(`⚠️ ${error.message}\n`));
|
|
55
105
|
}
|
|
56
|
-
// Everything else (including "continue", "yes", "go ahead", "do it", "y", or just Enter) → proceed
|
|
57
106
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Complex path: Use AI to interpret and execute any Git/GitHub command
|
|
110
|
+
*/
|
|
111
|
+
async function handleComplexCommand(userInput) {
|
|
112
|
+
const token = (0, auth_1.getToken)();
|
|
113
|
+
if (!token) {
|
|
114
|
+
console.log(chalk_1.default.red('❌ Not authenticated\n'));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
// Get AI interpretation
|
|
118
|
+
const intent = await getAIInterpretation(userInput, token);
|
|
119
|
+
if (!intent) {
|
|
120
|
+
console.log(chalk_1.default.red('❌ Could not understand command\n'));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// Execute based on type
|
|
124
|
+
if (intent.type === 'git') {
|
|
125
|
+
await executeGitCommands(intent.gitCommands || []);
|
|
126
|
+
}
|
|
127
|
+
else if (intent.type === 'github') {
|
|
128
|
+
await executeGitHubCommand(intent);
|
|
129
|
+
}
|
|
130
|
+
console.log(chalk_1.default.green('✓ Done\n'));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Execute Git commands with auto-retry on errors
|
|
134
|
+
*/
|
|
135
|
+
async function executeGitCommands(commands) {
|
|
136
|
+
for (const cmd of commands) {
|
|
61
137
|
try {
|
|
62
|
-
|
|
138
|
+
(0, child_process_1.execSync)(cmd, { encoding: 'utf-8', stdio: 'pipe' });
|
|
63
139
|
}
|
|
64
140
|
catch (error) {
|
|
65
141
|
// Try to auto-fix common errors
|
|
66
|
-
const fixed = await tryAutoFix(error,
|
|
142
|
+
const fixed = await tryAutoFix(error, cmd);
|
|
67
143
|
if (!fixed) {
|
|
68
|
-
console.log(chalk_1.default.red(
|
|
69
|
-
console.log(chalk_1.default.yellow('💡 Try: "undo last change" to revert\n'));
|
|
144
|
+
console.log(chalk_1.default.red(`❌ ${error.message}\n`));
|
|
70
145
|
return;
|
|
71
146
|
}
|
|
72
147
|
}
|
|
73
148
|
}
|
|
74
|
-
console.log(chalk_1.default.green('\n✅ All done!\n'));
|
|
75
149
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Execute GitHub operations (PRs, CI, issues)
|
|
152
|
+
*/
|
|
153
|
+
async function executeGitHubCommand(intent) {
|
|
154
|
+
if (!(0, github_connect_1.isGitHubConnected)()) {
|
|
155
|
+
console.log(chalk_1.default.yellow('⚠️ GitHub not connected. Run: snap github connect\n'));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
switch (intent.action) {
|
|
160
|
+
case 'pr_create':
|
|
161
|
+
console.log(chalk_1.default.blue('Creating PR...'));
|
|
162
|
+
const pr = await github.createPullRequest(intent.options || {});
|
|
163
|
+
console.log(chalk_1.default.green(`✓ PR created: ${pr.html_url}`));
|
|
164
|
+
break;
|
|
165
|
+
case 'pr_list':
|
|
166
|
+
console.log(chalk_1.default.blue('Listing PRs...'));
|
|
167
|
+
const prs = await github.listPullRequests({ state: 'open', limit: 10 });
|
|
168
|
+
if (prs.length === 0) {
|
|
169
|
+
console.log(chalk_1.default.gray('No open PRs'));
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
prs.forEach((p) => console.log(chalk_1.default.cyan(` #${p.number}: ${p.title}`)));
|
|
173
|
+
}
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
console.log(chalk_1.default.yellow(`⚠️ GitHub action not implemented: ${intent.action}\n`));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
console.log(chalk_1.default.red(`❌ ${error.message}\n`));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Auto-fix common Git errors (like Cursor does)
|
|
185
|
+
*/
|
|
186
|
+
async function tryAutoFix(error, command) {
|
|
187
|
+
const errorMsg = error.message?.toLowerCase() || '';
|
|
188
|
+
// Merge conflict
|
|
189
|
+
if (errorMsg.includes('conflict')) {
|
|
190
|
+
console.log(chalk_1.default.yellow('⚠️ Merge conflict - attempting auto-resolve...'));
|
|
191
|
+
try {
|
|
192
|
+
// Try to accept current changes
|
|
193
|
+
(0, child_process_1.execSync)('git add .', { encoding: 'utf-8', stdio: 'pipe' });
|
|
194
|
+
(0, child_process_1.execSync)('git commit --no-edit', { encoding: 'utf-8', stdio: 'pipe' });
|
|
195
|
+
console.log(chalk_1.default.green('✓ Auto-resolved'));
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Diverged branches
|
|
203
|
+
if (errorMsg.includes('diverged') || errorMsg.includes('non-fast-forward')) {
|
|
204
|
+
console.log(chalk_1.default.yellow('⚠️ Branches diverged - pulling and retrying...'));
|
|
205
|
+
try {
|
|
206
|
+
(0, child_process_1.execSync)('git pull --rebase', { encoding: 'utf-8', stdio: 'pipe' });
|
|
207
|
+
(0, child_process_1.execSync)(command, { encoding: 'utf-8', stdio: 'pipe' });
|
|
208
|
+
console.log(chalk_1.default.green('✓ Fixed'));
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return false;
|
|
88
213
|
}
|
|
89
|
-
actions.push({
|
|
90
|
-
type: 'stage',
|
|
91
|
-
description: 'Stage all changes',
|
|
92
|
-
requiresConfirmation: false,
|
|
93
|
-
});
|
|
94
|
-
actions.push({
|
|
95
|
-
type: 'commit',
|
|
96
|
-
description: `Commit with message: "${commitMessage || 'Update'}"`,
|
|
97
|
-
requiresConfirmation: true,
|
|
98
|
-
requiresCommitMessage: true,
|
|
99
|
-
});
|
|
100
|
-
actions.push({
|
|
101
|
-
type: 'push',
|
|
102
|
-
description: 'Push to origin',
|
|
103
|
-
command: 'git push',
|
|
104
|
-
requiresConfirmation: true,
|
|
105
|
-
});
|
|
106
|
-
return {
|
|
107
|
-
actions,
|
|
108
|
-
commitMessage,
|
|
109
|
-
explanation: 'Stage all changes, commit with AI-generated message, and push to remote',
|
|
110
|
-
};
|
|
111
214
|
}
|
|
112
|
-
//
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
215
|
+
// Unstaged changes
|
|
216
|
+
if (errorMsg.includes('unstaged') || errorMsg.includes('uncommitted')) {
|
|
217
|
+
console.log(chalk_1.default.yellow('⚠️ Unstaged changes - stashing and retrying...'));
|
|
218
|
+
try {
|
|
219
|
+
(0, child_process_1.execSync)('git stash', { encoding: 'utf-8', stdio: 'pipe' });
|
|
220
|
+
(0, child_process_1.execSync)(command, { encoding: 'utf-8', stdio: 'pipe' });
|
|
221
|
+
(0, child_process_1.execSync)('git stash pop', { encoding: 'utf-8', stdio: 'pipe' });
|
|
222
|
+
console.log(chalk_1.default.green('✓ Fixed'));
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
return false;
|
|
117
227
|
}
|
|
118
|
-
actions.push({
|
|
119
|
-
type: 'stage',
|
|
120
|
-
description: 'Stage all changes',
|
|
121
|
-
requiresConfirmation: false,
|
|
122
|
-
});
|
|
123
|
-
actions.push({
|
|
124
|
-
type: 'commit',
|
|
125
|
-
description: `Commit with message: "${commitMessage || 'Update'}"`,
|
|
126
|
-
requiresConfirmation: true,
|
|
127
|
-
requiresCommitMessage: true,
|
|
128
|
-
});
|
|
129
|
-
return {
|
|
130
|
-
actions,
|
|
131
|
-
commitMessage,
|
|
132
|
-
explanation: 'Stage and commit changes with AI-generated message',
|
|
133
|
-
};
|
|
134
228
|
}
|
|
135
|
-
|
|
136
|
-
return await getAIInterpretation(userInput);
|
|
229
|
+
return false;
|
|
137
230
|
}
|
|
138
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Get AI interpretation for complex commands
|
|
233
|
+
*/
|
|
234
|
+
async function getAIInterpretation(userInput, token) {
|
|
139
235
|
try {
|
|
140
|
-
(0, git_1.
|
|
141
|
-
|
|
236
|
+
const currentBranch = (0, git_1.getCurrentBranch)();
|
|
237
|
+
const status = (0, git_1.getGitStatus)();
|
|
238
|
+
const response = await fetch('https://snapcommit.dev/api/ai/interpret', {
|
|
239
|
+
method: 'POST',
|
|
240
|
+
headers: { 'Content-Type': 'application/json' },
|
|
241
|
+
body: JSON.stringify({
|
|
242
|
+
userInput,
|
|
243
|
+
token,
|
|
244
|
+
context: {
|
|
245
|
+
currentBranch,
|
|
246
|
+
hasUncommittedChanges: status.unstaged > 0 || status.untracked > 0,
|
|
247
|
+
lastCommitHash: (0, child_process_1.execSync)('git log -1 --format=%H 2>/dev/null || echo ""', { encoding: 'utf-8' }).trim(),
|
|
248
|
+
remoteBranch: (0, child_process_1.execSync)('git rev-parse --abbrev-ref @{upstream} 2>/dev/null || echo ""', { encoding: 'utf-8' }).trim(),
|
|
249
|
+
},
|
|
250
|
+
}),
|
|
251
|
+
});
|
|
252
|
+
if (!response.ok)
|
|
253
|
+
return null;
|
|
254
|
+
const data = await response.json();
|
|
255
|
+
return data.intent;
|
|
142
256
|
}
|
|
143
257
|
catch {
|
|
144
258
|
return null;
|
|
@@ -176,141 +290,4 @@ async function generateCommitMessage(diff) {
|
|
|
176
290
|
return 'Update changes';
|
|
177
291
|
}
|
|
178
292
|
}
|
|
179
|
-
|
|
180
|
-
const token = (0, auth_1.getToken)();
|
|
181
|
-
if (!token)
|
|
182
|
-
return null;
|
|
183
|
-
try {
|
|
184
|
-
const currentBranch = (0, git_1.getCurrentBranch)();
|
|
185
|
-
const status = (0, git_1.getGitStatus)();
|
|
186
|
-
const response = await fetch('https://snapcommit.dev/api/ai/interpret', {
|
|
187
|
-
method: 'POST',
|
|
188
|
-
headers: { 'Content-Type': 'application/json' },
|
|
189
|
-
body: JSON.stringify({
|
|
190
|
-
userInput,
|
|
191
|
-
token,
|
|
192
|
-
context: {
|
|
193
|
-
currentBranch,
|
|
194
|
-
hasUncommittedChanges: status.unstaged > 0 || status.untracked > 0,
|
|
195
|
-
lastCommitHash: (0, child_process_1.execSync)('git log -1 --format=%H 2>/dev/null || echo ""', { encoding: 'utf-8' }).trim(),
|
|
196
|
-
remoteBranch: (0, child_process_1.execSync)('git rev-parse --abbrev-ref @{upstream} 2>/dev/null || echo ""', { encoding: 'utf-8' }).trim(),
|
|
197
|
-
},
|
|
198
|
-
}),
|
|
199
|
-
});
|
|
200
|
-
const data = await response.json();
|
|
201
|
-
// Convert AI intent to execution plan
|
|
202
|
-
// This is a simplified version - in production, this would be more sophisticated
|
|
203
|
-
return convertIntentToPlan(data.intent);
|
|
204
|
-
}
|
|
205
|
-
catch {
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
function convertIntentToPlan(intent) {
|
|
210
|
-
// Convert the AI intent format to our execution plan format
|
|
211
|
-
// This bridges the existing intent format with the new Cursor-style execution
|
|
212
|
-
if (!intent || !intent.gitCommands)
|
|
213
|
-
return null;
|
|
214
|
-
const actions = intent.gitCommands.map((cmd, i) => ({
|
|
215
|
-
type: inferActionType(cmd),
|
|
216
|
-
description: intent.explanation || `Execute: ${cmd}`,
|
|
217
|
-
command: cmd,
|
|
218
|
-
requiresConfirmation: intent.needsConfirmation || intent.riskLevel !== 'safe',
|
|
219
|
-
}));
|
|
220
|
-
return {
|
|
221
|
-
actions,
|
|
222
|
-
explanation: intent.explanation,
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
function inferActionType(command) {
|
|
226
|
-
if (command.includes('git add'))
|
|
227
|
-
return 'stage';
|
|
228
|
-
if (command.includes('git commit'))
|
|
229
|
-
return 'commit';
|
|
230
|
-
if (command.includes('git push'))
|
|
231
|
-
return 'push';
|
|
232
|
-
if (command.includes('git checkout') || command.includes('git switch'))
|
|
233
|
-
return 'checkout';
|
|
234
|
-
if (command.includes('git merge'))
|
|
235
|
-
return 'merge';
|
|
236
|
-
if (command.includes('git reset'))
|
|
237
|
-
return 'reset';
|
|
238
|
-
if (command.includes('git branch'))
|
|
239
|
-
return 'branch';
|
|
240
|
-
if (command.includes('git pull'))
|
|
241
|
-
return 'pull';
|
|
242
|
-
if (command.includes('git rebase'))
|
|
243
|
-
return 'rebase';
|
|
244
|
-
if (command.includes('git cherry-pick'))
|
|
245
|
-
return 'cherry-pick';
|
|
246
|
-
return 'stage';
|
|
247
|
-
}
|
|
248
|
-
async function executeAction(action, commitMessage) {
|
|
249
|
-
switch (action.type) {
|
|
250
|
-
case 'stage':
|
|
251
|
-
(0, git_1.stageAllChanges)();
|
|
252
|
-
console.log(chalk_1.default.green(' ✓ Staged all changes'));
|
|
253
|
-
break;
|
|
254
|
-
case 'commit':
|
|
255
|
-
if (commitMessage) {
|
|
256
|
-
(0, child_process_1.execSync)(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, { encoding: 'utf-8' });
|
|
257
|
-
console.log(chalk_1.default.green(` ✓ Committed`));
|
|
258
|
-
}
|
|
259
|
-
break;
|
|
260
|
-
case 'push':
|
|
261
|
-
(0, child_process_1.execSync)('git push', { encoding: 'utf-8', stdio: 'pipe' });
|
|
262
|
-
console.log(chalk_1.default.green(' ✓ Pushed to remote'));
|
|
263
|
-
break;
|
|
264
|
-
default:
|
|
265
|
-
if (action.command) {
|
|
266
|
-
(0, child_process_1.execSync)(action.command, { encoding: 'utf-8', stdio: 'pipe' });
|
|
267
|
-
console.log(chalk_1.default.green(` ✓ ${action.description}`));
|
|
268
|
-
}
|
|
269
|
-
break;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
async function tryAutoFix(error, action) {
|
|
273
|
-
const errorMsg = error.message?.toLowerCase() || '';
|
|
274
|
-
// Handle "no remote configured"
|
|
275
|
-
if (errorMsg.includes('no configured push destination')) {
|
|
276
|
-
console.log(chalk_1.default.yellow('\n⚠️ No remote repository configured'));
|
|
277
|
-
console.log(chalk_1.default.gray(' You need to add a remote first\n'));
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
280
|
-
// Handle merge conflicts
|
|
281
|
-
if (errorMsg.includes('conflict')) {
|
|
282
|
-
console.log(chalk_1.default.yellow('\n⚠️ Merge conflict detected'));
|
|
283
|
-
console.log(chalk_1.default.gray(' Use: "resolve conflicts" to fix\n'));
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
// Handle auth failures
|
|
287
|
-
if (errorMsg.includes('authentication') || errorMsg.includes('permission denied')) {
|
|
288
|
-
console.log(chalk_1.default.yellow('\n⚠️ Authentication failed'));
|
|
289
|
-
console.log(chalk_1.default.gray(' Check your Git credentials\n'));
|
|
290
|
-
return false;
|
|
291
|
-
}
|
|
292
|
-
return false;
|
|
293
|
-
}
|
|
294
|
-
function askQuestion(query) {
|
|
295
|
-
const rl = readline_1.default.createInterface({
|
|
296
|
-
input: process.stdin,
|
|
297
|
-
output: process.stdout,
|
|
298
|
-
terminal: false, // Don't process terminal escape sequences
|
|
299
|
-
});
|
|
300
|
-
return new Promise((resolve) => {
|
|
301
|
-
// Write prompt manually
|
|
302
|
-
process.stdout.write(query);
|
|
303
|
-
// Listen for ONE line of input
|
|
304
|
-
rl.once('line', (answer) => {
|
|
305
|
-
rl.close();
|
|
306
|
-
resolve(answer.trim());
|
|
307
|
-
});
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
async function editMessage(originalMessage) {
|
|
311
|
-
console.log(chalk_1.default.cyan('\n✏️ Edit commit message:\n'));
|
|
312
|
-
console.log(chalk_1.default.gray(' (Press Enter to keep, or type new message)\n'));
|
|
313
|
-
console.log(chalk_1.default.white(` Current: ${chalk_1.default.cyan(originalMessage)}\n`));
|
|
314
|
-
const newMessage = await askQuestion(chalk_1.default.yellow(' New message: '));
|
|
315
|
-
return newMessage.trim() || originalMessage;
|
|
316
|
-
}
|
|
293
|
+
// All complex logic removed - keeping it DEAD SIMPLE!
|