@snapcommit/cli 2.5.0 → 2.6.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.
@@ -133,7 +133,7 @@ async function showStatus() {
133
133
  }
134
134
  /**
135
135
  * Execute commit with AI-generated message
136
- * Interactive flow: select files preview message edit → confirm → commit
136
+ * Natural language interactive flow - like talking to Cursor!
137
137
  */
138
138
  async function executeCommitWithAI(intent) {
139
139
  const status = (0, git_1.getGitStatus)();
@@ -142,30 +142,53 @@ async function executeCommitWithAI(intent) {
142
142
  console.log(chalk_1.default.gray('\n✓ Branch clean\n'));
143
143
  return;
144
144
  }
145
- // Show what changed
146
- console.log(chalk_1.default.blue('\n📦 Changes detected:'));
147
- if (status.unstaged > 0)
148
- console.log(chalk_1.default.yellow(` • ${status.unstaged} modified`));
149
- if (status.untracked > 0)
150
- console.log(chalk_1.default.yellow(` • ${status.untracked} new`));
145
+ // Show ALL changed files with details
146
+ console.log(chalk_1.default.blue('\n📦 Files changed:\n'));
147
+ try {
148
+ const output = (0, child_process_1.execSync)('git status --short', { encoding: 'utf-8' });
149
+ output.split('\n').filter(line => line.trim()).forEach(line => {
150
+ const status = line.substring(0, 2);
151
+ const file = line.substring(3);
152
+ if (status.includes('M')) {
153
+ console.log(chalk_1.default.yellow(` ✎ ${file}`));
154
+ }
155
+ else if (status.includes('?')) {
156
+ console.log(chalk_1.default.green(` + ${file}`));
157
+ }
158
+ else if (status.includes('D')) {
159
+ console.log(chalk_1.default.red(` - ${file}`));
160
+ }
161
+ });
162
+ }
163
+ catch {
164
+ if (status.unstaged > 0)
165
+ console.log(chalk_1.default.yellow(` • ${status.unstaged} modified`));
166
+ if (status.untracked > 0)
167
+ console.log(chalk_1.default.green(` • ${status.untracked} new`));
168
+ }
151
169
  console.log();
152
- // Ask if they want to commit all files
170
+ // Natural language file selection
153
171
  const readline = await Promise.resolve().then(() => __importStar(require('readline')));
154
172
  const rl = readline.createInterface({
155
173
  input: process.stdin,
156
174
  output: process.stdout,
157
175
  });
158
- const commitAll = await new Promise((resolve) => {
159
- rl.question(chalk_1.default.cyan('Commit all files? (Y/n): '), (ans) => {
176
+ const fileChoice = await new Promise((resolve) => {
177
+ rl.question(chalk_1.default.cyan('What do you want to do? ') + chalk_1.default.gray('(commit all / select files / cancel): '), (ans) => {
160
178
  rl.close();
161
- resolve(ans);
179
+ resolve(ans.toLowerCase().trim());
162
180
  });
163
181
  });
164
- if (commitAll.toLowerCase() === 'n') {
165
- console.log(chalk_1.default.yellow('\n💡 Tip: Use "git add <files>" to stage specific files, then try again\n'));
182
+ if (fileChoice.includes('cancel') || fileChoice === 'n' || fileChoice === 'no') {
183
+ console.log(chalk_1.default.gray('\n Cancelled\n'));
184
+ return;
185
+ }
186
+ if (fileChoice.includes('select')) {
187
+ console.log(chalk_1.default.yellow('\n💡 Use: ') + chalk_1.default.cyan('git add <files>') + chalk_1.default.yellow(' to stage specific files'));
188
+ console.log(chalk_1.default.gray(' Then run: ') + chalk_1.default.cyan('snap') + chalk_1.default.gray(' and try again\n'));
166
189
  return;
167
190
  }
168
- // Stage all
191
+ // Stage all (default for "commit all" or just pressing Enter)
169
192
  try {
170
193
  (0, git_1.stageAllChanges)();
171
194
  }
@@ -177,42 +200,46 @@ async function executeCommitWithAI(intent) {
177
200
  console.log(chalk_1.default.blue('🤖 Generating commit message...\n'));
178
201
  const diff = (0, git_1.getGitDiff)(true);
179
202
  let commitMessage = await generateCommitMessage(diff);
180
- // Show message
181
- console.log(chalk_1.default.cyan('📝 Commit message:'));
182
- console.log(chalk_1.default.white.bold(` ${commitMessage.split('\n')[0]}\n`));
183
- // Ask if message is good
203
+ // Show message with natural language prompt
204
+ console.log(chalk_1.default.cyan('📝 AI generated this commit message:'));
205
+ console.log(chalk_1.default.white.bold(` "${commitMessage.split('\n')[0]}"\n`));
184
206
  const rl2 = readline.createInterface({
185
207
  input: process.stdin,
186
208
  output: process.stdout,
187
209
  });
188
- const messageOk = await new Promise((resolve) => {
189
- rl2.question(chalk_1.default.cyan('Is this message okay? ') + chalk_1.default.gray('(Y/n/edit): '), (ans) => {
210
+ const messageAction = await new Promise((resolve) => {
211
+ rl2.question(chalk_1.default.cyan('What next? ') + chalk_1.default.gray('(looks good / edit / type new message / cancel): '), (ans) => {
190
212
  rl2.close();
191
- resolve(ans);
213
+ resolve(ans.toLowerCase().trim());
192
214
  });
193
215
  });
194
- // Handle response
195
- if (messageOk.toLowerCase() === 'n') {
216
+ // Handle response naturally
217
+ if (messageAction.includes('cancel') || messageAction === 'no' || messageAction === 'n') {
196
218
  console.log(chalk_1.default.gray('\n✗ Cancelled\n'));
197
219
  return;
198
220
  }
199
- if (messageOk.toLowerCase() === 'edit' || messageOk.toLowerCase() === 'e') {
221
+ if (messageAction.includes('edit') || messageAction.includes('change')) {
200
222
  const rl3 = readline.createInterface({
201
223
  input: process.stdin,
202
224
  output: process.stdout,
203
225
  });
204
226
  commitMessage = await new Promise((resolve) => {
205
- rl3.question(chalk_1.default.cyan('New message: '), (ans) => {
227
+ rl3.question(chalk_1.default.cyan('Your message: '), (ans) => {
206
228
  rl3.close();
207
- resolve(ans || commitMessage);
229
+ resolve(ans.trim() || commitMessage);
208
230
  });
209
231
  });
210
232
  console.log(chalk_1.default.green('\n✓ Message updated\n'));
211
233
  }
234
+ else if (messageAction && !messageAction.includes('good') && !messageAction.includes('yes') && !messageAction.includes('ok')) {
235
+ // They typed a custom message directly
236
+ commitMessage = messageAction;
237
+ console.log(chalk_1.default.green('\n✓ Using your message\n'));
238
+ }
212
239
  // Commit
213
240
  try {
214
241
  (0, child_process_1.execSync)(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, { encoding: 'utf-8', stdio: 'pipe' });
215
- console.log(chalk_1.default.green(`✓ Committed: ${commitMessage.split('\n')[0]}`));
242
+ console.log(chalk_1.default.green(`✓ ${commitMessage.split('\n')[0]}`));
216
243
  }
217
244
  catch (error) {
218
245
  console.log(chalk_1.default.red(`\n❌ Commit failed: ${error.message}\n`));
@@ -230,7 +257,7 @@ async function executeCommitWithAI(intent) {
230
257
  console.log(chalk_1.default.gray('✓ Committed locally (no remote)\n'));
231
258
  }
232
259
  else {
233
- console.log(chalk_1.default.yellow(`\n⚠️ Push failed: ${error.message}\n`));
260
+ console.log(chalk_1.default.yellow(`⚠️ Push failed: ${error.message}\n`));
234
261
  }
235
262
  }
236
263
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snapcommit/cli",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "Instant AI commits. Beautiful progress tracking. Never write commit messages again.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {