@snapcommit/cli 2.5.0 → 3.0.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 +133 -91
- package/package.json +1 -1
|
@@ -57,25 +57,25 @@ async function executeCursorStyle(userInput) {
|
|
|
57
57
|
await handleAICommand(userInput);
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
|
-
* AI-powered command handler -
|
|
61
|
-
* Pure AI interpretation
|
|
60
|
+
* AI-powered command handler - CURSOR-STYLE!
|
|
61
|
+
* Pure AI interpretation, minimal output, instant feel
|
|
62
62
|
*/
|
|
63
63
|
async function handleAICommand(userInput) {
|
|
64
64
|
const token = (0, auth_1.getToken)();
|
|
65
65
|
if (!token) {
|
|
66
|
-
console.log(chalk_1.default.red('❌ Not authenticated\n'));
|
|
66
|
+
console.log(chalk_1.default.red('\n❌ Not authenticated\n'));
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
69
|
// Get AI interpretation for EVERYTHING
|
|
70
70
|
const intent = await getAIInterpretation(userInput, token);
|
|
71
71
|
if (!intent) {
|
|
72
|
-
console.log(chalk_1.default.red('❌ Could not understand
|
|
73
|
-
console.log(chalk_1.default.gray('
|
|
72
|
+
console.log(chalk_1.default.red('\n❌ Could not understand'));
|
|
73
|
+
console.log(chalk_1.default.gray(' Try: "commit and push" or "show changes"\n'));
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
// Debug
|
|
76
|
+
// Debug mode (if needed)
|
|
77
77
|
if (process.env.DEBUG) {
|
|
78
|
-
console.log(chalk_1.default.gray(`[DEBUG]
|
|
78
|
+
console.log(chalk_1.default.gray(`[DEBUG] ${JSON.stringify(intent, null, 2)}`));
|
|
79
79
|
}
|
|
80
80
|
// Execute based on type
|
|
81
81
|
if (intent.type === 'git') {
|
|
@@ -84,30 +84,26 @@ async function handleAICommand(userInput) {
|
|
|
84
84
|
await showStatus();
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
|
-
//
|
|
87
|
+
// Commit/push flow
|
|
88
88
|
if (intent.action === 'commit' || intent.action === 'push' ||
|
|
89
89
|
(intent.gitCommands && intent.gitCommands.some((cmd) => cmd.includes('commit')))) {
|
|
90
90
|
await executeCommitWithAI(intent);
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
|
-
// Other git commands
|
|
93
|
+
// Other git commands (branch, merge, etc.)
|
|
94
94
|
if (intent.gitCommands && intent.gitCommands.length > 0) {
|
|
95
95
|
await executeGitCommands(intent.gitCommands);
|
|
96
|
-
console.log(chalk_1.default.green('
|
|
96
|
+
console.log(chalk_1.default.green('✓\n'));
|
|
97
97
|
}
|
|
98
98
|
else {
|
|
99
|
-
|
|
100
|
-
console.log(chalk_1.default.yellow('⚠️ No commands to execute'));
|
|
101
|
-
console.log(chalk_1.default.gray(`Intent action: ${intent.action || 'none'}`));
|
|
102
|
-
console.log(chalk_1.default.gray(`Git commands: ${intent.gitCommands?.length || 0}\n`));
|
|
99
|
+
console.log(chalk_1.default.yellow('\n⚠️ No action taken\n'));
|
|
103
100
|
}
|
|
104
101
|
}
|
|
105
102
|
else if (intent.type === 'github') {
|
|
106
103
|
await executeGitHubCommand(intent);
|
|
107
|
-
console.log(chalk_1.default.green('✓ Done\n'));
|
|
108
104
|
}
|
|
109
105
|
else {
|
|
110
|
-
console.log(chalk_1.default.yellow(
|
|
106
|
+
console.log(chalk_1.default.yellow(`\n⚠️ Unknown action\n`));
|
|
111
107
|
}
|
|
112
108
|
}
|
|
113
109
|
/**
|
|
@@ -132,8 +128,8 @@ async function showStatus() {
|
|
|
132
128
|
console.log();
|
|
133
129
|
}
|
|
134
130
|
/**
|
|
135
|
-
* Execute commit
|
|
136
|
-
*
|
|
131
|
+
* Execute commit - EXACTLY like Cursor!
|
|
132
|
+
* Minimal friction, one prompt, instant feel
|
|
137
133
|
*/
|
|
138
134
|
async function executeCommitWithAI(intent) {
|
|
139
135
|
const status = (0, git_1.getGitStatus)();
|
|
@@ -142,77 +138,71 @@ async function executeCommitWithAI(intent) {
|
|
|
142
138
|
console.log(chalk_1.default.gray('\n✓ Branch clean\n'));
|
|
143
139
|
return;
|
|
144
140
|
}
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
141
|
+
// Count files
|
|
142
|
+
let fileCount = status.staged + status.unstaged + status.untracked;
|
|
143
|
+
// Show changed files (like Cursor sidebar)
|
|
144
|
+
console.log(chalk_1.default.blue(`\n📦 Changes (${fileCount} ${fileCount === 1 ? 'file' : 'files'}):`));
|
|
145
|
+
try {
|
|
146
|
+
const output = (0, child_process_1.execSync)('git status --short', { encoding: 'utf-8' });
|
|
147
|
+
const lines = output.split('\n').filter(line => line.trim()).slice(0, 10); // Show max 10
|
|
148
|
+
lines.forEach(line => {
|
|
149
|
+
const status = line.substring(0, 2);
|
|
150
|
+
const file = line.substring(3);
|
|
151
|
+
if (status.includes('M')) {
|
|
152
|
+
console.log(chalk_1.default.yellow(` ✎ ${file}`));
|
|
153
|
+
}
|
|
154
|
+
else if (status.includes('?')) {
|
|
155
|
+
console.log(chalk_1.default.green(` + ${file}`));
|
|
156
|
+
}
|
|
157
|
+
else if (status.includes('D')) {
|
|
158
|
+
console.log(chalk_1.default.red(` - ${file}`));
|
|
159
|
+
}
|
|
162
160
|
});
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return;
|
|
161
|
+
if (fileCount > 10) {
|
|
162
|
+
console.log(chalk_1.default.gray(` ... and ${fileCount - 10} more`));
|
|
163
|
+
}
|
|
167
164
|
}
|
|
165
|
+
catch {
|
|
166
|
+
if (status.unstaged > 0)
|
|
167
|
+
console.log(chalk_1.default.yellow(` • ${status.unstaged} modified`));
|
|
168
|
+
if (status.untracked > 0)
|
|
169
|
+
console.log(chalk_1.default.green(` • ${status.untracked} new`));
|
|
170
|
+
}
|
|
171
|
+
console.log();
|
|
168
172
|
// Stage all
|
|
169
173
|
try {
|
|
170
174
|
(0, git_1.stageAllChanges)();
|
|
171
175
|
}
|
|
172
176
|
catch (error) {
|
|
173
|
-
console.log(chalk_1.default.red(
|
|
177
|
+
console.log(chalk_1.default.red(`❌ ${error.message}\n`));
|
|
174
178
|
return;
|
|
175
179
|
}
|
|
176
|
-
// Generate AI commit message
|
|
177
|
-
console.log(chalk_1.default.blue('🤖 Generating commit message...\n'));
|
|
180
|
+
// Generate AI commit message (like Cursor does instantly)
|
|
178
181
|
const diff = (0, git_1.getGitDiff)(true);
|
|
179
182
|
let commitMessage = await generateCommitMessage(diff);
|
|
180
|
-
// Show message
|
|
181
|
-
console.log(chalk_1.default.cyan('
|
|
182
|
-
console.log(
|
|
183
|
-
//
|
|
184
|
-
const
|
|
183
|
+
// Show message like Cursor - clean and ready to use
|
|
184
|
+
console.log(chalk_1.default.cyan('🤖 ') + chalk_1.default.white.bold(commitMessage.split('\n')[0]));
|
|
185
|
+
console.log();
|
|
186
|
+
// ONE PROMPT - like Cursor's commit button
|
|
187
|
+
const readline = await Promise.resolve().then(() => __importStar(require('readline')));
|
|
188
|
+
const rl = readline.createInterface({
|
|
185
189
|
input: process.stdin,
|
|
186
190
|
output: process.stdout,
|
|
187
191
|
});
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
resolve(ans);
|
|
192
|
+
const response = await new Promise((resolve) => {
|
|
193
|
+
rl.question(chalk_1.default.gray('→ Press Enter to commit, or edit message: '), (ans) => {
|
|
194
|
+
rl.close();
|
|
195
|
+
resolve(ans.trim());
|
|
192
196
|
});
|
|
193
197
|
});
|
|
194
|
-
//
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
if (messageOk.toLowerCase() === 'edit' || messageOk.toLowerCase() === 'e') {
|
|
200
|
-
const rl3 = readline.createInterface({
|
|
201
|
-
input: process.stdin,
|
|
202
|
-
output: process.stdout,
|
|
203
|
-
});
|
|
204
|
-
commitMessage = await new Promise((resolve) => {
|
|
205
|
-
rl3.question(chalk_1.default.cyan('New message: '), (ans) => {
|
|
206
|
-
rl3.close();
|
|
207
|
-
resolve(ans || commitMessage);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
console.log(chalk_1.default.green('\n✓ Message updated\n'));
|
|
198
|
+
// If they typed something, use it. Otherwise use AI message.
|
|
199
|
+
if (response) {
|
|
200
|
+
commitMessage = response;
|
|
211
201
|
}
|
|
212
|
-
// Commit
|
|
202
|
+
// Commit (like Cursor's instant commit)
|
|
213
203
|
try {
|
|
214
204
|
(0, child_process_1.execSync)(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
215
|
-
console.log(chalk_1.default.green(
|
|
205
|
+
console.log(chalk_1.default.green(`\n✓ Committed`));
|
|
216
206
|
}
|
|
217
207
|
catch (error) {
|
|
218
208
|
console.log(chalk_1.default.red(`\n❌ Commit failed: ${error.message}\n`));
|
|
@@ -230,7 +220,7 @@ async function executeCommitWithAI(intent) {
|
|
|
230
220
|
console.log(chalk_1.default.gray('✓ Committed locally (no remote)\n'));
|
|
231
221
|
}
|
|
232
222
|
else {
|
|
233
|
-
console.log(chalk_1.default.yellow(
|
|
223
|
+
console.log(chalk_1.default.yellow(`⚠️ Push failed: ${error.message}\n`));
|
|
234
224
|
}
|
|
235
225
|
}
|
|
236
226
|
}
|
|
@@ -239,69 +229,121 @@ async function executeCommitWithAI(intent) {
|
|
|
239
229
|
}
|
|
240
230
|
}
|
|
241
231
|
/**
|
|
242
|
-
* Execute Git commands
|
|
232
|
+
* Execute Git commands - Cursor-style (clean, fast, auto-fix)
|
|
243
233
|
*/
|
|
244
234
|
async function executeGitCommands(commands) {
|
|
245
235
|
for (const cmd of commands) {
|
|
246
236
|
try {
|
|
247
|
-
(0, child_process_1.execSync)(cmd, { encoding: 'utf-8', stdio: 'pipe' });
|
|
237
|
+
const output = (0, child_process_1.execSync)(cmd, { encoding: 'utf-8', stdio: 'pipe' });
|
|
238
|
+
// Show meaningful output for certain commands
|
|
239
|
+
if (cmd.includes('git branch') && !cmd.includes('-D')) {
|
|
240
|
+
if (output.trim()) {
|
|
241
|
+
console.log(chalk_1.default.cyan('\n' + output.trim() + '\n'));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
else if (cmd.includes('git log')) {
|
|
245
|
+
console.log(chalk_1.default.cyan('\n' + output.trim() + '\n'));
|
|
246
|
+
}
|
|
247
|
+
else if (cmd.includes('git diff') && !cmd.includes('--name-only')) {
|
|
248
|
+
if (output.trim()) {
|
|
249
|
+
console.log(chalk_1.default.gray('\n' + output.trim().substring(0, 500) + (output.length > 500 ? '...' : '') + '\n'));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
248
252
|
}
|
|
249
253
|
catch (error) {
|
|
250
254
|
// Try to auto-fix common errors
|
|
251
255
|
const fixed = await tryAutoFix(error, cmd);
|
|
252
256
|
if (!fixed) {
|
|
253
|
-
console.log(chalk_1.default.red(
|
|
257
|
+
console.log(chalk_1.default.red(`\n❌ ${error.message}\n`));
|
|
254
258
|
return;
|
|
255
259
|
}
|
|
256
260
|
}
|
|
257
261
|
}
|
|
258
262
|
}
|
|
259
263
|
/**
|
|
260
|
-
* Execute GitHub operations
|
|
264
|
+
* Execute GitHub operations - Cursor-style streamlined!
|
|
261
265
|
*/
|
|
262
266
|
async function executeGitHubCommand(intent) {
|
|
263
267
|
if (!(0, github_connect_1.isGitHubConnected)()) {
|
|
264
|
-
console.log(chalk_1.default.yellow('⚠️ GitHub not connected
|
|
268
|
+
console.log(chalk_1.default.yellow('\n⚠️ GitHub not connected'));
|
|
269
|
+
console.log(chalk_1.default.gray(' Run: ') + chalk_1.default.cyan('snap github connect\n'));
|
|
265
270
|
return;
|
|
266
271
|
}
|
|
267
272
|
try {
|
|
268
273
|
switch (intent.action) {
|
|
269
274
|
case 'pr_create':
|
|
270
|
-
console.log(chalk_1.default.blue('Creating PR...'));
|
|
275
|
+
console.log(chalk_1.default.blue('\n🔄 Creating PR...'));
|
|
271
276
|
const pr = await github.createPullRequest(intent.options || {});
|
|
272
|
-
console.log(chalk_1.default.green(`✓ PR
|
|
277
|
+
console.log(chalk_1.default.green(`✓ PR #${pr.number} created`));
|
|
278
|
+
console.log(chalk_1.default.cyan(` ${pr.html_url}\n`));
|
|
273
279
|
break;
|
|
274
280
|
case 'pr_list':
|
|
275
|
-
console.log(chalk_1.default.blue('Listing PRs...'));
|
|
276
281
|
const prs = await github.listPullRequests({ state: 'open', limit: 10 });
|
|
277
282
|
if (prs.length === 0) {
|
|
278
|
-
console.log(chalk_1.default.gray('No open PRs'));
|
|
283
|
+
console.log(chalk_1.default.gray('\n✓ No open PRs\n'));
|
|
279
284
|
}
|
|
280
285
|
else {
|
|
281
|
-
|
|
286
|
+
console.log(chalk_1.default.blue(`\n📋 Open PRs (${prs.length}):`));
|
|
287
|
+
prs.forEach((p) => {
|
|
288
|
+
console.log(chalk_1.default.cyan(` #${p.number} `) + chalk_1.default.white(p.title));
|
|
289
|
+
});
|
|
290
|
+
console.log();
|
|
291
|
+
}
|
|
292
|
+
break;
|
|
293
|
+
case 'pr_merge':
|
|
294
|
+
const prNumber = intent.target || intent.options?.number;
|
|
295
|
+
if (!prNumber) {
|
|
296
|
+
console.log(chalk_1.default.red('\n❌ PR number required\n'));
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
console.log(chalk_1.default.blue(`\n🔄 Merging PR #${prNumber}...`));
|
|
300
|
+
await github.mergePullRequest(prNumber);
|
|
301
|
+
console.log(chalk_1.default.green(`✓ PR #${prNumber} merged\n`));
|
|
302
|
+
break;
|
|
303
|
+
case 'ci_check':
|
|
304
|
+
console.log(chalk_1.default.blue('\n🔍 Checking CI status...'));
|
|
305
|
+
// TODO: Implement CI status check
|
|
306
|
+
console.log(chalk_1.default.gray(' CI checks (coming soon)\n'));
|
|
307
|
+
break;
|
|
308
|
+
case 'issue_create':
|
|
309
|
+
console.log(chalk_1.default.blue('\n🔄 Creating issue...'));
|
|
310
|
+
const issue = await github.createIssue(intent.options || {});
|
|
311
|
+
console.log(chalk_1.default.green(`✓ Issue #${issue.number} created`));
|
|
312
|
+
console.log(chalk_1.default.cyan(` ${issue.html_url}\n`));
|
|
313
|
+
break;
|
|
314
|
+
case 'issue_list':
|
|
315
|
+
const issues = await github.listIssues({ state: 'open', limit: 10 });
|
|
316
|
+
if (issues.length === 0) {
|
|
317
|
+
console.log(chalk_1.default.gray('\n✓ No open issues\n'));
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
console.log(chalk_1.default.blue(`\n🐛 Open Issues (${issues.length}):`));
|
|
321
|
+
issues.forEach((i) => {
|
|
322
|
+
console.log(chalk_1.default.cyan(` #${i.number} `) + chalk_1.default.white(i.title));
|
|
323
|
+
});
|
|
324
|
+
console.log();
|
|
282
325
|
}
|
|
283
326
|
break;
|
|
284
327
|
default:
|
|
285
|
-
console.log(chalk_1.default.yellow(
|
|
328
|
+
console.log(chalk_1.default.yellow(`\n⚠️ Action not supported: ${intent.action}\n`));
|
|
286
329
|
}
|
|
287
330
|
}
|
|
288
331
|
catch (error) {
|
|
289
|
-
console.log(chalk_1.default.red(
|
|
332
|
+
console.log(chalk_1.default.red(`\n❌ ${error.message}\n`));
|
|
290
333
|
}
|
|
291
334
|
}
|
|
292
335
|
/**
|
|
293
|
-
* Auto-fix common Git errors (like Cursor does)
|
|
336
|
+
* Auto-fix common Git errors (like Cursor does - silently when possible)
|
|
294
337
|
*/
|
|
295
338
|
async function tryAutoFix(error, command) {
|
|
296
339
|
const errorMsg = error.message?.toLowerCase() || '';
|
|
297
340
|
// Merge conflict
|
|
298
341
|
if (errorMsg.includes('conflict')) {
|
|
299
|
-
console.log(chalk_1.default.yellow('⚠️
|
|
342
|
+
console.log(chalk_1.default.yellow('\n⚠️ Conflict detected - auto-resolving...'));
|
|
300
343
|
try {
|
|
301
|
-
// Try to accept current changes
|
|
302
344
|
(0, child_process_1.execSync)('git add .', { encoding: 'utf-8', stdio: 'pipe' });
|
|
303
345
|
(0, child_process_1.execSync)('git commit --no-edit', { encoding: 'utf-8', stdio: 'pipe' });
|
|
304
|
-
console.log(chalk_1.default.green('✓
|
|
346
|
+
console.log(chalk_1.default.green('✓ Resolved\n'));
|
|
305
347
|
return true;
|
|
306
348
|
}
|
|
307
349
|
catch {
|
|
@@ -310,11 +352,11 @@ async function tryAutoFix(error, command) {
|
|
|
310
352
|
}
|
|
311
353
|
// Diverged branches
|
|
312
354
|
if (errorMsg.includes('diverged') || errorMsg.includes('non-fast-forward')) {
|
|
313
|
-
console.log(chalk_1.default.yellow('⚠️
|
|
355
|
+
console.log(chalk_1.default.yellow('\n⚠️ Syncing with remote...'));
|
|
314
356
|
try {
|
|
315
357
|
(0, child_process_1.execSync)('git pull --rebase', { encoding: 'utf-8', stdio: 'pipe' });
|
|
316
358
|
(0, child_process_1.execSync)(command, { encoding: 'utf-8', stdio: 'pipe' });
|
|
317
|
-
console.log(chalk_1.default.green('✓
|
|
359
|
+
console.log(chalk_1.default.green('✓ Synced\n'));
|
|
318
360
|
return true;
|
|
319
361
|
}
|
|
320
362
|
catch {
|
|
@@ -323,12 +365,12 @@ async function tryAutoFix(error, command) {
|
|
|
323
365
|
}
|
|
324
366
|
// Unstaged changes
|
|
325
367
|
if (errorMsg.includes('unstaged') || errorMsg.includes('uncommitted')) {
|
|
326
|
-
console.log(chalk_1.default.yellow('⚠️
|
|
368
|
+
console.log(chalk_1.default.yellow('\n⚠️ Stashing changes...'));
|
|
327
369
|
try {
|
|
328
370
|
(0, child_process_1.execSync)('git stash', { encoding: 'utf-8', stdio: 'pipe' });
|
|
329
371
|
(0, child_process_1.execSync)(command, { encoding: 'utf-8', stdio: 'pipe' });
|
|
330
372
|
(0, child_process_1.execSync)('git stash pop', { encoding: 'utf-8', stdio: 'pipe' });
|
|
331
|
-
console.log(chalk_1.default.green('✓
|
|
373
|
+
console.log(chalk_1.default.green('✓ Restored\n'));
|
|
332
374
|
return true;
|
|
333
375
|
}
|
|
334
376
|
catch {
|