natureco-cli 5.55.0 → 5.57.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.
@@ -1,4 +1,6 @@
1
1
  const chalk = require('chalk');
2
+ const { getLang: _gl } = require('../utils/i18n');
3
+ const L = (tr, en) => (_gl() === 'en' ? en : tr);
2
4
  const inquirer = require('../utils/inquirer-wrapper');
3
5
  const { getConfig, saveConfig } = require('../utils/config');
4
6
  const fs = require('fs');
@@ -28,11 +30,11 @@ async function signal(action, subAction) {
28
30
  async function connectSignal() {
29
31
  const config = getConfig();
30
32
  if (!config.providerUrl) {
31
- console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
33
+ console.log(chalk.red(L('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n', '\n❌ Setup not done. Run "natureco setup" first.\n')));
32
34
  process.exit(1);
33
35
  }
34
- console.log(chalk.yellow('\n⏳ Signal bağlantısı hazırlanıyor...\n'));
35
- console.log(chalk.gray('Signal, signal-cli REST API üzerinden bağlanır.\n'));
36
+ console.log(chalk.yellow(L('\n⏳ Signal bağlantısı hazırlanıyor...\n', '\n⏳ Preparing Signal connection...\n')));
37
+ console.log(chalk.gray(L('Signal, signal-cli REST API üzerinden bağlanır.\n', 'Signal connects via the signal-cli REST API.\n')));
36
38
 
37
39
  const existing = config.signalHttpUrl || '';
38
40
  const existingAccount = config.signalAccount || '';
@@ -40,29 +42,29 @@ async function connectSignal() {
40
42
  const existingMode = config.signalApiMode || 'auto';
41
43
 
42
44
  const answers = await inquirer.prompt([
43
- { type: 'input', name: 'httpUrl', message: 'signal-cli REST API URL:', default: existing || 'http://localhost:8080', validate: v => v.trim() ? true : 'URL boş olamaz' },
44
- { type: 'input', name: 'account', message: 'Signal hesap numarası (+905551234567):', default: existingAccount, validate: v => v.trim() ? true : 'Numara boş olamaz' },
45
+ { type: 'input', name: 'httpUrl', message: 'signal-cli REST API URL:', default: existing || 'http://localhost:8080', validate: v => v.trim() ? true : L('URL boş olamaz', 'URL cannot be empty') },
46
+ { type: 'input', name: 'account', message: L('Signal hesap numarası (+905551234567):', 'Signal account number (+905551234567):'), default: existingAccount, validate: v => v.trim() ? true : L('Numara boş olamaz', 'Number cannot be empty') },
45
47
  {
46
- type: 'list', name: 'apiMode', message: 'API modu:', default: existingMode,
48
+ type: 'list', name: 'apiMode', message: L('API modu:', 'API mode:'), default: existingMode,
47
49
  choices: [
48
- { name: 'Auto-detect (önerilen)', value: 'auto' },
50
+ { name: L('Auto-detect (önerilen)', 'Auto-detect (recommended)'), value: 'auto' },
49
51
  { name: 'Native (signal-cli JSON-RPC)', value: 'native' },
50
52
  { name: 'Container (bbernhard/signal-cli-rest-api)', value: 'container' },
51
53
  ]
52
54
  },
53
- { type: 'confirm', name: 'autoStart', message: 'Gateway ile signal-cli daemon\'ı otomatik başlatılsın mı?', default: config.signalAutoStart !== undefined ? config.signalAutoStart : true },
55
+ { type: 'confirm', name: 'autoStart', message: L('Gateway ile signal-cli daemon\'ı otomatik başlatılsın mı?', 'Auto-start the signal-cli daemon with the gateway?'), default: config.signalAutoStart !== undefined ? config.signalAutoStart : true },
54
56
  {
55
- type: 'list', name: 'receiveMode', message: 'Mesaj alma modu:', default: config.signalReceiveMode || 'on-start',
57
+ type: 'list', name: 'receiveMode', message: L('Mesaj alma modu:', 'Message receive mode:'), default: config.signalReceiveMode || 'on-start',
56
58
  choices: [
57
- { name: 'Gateway başlangıcında dinlemeye başla (önerilen)', value: 'on-start' },
58
- { name: 'Manuel (sadece status kontrol)', value: 'manual' },
59
+ { name: L('Gateway başlangıcında dinlemeye başla (önerilen)', 'Start listening when the gateway starts (recommended)'), value: 'on-start' },
60
+ { name: L('Manuel (sadece status kontrol)', 'Manual (status check only)'), value: 'manual' },
59
61
  ]
60
62
  },
61
- { type: 'list', name: 'dmPolicy', message: 'DM politikası:', default: existingDm, choices: [
62
- { name: 'Pairing (önerilen) — eşleşme onayı ile', value: 'pairing' },
63
- { name: 'Allowlist — sadece izin listesi', value: 'allowlist' },
64
- { name: 'Open — herkese açık', value: 'open' },
65
- { name: 'Disabled — devre dışı', value: 'disabled' },
63
+ { type: 'list', name: 'dmPolicy', message: L('DM politikası:', 'DM policy:'), default: existingDm, choices: [
64
+ { name: L('Pairing (önerilen) — eşleşme onayı ile', 'Pairing (recommended) — with match approval'), value: 'pairing' },
65
+ { name: L('Allowlist — sadece izin listesi', 'Allowlist — only the allowlist'), value: 'allowlist' },
66
+ { name: L('Open — herkese açık', 'Open — public'), value: 'open' },
67
+ { name: L('Disabled — devre dışı', 'Disabled — off'), value: 'disabled' },
66
68
  ]},
67
69
  ]);
68
70
 
@@ -76,23 +78,23 @@ async function connectSignal() {
76
78
  config.signalBotId = botId;
77
79
  saveConfig(config);
78
80
 
79
- console.log(chalk.green('\n✅ Signal bağlantısı kaydedildi!\n'));
81
+ console.log(chalk.green(L('\n✅ Signal bağlantısı kaydedildi!\n', '\n✅ Signal connection saved!\n')));
80
82
  console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
81
83
  console.log(chalk.cyan('REST API URL:'), chalk.white(config.signalHttpUrl));
82
- console.log(chalk.cyan('Hesap:'), chalk.white(config.signalAccount));
83
- console.log(chalk.cyan('API Modu:'), chalk.white(answers.apiMode));
84
- console.log(chalk.cyan('DM Politikası:'), chalk.white(answers.dmPolicy));
84
+ console.log(chalk.cyan(L('Hesap:', 'Account:')), chalk.white(config.signalAccount));
85
+ console.log(chalk.cyan(L('API Modu:', 'API Mode:')), chalk.white(answers.apiMode));
86
+ console.log(chalk.cyan(L('DM Politikası:', 'DM Policy:')), chalk.white(answers.dmPolicy));
85
87
 
86
88
  if (answers.autoStart) {
87
89
  const signalCliPath = findSignalCli();
88
90
  if (signalCliPath) {
89
- console.log(chalk.gray(`\nsignal-cli bulundu: ${signalCliPath}`));
91
+ console.log(chalk.gray(`\n${L('signal-cli bulundu', 'signal-cli found')}: ${signalCliPath}`));
90
92
  } else {
91
- console.log(chalk.yellow('\n⚠️ signal-cli bulunamadı. İndirmek için:'));
93
+ console.log(chalk.yellow(L('\n⚠️ signal-cli bulunamadı. İndirmek için:', '\n⚠️ signal-cli not found. To download:')));
92
94
  console.log(chalk.cyan(' natureco signal install'));
93
95
  }
94
96
  }
95
- console.log(chalk.gray('\nGateway ile başlatmak için: natureco gateway start\n'));
97
+ console.log(chalk.gray(L('\nGateway ile başlatmak için: natureco gateway start\n', '\nTo start with the gateway: natureco gateway start\n')));
96
98
  }
97
99
 
98
100
  async function disconnectSignal() {
@@ -102,7 +104,7 @@ async function disconnectSignal() {
102
104
  return;
103
105
  }
104
106
  const { confirm } = await inquirer.prompt([
105
- { type: 'confirm', name: 'confirm', message: 'Signal bağlantısını kaldırmak istediğinize emin misiniz?', default: false }
107
+ { type: 'confirm', name: 'confirm', message: L('Signal bağlantısını kaldırmak istediğinize emin misiniz?', 'Are you sure you want to remove the Signal connection?'), default: false }
106
108
  ]);
107
109
  if (!confirm) {
108
110
  console.log(chalk.gray('\nCancelled\n'));
@@ -136,13 +138,13 @@ function statusSignal() {
136
138
  console.log(chalk.green('\n✅ Signal connected\n'));
137
139
  console.log(chalk.cyan('Bot ID:'), chalk.white(config.signalBotId));
138
140
  console.log(chalk.cyan('REST API URL:'), chalk.white(config.signalHttpUrl));
139
- console.log(chalk.cyan('Hesap:'), chalk.white(config.signalAccount));
140
- console.log(chalk.cyan('API Modu:'), chalk.white(config.signalApiMode || 'auto'));
141
- console.log(chalk.cyan('DM Politikası:'), chalk.white(config.signalDmPolicy || 'pairing'));
141
+ console.log(chalk.cyan(L('Hesap:', 'Account:')), chalk.white(config.signalAccount));
142
+ console.log(chalk.cyan(L('API Modu:', 'API Mode:')), chalk.white(config.signalApiMode || 'auto'));
143
+ console.log(chalk.cyan(L('DM Politikası:', 'DM Policy:')), chalk.white(config.signalDmPolicy || 'pairing'));
142
144
 
143
145
  console.log('');
144
- console.log(chalk.cyan('Daemon Durumu:'), daemonRunning ? chalk.green('✓ Çalışıyor') : chalk.gray('✗ Durduruldu'));
145
- console.log(chalk.cyan('API Erişilebilirlik:'), apiReachable ? chalk.green('✓ Ulaşılabilir') : chalk.red('✗ Ulaşılamıyor'));
146
+ console.log(chalk.cyan(L('Daemon Durumu:', 'Daemon Status:')), daemonRunning ? chalk.green(L('✓ Çalışıyor', '✓ Running')) : chalk.gray(L('✗ Durduruldu', '✗ Stopped')));
147
+ console.log(chalk.cyan(L('API Erişilebilirlik:', 'API Reachability:')), apiReachable ? chalk.green(L('✓ Ulaşılabilir', '✓ Reachable')) : chalk.red(L('✗ Ulaşılamıyor', '✗ Unreachable')));
146
148
 
147
149
  if (config.signalCliPath) {
148
150
  console.log(chalk.gray(`\nsignal-cli: ${config.signalCliPath}`));
@@ -155,7 +157,7 @@ function statusSignal() {
155
157
  }
156
158
 
157
159
  async function installSignalCli() {
158
- console.log(chalk.yellow('\n⏳ signal-cli indiriliyor...\n'));
160
+ console.log(chalk.yellow(L('\n⏳ signal-cli indiriliyor...\n', '\n⏳ Downloading signal-cli...\n')));
159
161
 
160
162
  if (!fs.existsSync(SIGNAL_DIR)) {
161
163
  fs.mkdirSync(SIGNAL_DIR, { recursive: true });
@@ -175,8 +177,8 @@ async function installSignalCli() {
175
177
  archiveName = `signal-cli-${SIGNAL_CLI_VERSION}-macOS.tar.gz`;
176
178
  downloadUrl = `https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/${archiveName}`;
177
179
  } else {
178
- console.log(chalk.red(`\n❌ Platform desteklenmiyor: ${platform}\n`));
179
- console.log(chalk.gray('Manual kurulum: https://github.com/AsamK/signal-cli#installation\n'));
180
+ console.log(chalk.red(`\n❌ ${L('Platform desteklenmiyor', 'Platform not supported')}: ${platform}\n`));
181
+ console.log(chalk.gray(L('Manual kurulum: https://github.com/AsamK/signal-cli#installation\n', 'Manual installation: https://github.com/AsamK/signal-cli#installation\n')));
180
182
  process.exit(1);
181
183
  }
182
184
 
@@ -184,30 +186,30 @@ async function installSignalCli() {
184
186
  const extractDir = path.join(SIGNAL_DIR, `signal-cli-${SIGNAL_CLI_VERSION}`);
185
187
 
186
188
  if (fs.existsSync(extractDir)) {
187
- console.log(chalk.gray(`signal-cli ${SIGNAL_CLI_VERSION} zaten indirilmiş: ${extractDir}`));
189
+ console.log(chalk.gray(`signal-cli ${SIGNAL_CLI_VERSION} ${L('zaten indirilmiş', 'already downloaded')}: ${extractDir}`));
188
190
  const config = getConfig();
189
191
  config.signalCliPath = path.join(extractDir, 'bin', 'signal-cli' + (platform === 'win32' ? '.bat' : ''));
190
192
  saveConfig(config);
191
- console.log(chalk.green('✅ Hazır\n'));
193
+ console.log(chalk.green(L('✅ Hazır\n', '✅ Ready\n')));
192
194
  return;
193
195
  }
194
196
 
195
197
  try {
196
- console.log(chalk.cyan(`İndiriliyor: ${downloadUrl}`));
198
+ console.log(chalk.cyan(`${L('İndiriliyor', 'Downloading')}: ${downloadUrl}`));
197
199
  const response = await fetch(downloadUrl);
198
200
  if (!response.ok) {
199
201
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
200
202
  }
201
203
  const buffer = Buffer.from(await response.arrayBuffer());
202
204
  fs.writeFileSync(archivePath, buffer);
203
- console.log(chalk.green(`✓ İndirildi (${(buffer.length / 1024 / 1024).toFixed(1)} MB)`));
205
+ console.log(chalk.green(`✓ ${L('İndirildi', 'Downloaded')} (${(buffer.length / 1024 / 1024).toFixed(1)} MB)`));
204
206
 
205
207
  // Extract
206
- console.log(chalk.cyan('Ayıklanıyor...'));
208
+ console.log(chalk.cyan(L('Ayıklanıyor...', 'Extracting...')));
207
209
  const tar = require('tar');
208
210
  fs.mkdirSync(extractDir, { recursive: true });
209
211
  await tar.x({ file: archivePath, cwd: SIGNAL_DIR });
210
- console.log(chalk.green('✓ Ayıklandı'));
212
+ console.log(chalk.green(L('✓ Ayıklandı', '✓ Extracted')));
211
213
 
212
214
  // Clean up archive
213
215
  fs.unlinkSync(archivePath);
@@ -225,13 +227,13 @@ async function installSignalCli() {
225
227
  config.signalCliPath = path.join(extractDir, 'bin', 'signal-cli' + (platform === 'win32' ? '.bat' : ''));
226
228
  saveConfig(config);
227
229
 
228
- console.log(chalk.green(`\n✅ signal-cli ${SIGNAL_CLI_VERSION} kuruldu!\n`));
230
+ console.log(chalk.green(`\n✅ signal-cli ${SIGNAL_CLI_VERSION} ${L('kuruldu', 'installed')}!\n`));
229
231
  console.log(chalk.cyan('Binary:'), chalk.white(config.signalCliPath));
230
- console.log(chalk.gray('\nDaemon\'ı başlatmak için: natureco signal daemon start\n'));
232
+ console.log(chalk.gray(L('\nDaemon\'ı başlatmak için: natureco signal daemon start\n', '\nTo start the daemon: natureco signal daemon start\n')));
231
233
 
232
234
  } catch (err) {
233
- console.log(chalk.red(`\n❌ Kurulum hatası: ${err.message}\n`));
234
- console.log(chalk.gray('Manuel kurulum: https://github.com/AsamK/signal-cli#installation\n'));
235
+ console.log(chalk.red(`\n❌ ${L('Kurulum hatası', 'Installation error')}: ${err.message}\n`));
236
+ console.log(chalk.gray(L('Manuel kurulum: https://github.com/AsamK/signal-cli#installation\n', 'Manual installation: https://github.com/AsamK/signal-cli#installation\n')));
235
237
  process.exit(1);
236
238
  }
237
239
  }
@@ -239,7 +241,7 @@ async function installSignalCli() {
239
241
  async function manageDaemon(subAction) {
240
242
  const config = getConfig();
241
243
  if (!config.signalBotId) {
242
- console.log(chalk.red('\n❌ Signal bağlı değil\n'));
244
+ console.log(chalk.red(L('\n❌ Signal bağlı değil\n', '\n❌ Signal not connected\n')));
243
245
  process.exit(1);
244
246
  }
245
247
 
@@ -265,13 +267,13 @@ async function startDaemon(config) {
265
267
 
266
268
  const cliPath = config.signalCliPath || findSignalCli();
267
269
  if (!cliPath) {
268
- console.log(chalk.red('\n❌ signal-cli bulunamadı\n'));
269
- console.log(chalk.yellow('Önce indirin:'), chalk.cyan('natureco signal install\n'));
270
+ console.log(chalk.red(L('\n❌ signal-cli bulunamadı\n', '\n❌ signal-cli not found\n')));
271
+ console.log(chalk.yellow(L('Önce indirin:', 'Download first:')), chalk.cyan('natureco signal install\n'));
270
272
  process.exit(1);
271
273
  }
272
274
 
273
275
  if (!fs.existsSync(cliPath)) {
274
- console.log(chalk.red(`\n❌ signal-cli binary bulunamadı: ${cliPath}\n`));
276
+ console.log(chalk.red(`\n❌ signal-cli binary ${L('bulunamadı', 'not found')}: ${cliPath}\n`));
275
277
  process.exit(1);
276
278
  }
277
279
 
@@ -285,9 +287,9 @@ async function startDaemon(config) {
285
287
  const port = urlObj.port || '8080';
286
288
  const account = config.signalAccount;
287
289
 
288
- console.log(chalk.yellow(`\n⏳ signal-cli daemon başlatılıyor...\n`));
290
+ console.log(chalk.yellow(`\n⏳ signal-cli daemon ${L('başlatılıyor...', 'starting...')}\n`));
289
291
  console.log(chalk.gray(`HTTP: ${host}:${port}`));
290
- console.log(chalk.gray(`Hesap: ${account}`));
292
+ console.log(chalk.gray(`${L('Hesap', 'Account')}: ${account}`));
291
293
 
292
294
  const args = [
293
295
  'daemon',
@@ -308,21 +310,21 @@ async function startDaemon(config) {
308
310
  child.unref();
309
311
  fs.writeFileSync(SIGNAL_PID_FILE, String(child.pid), 'utf-8');
310
312
 
311
- console.log(chalk.green('✅ Daemon başlatıldı'));
313
+ console.log(chalk.green(L('✅ Daemon başlatıldı', '✅ Daemon started')));
312
314
  console.log(chalk.cyan('PID:'), chalk.white(child.pid));
313
315
  console.log(chalk.cyan('Log:'), chalk.white(SIGNAL_LOG_FILE));
314
316
 
315
317
  // Wait for API to be ready
316
- console.log(chalk.gray('\nAPI hazır olana kadar bekleniyor...'));
318
+ console.log(chalk.gray(L('\nAPI hazır olana kadar bekleniyor...', '\nWaiting for the API to be ready...')));
317
319
  for (let i = 0; i < 30; i++) {
318
320
  await new Promise(r => setTimeout(r, 1000));
319
321
  if (probeSync(config)) {
320
- console.log(chalk.green('✓ API hazır\n'));
322
+ console.log(chalk.green(L('✓ API hazır\n', '✓ API ready\n')));
321
323
  return;
322
324
  }
323
325
  process.stdout.write('.');
324
326
  }
325
- console.log(chalk.yellow('\n⚠️ API yanıt vermedi, logları kontrol edin\n'));
327
+ console.log(chalk.yellow(L('\n⚠️ API yanıt vermedi, logları kontrol edin\n', '\n⚠️ API did not respond, check the logs\n')));
326
328
  }
327
329
 
328
330
  function stopDaemon() {
@@ -344,9 +346,9 @@ function stopDaemon() {
344
346
  if (fs.existsSync(SIGNAL_PID_FILE)) {
345
347
  fs.unlinkSync(SIGNAL_PID_FILE);
346
348
  }
347
- console.log(chalk.green('\n✅ Daemon durduruldu\n'));
349
+ console.log(chalk.green(L('\n✅ Daemon durduruldu\n', '\n✅ Daemon stopped\n')));
348
350
  } catch (err) {
349
- console.log(chalk.red(`\n❌ Hata: ${err.message}\n`));
351
+ console.log(chalk.red(`\n❌ ${L('Hata', 'Error')}: ${err.message}\n`));
350
352
  }
351
353
  }
352
354
 
@@ -390,14 +392,14 @@ function isDaemonRunning() {
390
392
  async function probeSignalCli() {
391
393
  const config = getConfig();
392
394
  if (!config.signalHttpUrl) {
393
- console.log(chalk.red('\n❌ Signal bağlantısı yapılmamış\n'));
394
- console.log(chalk.gray('Önce: natureco signal connect\n'));
395
+ console.log(chalk.red(L('\n❌ Signal bağlantısı yapılmamış\n', '\n❌ Signal connection not set up\n')));
396
+ console.log(chalk.gray(L('Önce: natureco signal connect\n', 'First: natureco signal connect\n')));
395
397
  process.exit(1);
396
398
  }
397
399
 
398
400
  const baseUrl = config.signalHttpUrl;
399
401
  const mode = config.signalApiMode || 'auto';
400
- console.log(chalk.yellow(`\n⏳ Problanıyor: ${baseUrl}\n`));
402
+ console.log(chalk.yellow(`\n⏳ ${L('Problanıyor', 'Probing')}: ${baseUrl}\n`));
401
403
 
402
404
  let nativeOk = false;
403
405
  let containerOk = false;
@@ -428,7 +430,7 @@ async function probeSignalCli() {
428
430
 
429
431
  if (mode === 'auto') {
430
432
  const detected = nativeOk ? 'native' : containerOk ? 'container' : 'none';
431
- console.log(chalk.cyan(`\nAuto-detect sonucu: ${detected}`));
433
+ console.log(chalk.cyan(`\nAuto-detect ${L('sonucu', 'result')}: ${detected}`));
432
434
  }
433
435
 
434
436
  const cliPath = findSignalCli();
@@ -438,7 +440,7 @@ async function probeSignalCli() {
438
440
  const versionOut = execSync(`"${cliPath}" --version`, { encoding: 'utf-8', timeout: 10000 });
439
441
  console.log(chalk.gray(`Version: ${versionOut.trim()}`));
440
442
  } catch {
441
- console.log(chalk.gray('Version sorgulanamadı'));
443
+ console.log(chalk.gray(L('Version sorgulanamadı', 'Could not query version')));
442
444
  }
443
445
  }
444
446
 
@@ -1,4 +1,6 @@
1
1
  const chalk = require('chalk');
2
+ const { getLang: _gl } = require('../utils/i18n');
3
+ const L = (tr, en) => (_gl() === 'en' ? en : tr);
2
4
  const inquirer = require('../utils/inquirer-wrapper');
3
5
  const { getApiKey, getConfig, saveConfig } = require('../utils/config');
4
6
  const { getBots } = require('../utils/api');
@@ -27,7 +29,7 @@ async function connectSlack() {
27
29
  const config = getConfig();
28
30
 
29
31
  if (!config.providerUrl) {
30
- console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
32
+ console.log(chalk.red(L('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n', '\n❌ Setup not done. Run "natureco setup" first.\n')));
31
33
  process.exit(1);
32
34
  }
33
35
 
@@ -51,18 +53,18 @@ async function connectSlack() {
51
53
  const botId = `slack_${Date.now()}`;
52
54
  const selectedBot = { name: 'Slack Bot', id: botId };
53
55
 
54
- console.log(chalk.yellow('\n⏳ Slack bağlantısı kaydediliyor...\n'));
56
+ console.log(chalk.yellow(L('\n⏳ Slack bağlantısı kaydediliyor...\n', '\n⏳ Saving Slack connection...\n')));
55
57
 
56
58
  // Save to config (v2.x - no backend call)
57
59
  config.slackToken = answers.token.trim();
58
60
  config.slackBotId = botId;
59
61
  saveConfig(config);
60
62
 
61
- console.log(chalk.green('✅ Slack token kaydedildi!\n'));
63
+ console.log(chalk.green(L('✅ Slack token kaydedildi!\n', '✅ Slack token saved!\n')));
62
64
  console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
63
65
  console.log(chalk.cyan('Token:'), chalk.white(answers.token.slice(0, 20) + '...'));
64
- console.log(chalk.gray('\nNot: Slack botunuzu Slack App settings\'ten yapılandırmanız gerekiyor.'));
65
- console.log(chalk.gray('Token config\'e kaydedildi: ~/.natureco/config.json\n'));
66
+ console.log(chalk.gray(L('\nNot: Slack botunuzu Slack App settings\'ten yapılandırmanız gerekiyor.', '\nNote: You need to configure your Slack bot from the Slack App settings.')));
67
+ console.log(chalk.gray(L('Token config\'e kaydedildi: ~/.natureco/config.json\n', 'Token saved to config: ~/.natureco/config.json\n')));
66
68
  }
67
69
 
68
70
  async function disconnectSlack() {
@@ -1,4 +1,6 @@
1
1
  const chalk = require('chalk');
2
+ const { getLang: _gl } = require('../utils/i18n');
3
+ const L = (tr, en) => (_gl() === 'en' ? en : tr);
2
4
  const inquirer = require('../utils/inquirer-wrapper');
3
5
  const { getConfig, saveConfig } = require('../utils/config');
4
6
 
@@ -15,11 +17,11 @@ async function sms(action) {
15
17
  async function connectSms() {
16
18
  const config = getConfig();
17
19
  if (!config.providerUrl) {
18
- console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
20
+ console.log(chalk.red(L('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n', '\n❌ Setup not done. Run "natureco setup" first.\n')));
19
21
  process.exit(1);
20
22
  }
21
- console.log(chalk.yellow('\n⏳ SMS (Twilio) bağlantısı hazırlanıyor...\n'));
22
- console.log(chalk.gray('Twilio hesabı gereklidir: https://twilio.com\n'));
23
+ console.log(chalk.yellow(L('\n⏳ SMS (Twilio) bağlantısı hazırlanıyor...\n', '\n⏳ Preparing SMS (Twilio) connection...\n')));
24
+ console.log(chalk.gray(L('Twilio hesabı gereklidir: https://twilio.com\n', 'A Twilio account is required: https://twilio.com\n')));
23
25
 
24
26
  const defaults = {
25
27
  accountSid: config.smsAccountSid || '',
@@ -31,18 +33,18 @@ async function connectSms() {
31
33
  };
32
34
 
33
35
  const answers = await inquirer.prompt([
34
- { type: 'input', name: 'accountSid', message: 'Twilio Account SID:', default: defaults.accountSid ? defaults.accountSid.slice(0, 10) + '...' : '', validate: v => v.trim() ? true : 'Gerekli' },
36
+ { type: 'input', name: 'accountSid', message: 'Twilio Account SID:', default: defaults.accountSid ? defaults.accountSid.slice(0, 10) + '...' : '', validate: v => v.trim() ? true : L('Gerekli', 'Required') },
35
37
  { type: 'password', name: 'authToken', message: 'Twilio Auth Token:' },
36
- { type: 'input', name: 'fromNumber', message: 'Gönderen numara (E.164, +15551234567):', default: defaults.fromNumber, validate: v => v.trim() || defaults.messagingServiceSid ? true : 'Numara veya Messaging Service SID gerekli' },
37
- { type: 'input', name: 'messagingServiceSid', message: 'Messaging Service SID (opsiyonel):', default: defaults.messagingServiceSid },
38
- { type: 'input', name: 'webhookUrl', message: 'Genel webhook URL (ngrok vb., opsiyonel):', default: defaults.webhookUrl },
39
- { type: 'list', name: 'dmPolicy', message: 'DM politikası:', default: defaults.dmPolicy, choices: [
40
- { name: 'Allowlist (önerilen) — spam koruması', value: 'allowlist' },
41
- { name: 'Pairing — eşleşme kodu ile', value: 'pairing' },
42
- { name: 'Open — herkese açık', value: 'open' },
43
- { name: 'Disabled — devre dışı', value: 'disabled' },
38
+ { type: 'input', name: 'fromNumber', message: L('Gönderen numara (E.164, +15551234567):', 'Sender number (E.164, +15551234567):'), default: defaults.fromNumber, validate: v => v.trim() || defaults.messagingServiceSid ? true : L('Numara veya Messaging Service SID gerekli', 'Number or Messaging Service SID required') },
39
+ { type: 'input', name: 'messagingServiceSid', message: L('Messaging Service SID (opsiyonel):', 'Messaging Service SID (optional):'), default: defaults.messagingServiceSid },
40
+ { type: 'input', name: 'webhookUrl', message: L('Genel webhook URL (ngrok vb., opsiyonel):', 'Public webhook URL (ngrok etc., optional):'), default: defaults.webhookUrl },
41
+ { type: 'list', name: 'dmPolicy', message: L('DM politikası:', 'DM policy:'), default: defaults.dmPolicy, choices: [
42
+ { name: L('Allowlist (önerilen) — spam koruması', 'Allowlist (recommended) — spam protection'), value: 'allowlist' },
43
+ { name: L('Pairing — eşleşme kodu ile', 'Pairing — with a match code'), value: 'pairing' },
44
+ { name: L('Open — herkese açık', 'Open — public'), value: 'open' },
45
+ { name: L('Disabled — devre dışı', 'Disabled — off'), value: 'disabled' },
44
46
  ]},
45
- { type: 'confirm', name: 'enableWebhook', message: 'Gelen SMS webhook\'u etkinleştirilsin mi?', default: config.smsEnableWebhook !== false },
47
+ { type: 'confirm', name: 'enableWebhook', message: L('Gelen SMS webhook\'u etkinleştirilsin mi?', 'Enable inbound SMS webhook?'), default: config.smsEnableWebhook !== false },
46
48
  ]);
47
49
 
48
50
  const botId = `sms_${Date.now()}`;
@@ -56,21 +58,21 @@ async function connectSms() {
56
58
  config.smsBotId = botId;
57
59
  saveConfig(config);
58
60
 
59
- console.log(chalk.green('\n✅ SMS (Twilio) bağlantısı kaydedildi!\n'));
61
+ console.log(chalk.green(L('\n✅ SMS (Twilio) bağlantısı kaydedildi!\n', '\n✅ SMS (Twilio) connection saved!\n')));
60
62
  console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
61
63
  console.log(chalk.cyan('Account SID:'), chalk.white(answers.accountSid.slice(0, 20) + '...'));
62
- console.log(chalk.cyan('Numara:'), chalk.white(answers.fromNumber || '(Messaging Service)'));
63
- console.log(chalk.cyan('DM Politikası:'), chalk.white(answers.dmPolicy));
64
+ console.log(chalk.cyan(L('Numara:', 'Number:')), chalk.white(answers.fromNumber || '(Messaging Service)'));
65
+ console.log(chalk.cyan(L('DM Politikası:', 'DM Policy:')), chalk.white(answers.dmPolicy));
64
66
 
65
67
  if (answers.enableWebhook) {
66
- console.log(chalk.gray('\nTwilio Console\'da webhook URL\'si ayarlayın:'));
68
+ console.log(chalk.gray(L('\nTwilio Console\'da webhook URL\'si ayarlayın:', '\nSet the webhook URL in the Twilio Console:')));
67
69
  if (answers.webhookUrl) {
68
70
  console.log(chalk.cyan(` ${answers.webhookUrl}/webhooks/sms`));
69
71
  } else {
70
- console.log(chalk.gray(' (önce bir genel URL ayarlayın)'));
72
+ console.log(chalk.gray(L(' (önce bir genel URL ayarlayın)', ' (set a public URL first)')));
71
73
  }
72
74
  }
73
- console.log(chalk.gray('\nGateway ile başlatmak için: natureco gateway start\n'));
75
+ console.log(chalk.gray(L('\nGateway ile başlatmak için: natureco gateway start\n', '\nTo start with the gateway: natureco gateway start\n')));
74
76
  }
75
77
 
76
78
  async function disconnectSms() {
@@ -80,7 +82,7 @@ async function disconnectSms() {
80
82
  return;
81
83
  }
82
84
  const { confirm } = await inquirer.prompt([
83
- { type: 'confirm', name: 'confirm', message: 'SMS bağlantısını kaldırmak istediğinize emin misiniz?', default: false }
85
+ { type: 'confirm', name: 'confirm', message: L('SMS bağlantısını kaldırmak istediğinize emin misiniz?', 'Are you sure you want to remove the SMS connection?'), default: false }
84
86
  ]);
85
87
  if (!confirm) {
86
88
  console.log(chalk.gray('\nCancelled\n'));
@@ -103,22 +105,22 @@ function statusSms() {
103
105
  console.log(chalk.green('\n✅ SMS (Twilio) connected\n'));
104
106
  console.log(chalk.cyan('Bot ID:'), chalk.white(config.smsBotId));
105
107
  console.log(chalk.cyan('Account SID:'), chalk.white((config.smsAccountSid || '').slice(0, 20) + '...'));
106
- console.log(chalk.cyan('Numara:'), chalk.white(config.smsFromNumber || '(Messaging Service)'));
107
- console.log(chalk.cyan('DM Politikası:'), chalk.white(config.smsDmPolicy || 'allowlist'));
108
- console.log(chalk.cyan('Webhook:'), chalk.white(config.smsEnableWebhook !== false ? 'Aktif' : 'Devre Dışı'));
108
+ console.log(chalk.cyan(L('Numara:', 'Number:')), chalk.white(config.smsFromNumber || '(Messaging Service)'));
109
+ console.log(chalk.cyan(L('DM Politikası:', 'DM Policy:')), chalk.white(config.smsDmPolicy || 'allowlist'));
110
+ console.log(chalk.cyan('Webhook:'), chalk.white(config.smsEnableWebhook !== false ? L('Aktif', 'Active') : L('Devre Dışı', 'Disabled')));
109
111
  console.log(chalk.gray('\nDisconnect with: natureco sms disconnect\n'));
110
112
  }
111
113
 
112
114
  async function probeSms() {
113
115
  const config = getConfig();
114
116
  if (!config.smsAccountSid || !config.smsAuthToken) {
115
- console.log(chalk.red('\n❌ SMS bağlantısı yapılmamış\n'));
116
- console.log(chalk.gray('Önce: natureco sms connect\n'));
117
+ console.log(chalk.red(L('\n❌ SMS bağlantısı yapılmamış\n', '\n❌ SMS connection not set up\n')));
118
+ console.log(chalk.gray(L('Önce: natureco sms connect\n', 'First: natureco sms connect\n')));
117
119
  process.exit(1);
118
120
  }
119
121
 
120
122
  const base64Auth = Buffer.from(`${config.smsAccountSid}:${config.smsAuthToken}`).toString('base64');
121
- console.log(chalk.yellow('\n⏳ Twilio problanıyor...\n'));
123
+ console.log(chalk.yellow(L('\n⏳ Twilio problanıyor...\n', '\n⏳ Probing Twilio...\n')));
122
124
 
123
125
  try {
124
126
  const res = await fetch('https://api.twilio.com/2010-04-01/Accounts/' + config.smsAccountSid + '.json', {
@@ -127,14 +129,14 @@ async function probeSms() {
127
129
  });
128
130
 
129
131
  if (!res.ok) {
130
- console.log(chalk.red(`✗ Twilio API Hatası: HTTP ${res.status}\n`));
131
- if (res.status === 401) console.log(chalk.gray(' Account SID veya Auth Token hatalı.\n'));
132
+ console.log(chalk.red(`✗ ${L('Twilio API Hatası', 'Twilio API Error')}: HTTP ${res.status}\n`));
133
+ if (res.status === 401) console.log(chalk.gray(L(' Account SID veya Auth Token hatalı.\n', ' Account SID or Auth Token is incorrect.\n')));
132
134
  process.exit(1);
133
135
  }
134
136
 
135
137
  const account = await res.json();
136
- console.log(chalk.green('✓ Twilio API Bağlantısı Başarılı\n'));
137
- console.log(chalk.cyan('Hesap Adı:'), chalk.white(account.friendly_name));
138
+ console.log(chalk.green(L('✓ Twilio API Bağlantısı Başarılı\n', '✓ Twilio API Connection Successful\n')));
139
+ console.log(chalk.cyan(L('Hesap Adı:', 'Account Name:')), chalk.white(account.friendly_name));
138
140
  console.log(chalk.cyan('Status:'), chalk.white(account.status));
139
141
  console.log(chalk.cyan('Type:'), chalk.white(account.type));
140
142
 
@@ -147,20 +149,20 @@ async function probeSms() {
147
149
  });
148
150
  if (balRes.ok) {
149
151
  const balance = await balRes.json();
150
- console.log(chalk.cyan('Bakiye:'), chalk.white(`${balance.balance} ${balance.currency}`));
152
+ console.log(chalk.cyan(L('Bakiye:', 'Balance:')), chalk.white(`${balance.balance} ${balance.currency}`));
151
153
  }
152
154
  } catch {}
153
155
  }
154
156
 
155
157
  // Check phone number
156
158
  if (config.smsFromNumber) {
157
- console.log(chalk.gray(`\nGönderen numara: ${config.smsFromNumber}`));
159
+ console.log(chalk.gray(`\n${L('Gönderen numara', 'Sender number')}: ${config.smsFromNumber}`));
158
160
  }
159
161
 
160
162
  console.log('');
161
163
 
162
164
  } catch (err) {
163
- console.log(chalk.red(`\n✗ Probe hatası: ${err.message}\n`));
165
+ console.log(chalk.red(`\n✗ ${L('Probe hatası', 'Probe error')}: ${err.message}\n`));
164
166
  process.exit(1);
165
167
  }
166
168
  }