@snapcommit/cli 2.0.4 → 2.1.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 +47 -248
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Cursor-style natural language Git assistant
|
|
4
|
-
*
|
|
4
|
+
* DEAD SIMPLE: Check status → Show changes → Commit → Push → Done!
|
|
5
5
|
*/
|
|
6
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -17,128 +17,62 @@ async function executeCursorStyle(userInput) {
|
|
|
17
17
|
console.log(chalk_1.default.red('\n❌ Not a git repository\n'));
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
if (!
|
|
24
|
-
console.log(chalk_1.default.
|
|
20
|
+
// Check if there are any changes first
|
|
21
|
+
const status = (0, git_1.getGitStatus)();
|
|
22
|
+
const hasChanges = status.staged > 0 || status.unstaged > 0 || status.untracked > 0;
|
|
23
|
+
if (!hasChanges) {
|
|
24
|
+
console.log(chalk_1.default.gray('\n✓ Branch clean - no changes to commit\n'));
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
-
// Show
|
|
28
|
-
console.log(chalk_1.default.
|
|
29
|
-
|
|
30
|
-
console.log(chalk_1.default.
|
|
31
|
-
|
|
27
|
+
// Show what changed
|
|
28
|
+
console.log(chalk_1.default.blue('\n📦 Changes detected:\n'));
|
|
29
|
+
if (status.unstaged > 0)
|
|
30
|
+
console.log(chalk_1.default.yellow(` • ${status.unstaged} modified`));
|
|
31
|
+
if (status.untracked > 0)
|
|
32
|
+
console.log(chalk_1.default.yellow(` • ${status.untracked} new`));
|
|
33
|
+
if (status.staged > 0)
|
|
34
|
+
console.log(chalk_1.default.green(` • ${status.staged} staged`));
|
|
32
35
|
console.log();
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
console.log();
|
|
37
|
-
}
|
|
38
|
-
// Ask for confirmation
|
|
39
|
-
const needsConfirm = plan.actions.some(a => a.requiresConfirmation);
|
|
40
|
-
if (needsConfirm) {
|
|
41
|
-
const confirmOptions = plan.commitMessage
|
|
42
|
-
? chalk_1.default.yellow('Continue? (Y/n/e to edit message): ')
|
|
43
|
-
: chalk_1.default.yellow('Continue? (Y/n): ');
|
|
44
|
-
const answer = await askQuestion(confirmOptions);
|
|
45
|
-
if (answer.toLowerCase() === 'n') {
|
|
46
|
-
console.log(chalk_1.default.gray('\n✗ Cancelled\n'));
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (answer.toLowerCase() === 'e' && plan.commitMessage) {
|
|
50
|
-
plan.commitMessage = await editMessage(plan.commitMessage);
|
|
51
|
-
}
|
|
36
|
+
// Stage everything
|
|
37
|
+
try {
|
|
38
|
+
(0, git_1.stageAllChanges)();
|
|
52
39
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
await executeAction(action, plan.commitMessage);
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
// Try to auto-fix common errors
|
|
61
|
-
const fixed = await tryAutoFix(error, action);
|
|
62
|
-
if (!fixed) {
|
|
63
|
-
console.log(chalk_1.default.red(`\n❌ Error: ${error.message}\n`));
|
|
64
|
-
console.log(chalk_1.default.yellow('💡 Try: "undo last change" to revert\n'));
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.log(chalk_1.default.red(`❌ Failed to stage changes: ${error.message}\n`));
|
|
42
|
+
return;
|
|
68
43
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (input.includes('commit') && input.includes('push')) {
|
|
79
|
-
// Generate commit message
|
|
80
|
-
const diff = await getChangeDiff();
|
|
81
|
-
if (diff) {
|
|
82
|
-
commitMessage = await generateCommitMessage(diff);
|
|
83
|
-
}
|
|
84
|
-
actions.push({
|
|
85
|
-
type: 'stage',
|
|
86
|
-
description: 'Stage all changes',
|
|
87
|
-
requiresConfirmation: false,
|
|
88
|
-
});
|
|
89
|
-
actions.push({
|
|
90
|
-
type: 'commit',
|
|
91
|
-
description: `Commit with message: "${commitMessage || 'Update'}"`,
|
|
92
|
-
requiresConfirmation: true,
|
|
93
|
-
requiresCommitMessage: true,
|
|
94
|
-
});
|
|
95
|
-
actions.push({
|
|
96
|
-
type: 'push',
|
|
97
|
-
description: 'Push to origin',
|
|
98
|
-
command: 'git push',
|
|
99
|
-
requiresConfirmation: true,
|
|
100
|
-
});
|
|
101
|
-
return {
|
|
102
|
-
actions,
|
|
103
|
-
commitMessage,
|
|
104
|
-
explanation: 'Stage all changes, commit with AI-generated message, and push to remote',
|
|
105
|
-
};
|
|
44
|
+
// Generate commit message
|
|
45
|
+
console.log(chalk_1.default.blue('🤖 Generating commit message...'));
|
|
46
|
+
const diff = (0, git_1.getGitDiff)(true);
|
|
47
|
+
const commitMessage = await generateCommitMessage(diff);
|
|
48
|
+
console.log(chalk_1.default.green(`\n📝 ${commitMessage.split('\n')[0]}\n`));
|
|
49
|
+
// Commit
|
|
50
|
+
try {
|
|
51
|
+
(0, child_process_1.execSync)(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
52
|
+
console.log(chalk_1.default.green('✓ Committed'));
|
|
106
53
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (diff) {
|
|
111
|
-
commitMessage = await generateCommitMessage(diff);
|
|
112
|
-
}
|
|
113
|
-
actions.push({
|
|
114
|
-
type: 'stage',
|
|
115
|
-
description: 'Stage all changes',
|
|
116
|
-
requiresConfirmation: false,
|
|
117
|
-
});
|
|
118
|
-
actions.push({
|
|
119
|
-
type: 'commit',
|
|
120
|
-
description: `Commit with message: "${commitMessage || 'Update'}"`,
|
|
121
|
-
requiresConfirmation: true,
|
|
122
|
-
requiresCommitMessage: true,
|
|
123
|
-
});
|
|
124
|
-
return {
|
|
125
|
-
actions,
|
|
126
|
-
commitMessage,
|
|
127
|
-
explanation: 'Stage and commit changes with AI-generated message',
|
|
128
|
-
};
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.log(chalk_1.default.red(`❌ Commit failed: ${error.message}\n`));
|
|
56
|
+
return;
|
|
129
57
|
}
|
|
130
|
-
//
|
|
131
|
-
return await getAIInterpretation(userInput);
|
|
132
|
-
}
|
|
133
|
-
async function getChangeDiff() {
|
|
58
|
+
// Push
|
|
134
59
|
try {
|
|
135
|
-
(
|
|
136
|
-
|
|
60
|
+
console.log(chalk_1.default.blue('⬆️ Pushing to remote...'));
|
|
61
|
+
(0, child_process_1.execSync)('git push', { encoding: 'utf-8', stdio: 'pipe' });
|
|
62
|
+
console.log(chalk_1.default.green('✓ Pushed\n'));
|
|
137
63
|
}
|
|
138
|
-
catch {
|
|
139
|
-
|
|
64
|
+
catch (error) {
|
|
65
|
+
// If push fails (e.g., no remote), that's okay
|
|
66
|
+
if (error.message.includes('no configured push destination')) {
|
|
67
|
+
console.log(chalk_1.default.yellow('⚠️ No remote configured - changes committed locally\n'));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
console.log(chalk_1.default.yellow(`⚠️ Push failed: ${error.message}\n`));
|
|
71
|
+
}
|
|
140
72
|
}
|
|
73
|
+
console.log(chalk_1.default.green('✅ Done!\n'));
|
|
141
74
|
}
|
|
75
|
+
// All removed - we're keeping it SUPER simple now!
|
|
142
76
|
async function generateCommitMessage(diff) {
|
|
143
77
|
const token = (0, auth_1.getToken)();
|
|
144
78
|
if (!token) {
|
|
@@ -171,139 +105,4 @@ async function generateCommitMessage(diff) {
|
|
|
171
105
|
return 'Update changes';
|
|
172
106
|
}
|
|
173
107
|
}
|
|
174
|
-
|
|
175
|
-
const token = (0, auth_1.getToken)();
|
|
176
|
-
if (!token)
|
|
177
|
-
return null;
|
|
178
|
-
try {
|
|
179
|
-
const currentBranch = (0, git_1.getCurrentBranch)();
|
|
180
|
-
const status = (0, git_1.getGitStatus)();
|
|
181
|
-
const response = await fetch('https://snapcommit.dev/api/ai/interpret', {
|
|
182
|
-
method: 'POST',
|
|
183
|
-
headers: { 'Content-Type': 'application/json' },
|
|
184
|
-
body: JSON.stringify({
|
|
185
|
-
userInput,
|
|
186
|
-
token,
|
|
187
|
-
context: {
|
|
188
|
-
currentBranch,
|
|
189
|
-
hasUncommittedChanges: status.unstaged > 0 || status.untracked > 0,
|
|
190
|
-
lastCommitHash: (0, child_process_1.execSync)('git log -1 --format=%H 2>/dev/null || echo ""', { encoding: 'utf-8' }).trim(),
|
|
191
|
-
remoteBranch: (0, child_process_1.execSync)('git rev-parse --abbrev-ref @{upstream} 2>/dev/null || echo ""', { encoding: 'utf-8' }).trim(),
|
|
192
|
-
},
|
|
193
|
-
}),
|
|
194
|
-
});
|
|
195
|
-
const data = await response.json();
|
|
196
|
-
// Convert AI intent to execution plan
|
|
197
|
-
// This is a simplified version - in production, this would be more sophisticated
|
|
198
|
-
return convertIntentToPlan(data.intent);
|
|
199
|
-
}
|
|
200
|
-
catch {
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
function convertIntentToPlan(intent) {
|
|
205
|
-
// Convert the AI intent format to our execution plan format
|
|
206
|
-
// This bridges the existing intent format with the new Cursor-style execution
|
|
207
|
-
if (!intent || !intent.gitCommands)
|
|
208
|
-
return null;
|
|
209
|
-
const actions = intent.gitCommands.map((cmd, i) => ({
|
|
210
|
-
type: inferActionType(cmd),
|
|
211
|
-
description: intent.explanation || `Execute: ${cmd}`,
|
|
212
|
-
command: cmd,
|
|
213
|
-
requiresConfirmation: intent.needsConfirmation || intent.riskLevel !== 'safe',
|
|
214
|
-
}));
|
|
215
|
-
return {
|
|
216
|
-
actions,
|
|
217
|
-
explanation: intent.explanation,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
function inferActionType(command) {
|
|
221
|
-
if (command.includes('git add'))
|
|
222
|
-
return 'stage';
|
|
223
|
-
if (command.includes('git commit'))
|
|
224
|
-
return 'commit';
|
|
225
|
-
if (command.includes('git push'))
|
|
226
|
-
return 'push';
|
|
227
|
-
if (command.includes('git checkout') || command.includes('git switch'))
|
|
228
|
-
return 'checkout';
|
|
229
|
-
if (command.includes('git merge'))
|
|
230
|
-
return 'merge';
|
|
231
|
-
if (command.includes('git reset'))
|
|
232
|
-
return 'reset';
|
|
233
|
-
if (command.includes('git branch'))
|
|
234
|
-
return 'branch';
|
|
235
|
-
if (command.includes('git pull'))
|
|
236
|
-
return 'pull';
|
|
237
|
-
if (command.includes('git rebase'))
|
|
238
|
-
return 'rebase';
|
|
239
|
-
if (command.includes('git cherry-pick'))
|
|
240
|
-
return 'cherry-pick';
|
|
241
|
-
return 'stage';
|
|
242
|
-
}
|
|
243
|
-
async function executeAction(action, commitMessage) {
|
|
244
|
-
switch (action.type) {
|
|
245
|
-
case 'stage':
|
|
246
|
-
(0, git_1.stageAllChanges)();
|
|
247
|
-
console.log(chalk_1.default.green(' ✓ Staged all changes'));
|
|
248
|
-
break;
|
|
249
|
-
case 'commit':
|
|
250
|
-
if (commitMessage) {
|
|
251
|
-
(0, child_process_1.execSync)(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, { encoding: 'utf-8' });
|
|
252
|
-
console.log(chalk_1.default.green(` ✓ Committed`));
|
|
253
|
-
}
|
|
254
|
-
break;
|
|
255
|
-
case 'push':
|
|
256
|
-
(0, child_process_1.execSync)('git push', { encoding: 'utf-8', stdio: 'pipe' });
|
|
257
|
-
console.log(chalk_1.default.green(' ✓ Pushed to remote'));
|
|
258
|
-
break;
|
|
259
|
-
default:
|
|
260
|
-
if (action.command) {
|
|
261
|
-
(0, child_process_1.execSync)(action.command, { encoding: 'utf-8', stdio: 'pipe' });
|
|
262
|
-
console.log(chalk_1.default.green(` ✓ ${action.description}`));
|
|
263
|
-
}
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
async function tryAutoFix(error, action) {
|
|
268
|
-
const errorMsg = error.message?.toLowerCase() || '';
|
|
269
|
-
// Handle "no remote configured"
|
|
270
|
-
if (errorMsg.includes('no configured push destination')) {
|
|
271
|
-
console.log(chalk_1.default.yellow('\n⚠️ No remote repository configured'));
|
|
272
|
-
console.log(chalk_1.default.gray(' You need to add a remote first\n'));
|
|
273
|
-
return false;
|
|
274
|
-
}
|
|
275
|
-
// Handle merge conflicts
|
|
276
|
-
if (errorMsg.includes('conflict')) {
|
|
277
|
-
console.log(chalk_1.default.yellow('\n⚠️ Merge conflict detected'));
|
|
278
|
-
console.log(chalk_1.default.gray(' Use: "resolve conflicts" to fix\n'));
|
|
279
|
-
return false;
|
|
280
|
-
}
|
|
281
|
-
// Handle auth failures
|
|
282
|
-
if (errorMsg.includes('authentication') || errorMsg.includes('permission denied')) {
|
|
283
|
-
console.log(chalk_1.default.yellow('\n⚠️ Authentication failed'));
|
|
284
|
-
console.log(chalk_1.default.gray(' Check your Git credentials\n'));
|
|
285
|
-
return false;
|
|
286
|
-
}
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
function askQuestion(query) {
|
|
290
|
-
return new Promise((resolve) => {
|
|
291
|
-
process.stdout.write(query);
|
|
292
|
-
process.stdin.setRawMode(false);
|
|
293
|
-
process.stdin.resume();
|
|
294
|
-
process.stdin.setEncoding('utf8');
|
|
295
|
-
const onData = (data) => {
|
|
296
|
-
process.stdin.removeListener('data', onData);
|
|
297
|
-
process.stdin.pause();
|
|
298
|
-
resolve(data.toString().trim());
|
|
299
|
-
};
|
|
300
|
-
process.stdin.once('data', onData);
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
async function editMessage(originalMessage) {
|
|
304
|
-
console.log(chalk_1.default.cyan('\n✏️ Edit commit message:\n'));
|
|
305
|
-
console.log(chalk_1.default.gray(' (Press Enter to keep, or type new message)\n'));
|
|
306
|
-
console.log(chalk_1.default.white(` Current: ${chalk_1.default.cyan(originalMessage)}\n`));
|
|
307
|
-
const newMessage = await askQuestion(chalk_1.default.yellow(' New message: '));
|
|
308
|
-
return newMessage.trim() || originalMessage;
|
|
309
|
-
}
|
|
108
|
+
// All complex logic removed - keeping it DEAD SIMPLE!
|