natureco-cli 2.20.0 → 2.20.2
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/package.json +1 -1
- package/src/commands/code.js +117 -1
package/package.json
CHANGED
package/src/commands/code.js
CHANGED
|
@@ -141,7 +141,28 @@ function buildIndexPrompt(index) {
|
|
|
141
141
|
return lines.join('\n');
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
// ──
|
|
144
|
+
// ── Git helpers ───────────────────────────────────────────────────────────────
|
|
145
|
+
async function generateCommitMessage(diff, providerConfig) {
|
|
146
|
+
const body = {
|
|
147
|
+
model: providerConfig.model,
|
|
148
|
+
messages: [
|
|
149
|
+
{ role: 'system', content: 'Sen bir git commit mesajı üreticisin. Conventional Commits formatında (feat/fix/refactor/chore vb.) kısa ve açıklayıcı bir commit mesajı yaz. Sadece mesajı yaz, başka hiçbir şey yazma.' },
|
|
150
|
+
{ role: 'user', content: `Bu diff için commit mesajı üret:\n\n${diff}` },
|
|
151
|
+
],
|
|
152
|
+
temperature: 0.3,
|
|
153
|
+
max_tokens: 100,
|
|
154
|
+
stream: false,
|
|
155
|
+
};
|
|
156
|
+
const res = await fetch(`${providerConfig.url}/chat/completions`, {
|
|
157
|
+
method: 'POST',
|
|
158
|
+
headers: { 'Authorization': `Bearer ${providerConfig.apiKey}`, 'Content-Type': 'application/json' },
|
|
159
|
+
body: JSON.stringify(body),
|
|
160
|
+
});
|
|
161
|
+
const data = await res.json();
|
|
162
|
+
return (data.choices?.[0]?.message?.content || 'chore: update files').trim().replace(/^["']|["']$/g, '');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
145
166
|
async function streamMessage(providerConfig, messages, tools) {
|
|
146
167
|
const endpoint = `${providerConfig.url}/chat/completions`;
|
|
147
168
|
const body = {
|
|
@@ -245,6 +266,10 @@ async function runToolCall(toolCall, stats) {
|
|
|
245
266
|
stats.filesChanged++;
|
|
246
267
|
stats.changedFiles.push(toolCall.input.path || '?');
|
|
247
268
|
console.log(chalk.green(` ✓ ${toolCall.input.path} güncellendi`));
|
|
269
|
+
if (stats.changedFiles.length === 1) {
|
|
270
|
+
// İlk değişiklikte ipucu göster
|
|
271
|
+
console.log(chalk.gray(` 💡 git add . && /commit ile kaydet`));
|
|
272
|
+
}
|
|
248
273
|
}
|
|
249
274
|
if (toolCall.name === 'bash') stats.commandsRun++;
|
|
250
275
|
stats.toolCallCount++;
|
|
@@ -426,6 +451,36 @@ ${indexPrompt}`;
|
|
|
426
451
|
console.log();
|
|
427
452
|
}
|
|
428
453
|
|
|
454
|
+
// ── Komut çalıştır + hata döngüsü ───────────────────────────────────────────
|
|
455
|
+
async function runAndFix(cmd) {
|
|
456
|
+
console.log(chalk.gray(`\n ▶ ${cmd} çalıştırılıyor...\n`));
|
|
457
|
+
try {
|
|
458
|
+
const output = execSync(cmd, {
|
|
459
|
+
cwd: process.cwd(), timeout: 30000, stdio: 'pipe',
|
|
460
|
+
}).toString();
|
|
461
|
+
console.log(chalk.green(' ✓ Başarılı:'));
|
|
462
|
+
console.log(chalk.gray(' ' + output.slice(0, 500).split('\n').join('\n ')));
|
|
463
|
+
console.log();
|
|
464
|
+
} catch (err) {
|
|
465
|
+
const errorOutput = (err.stderr?.toString() || err.stdout?.toString() || err.message || '').slice(0, 500);
|
|
466
|
+
console.log(chalk.red(' ✗ Hata:'));
|
|
467
|
+
console.log(chalk.gray(' ' + errorOutput.split('\n').join('\n ')));
|
|
468
|
+
console.log();
|
|
469
|
+
|
|
470
|
+
const { fix } = await inquirer.prompt([{
|
|
471
|
+
type: 'confirm', name: 'fix',
|
|
472
|
+
message: chalk.yellow(' Hatayı otomatik düzeltmemi ister misin?'),
|
|
473
|
+
default: true,
|
|
474
|
+
}]);
|
|
475
|
+
|
|
476
|
+
if (fix) {
|
|
477
|
+
const fixMessage = `Şu komut çalıştırıldı: ${cmd}\nHata oluştu:\n${errorOutput}\nBu hatayı analiz et ve düzelt.`;
|
|
478
|
+
console.log(chalk.cyan('\n Düzeltiliyor...\n'));
|
|
479
|
+
await handleMessage(fixMessage);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
429
484
|
// ── Mesaj gönder + tool loop ──────────────────────────────────────────────
|
|
430
485
|
async function handleMessage(userMessage) {
|
|
431
486
|
userMessage = userMessage.trim();
|
|
@@ -441,6 +496,10 @@ ${indexPrompt}`;
|
|
|
441
496
|
['/summary', 'Session özetini göster'],
|
|
442
497
|
['/done', 'Bitir ve özet göster'],
|
|
443
498
|
['/index', 'Projeyi yeniden indexle'],
|
|
499
|
+
['/run <cmd>','Komutu çalıştır, hata varsa düzelt'],
|
|
500
|
+
['/test', 'Testleri çalıştır, hata varsa düzelt'],
|
|
501
|
+
['/git', 'Git durumu ve son commitler'],
|
|
502
|
+
['/commit', 'Staged değişiklikleri AI ile commit et'],
|
|
444
503
|
['/help', 'Bu yardım'],
|
|
445
504
|
].forEach(([c, d]) => console.log(' ' + chalk.cyan(c.padEnd(12)) + chalk.gray(d)));
|
|
446
505
|
console.log(chalk.gray(' Ctrl+C'.padEnd(14) + 'Çıkış'));
|
|
@@ -465,6 +524,63 @@ ${indexPrompt}`;
|
|
|
465
524
|
);
|
|
466
525
|
return;
|
|
467
526
|
}
|
|
527
|
+
case 'run': {
|
|
528
|
+
const runCmd = userMessage.slice(4).trim() || 'node index.js';
|
|
529
|
+
await runAndFix(runCmd);
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
case 'test': {
|
|
533
|
+
const testCmd = projectIndex.packageJson?.scripts?.test
|
|
534
|
+
? 'npm test'
|
|
535
|
+
: projectIndex.type === 'python' ? 'python -m pytest' : null;
|
|
536
|
+
if (!testCmd) {
|
|
537
|
+
console.log(chalk.red(' Test komutu bulunamadı.\n'));
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
await runAndFix(testCmd);
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
case 'git': {
|
|
544
|
+
try {
|
|
545
|
+
const status = execSync('git status --short', { cwd: process.cwd(), stdio: 'pipe' }).toString().trim();
|
|
546
|
+
const log = execSync('git log --oneline -5', { cwd: process.cwd(), stdio: 'pipe' }).toString().trim();
|
|
547
|
+
console.log(chalk.yellow('\n Git Durumu:'));
|
|
548
|
+
console.log(status ? chalk.gray(' ' + status.split('\n').join('\n ')) : chalk.gray(' temiz'));
|
|
549
|
+
console.log(chalk.yellow('\n Son Commitler:'));
|
|
550
|
+
console.log(chalk.gray(' ' + log.split('\n').join('\n ')));
|
|
551
|
+
console.log();
|
|
552
|
+
} catch (e) {
|
|
553
|
+
console.log(chalk.red(' Git bulunamadı veya bu dizin bir git repo değil.\n'));
|
|
554
|
+
}
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
case 'commit': {
|
|
558
|
+
try {
|
|
559
|
+
const diff = execSync('git diff --staged', { cwd: process.cwd(), stdio: 'pipe' }).toString();
|
|
560
|
+
if (!diff.trim()) {
|
|
561
|
+
console.log(chalk.red('\n Staged değişiklik yok.'));
|
|
562
|
+
console.log(chalk.gray(' Önce: git add .\n'));
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
const sp = startSpinner('Commit mesajı üretiliyor...');
|
|
566
|
+
const commitMsg = await generateCommitMessage(diff.slice(0, 2000), providerConfig);
|
|
567
|
+
stopSpinner(sp, 'Commit mesajı hazır', true);
|
|
568
|
+
console.log(chalk.cyan(`\n Önerilen: ${chalk.white(commitMsg)}\n`));
|
|
569
|
+
const { ok } = await inquirer.prompt([{
|
|
570
|
+
type: 'confirm', name: 'ok',
|
|
571
|
+
message: ' Commit edilsin mi?', default: true,
|
|
572
|
+
}]);
|
|
573
|
+
if (ok) {
|
|
574
|
+
execSync(`git commit -m "${commitMsg.replace(/"/g, '\\"')}"`, { cwd: process.cwd(), stdio: 'pipe' });
|
|
575
|
+
console.log(chalk.green(' ✓ Commit yapıldı!\n'));
|
|
576
|
+
} else {
|
|
577
|
+
console.log(chalk.gray(' İptal edildi.\n'));
|
|
578
|
+
}
|
|
579
|
+
} catch (e) {
|
|
580
|
+
console.log(chalk.red(` Git hatası: ${e.message}\n`));
|
|
581
|
+
}
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
468
584
|
default:
|
|
469
585
|
console.log(chalk.red(`Bilinmeyen komut: /${cmd}\n`));
|
|
470
586
|
return;
|