natureco-cli 5.55.0 → 5.56.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 F = require('../utils/format');
3
5
  const { listTasks, getTask, cancelTask, auditTasks, maintenanceTasks, getTaskSummary, TASK_STATUSES, RUNTIME_TYPES } = require('../utils/background');
4
6
  const { spawnSubAgent, spawnParallel, getStatus } = require('../utils/sub-agent');
@@ -65,8 +67,8 @@ async function tasks(args) {
65
67
  if (action === 'delegate-parallel') return delegateParallelHandler(params.join(' '));
66
68
  if (action === 'sub-status') return subStatusHandler();
67
69
 
68
- console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
69
- console.log(chalk.gray(' Kullanım: natureco tasks [list|show|cancel|audit|maintenance|flow|summary|notify|delegate|delegate-parallel|sub-status]\n'));
70
+ console.log(chalk.red(`\n ❌ ${L('Bilinmeyen komut', 'Unknown command')}: ${action}\n`));
71
+ console.log(chalk.gray(L(' Kullanım: natureco tasks [list|show|cancel|audit|maintenance|flow|summary|notify|delegate|delegate-parallel|sub-status]\n', ' Usage: natureco tasks [list|show|cancel|audit|maintenance|flow|summary|notify|delegate|delegate-parallel|sub-status]\n')));
70
72
  process.exit(1);
71
73
  }
72
74
 
@@ -81,9 +83,9 @@ function listTasksHandler(opts) {
81
83
  F.header('Background Tasks');
82
84
 
83
85
  if (tasks.length === 0) {
84
- F.meta('Hiç task bulunamadı.');
85
- if (opts.runtime) F.meta('Filtre: runtime=' + opts.runtime);
86
- if (opts.status) F.meta('Filtre: status=' + opts.status);
86
+ F.meta(L('Hiç task bulunamadı.', 'No tasks found.'));
87
+ if (opts.runtime) F.meta(L('Filtre: runtime=', 'Filter: runtime=') + opts.runtime);
88
+ if (opts.status) F.meta(L('Filtre: status=', 'Filter: status=') + opts.status);
87
89
  return;
88
90
  }
89
91
 
@@ -97,21 +99,21 @@ function listTasksHandler(opts) {
97
99
  F.table(['ID', 'Name', 'Status', 'Runtime', 'Time'], rows);
98
100
 
99
101
  const summary = getTaskSummary();
100
- F.meta('Toplam: ' + tasks.length + ' (gösterilen) | Aktif: ' + summary.active + ' | Hata: ' + summary.failures);
101
- F.meta('Filtre: --runtime <type> --status <status>');
102
+ F.meta(L('Toplam: ', 'Total: ') + tasks.length + L(' (gösterilen) | Aktif: ', ' (shown) | Active: ') + summary.active + L(' | Hata: ', ' | Errors: ') + summary.failures);
103
+ F.meta(L('Filtre: --runtime <type> --status <status>', 'Filter: --runtime <type> --status <status>'));
102
104
  F.meta('JSON: natureco tasks list --json');
103
105
  }
104
106
 
105
107
  function showTaskHandler(id, opts) {
106
108
  if (!id) {
107
- F.error('Task ID gerekli');
108
- F.meta('Kullanım: natureco tasks show <id>');
109
+ F.error(L('Task ID gerekli', 'Task ID required'));
110
+ F.meta(L('Kullanım: natureco tasks show <id>', 'Usage: natureco tasks show <id>'));
109
111
  process.exit(1);
110
112
  }
111
113
 
112
114
  const task = getTask(id);
113
115
  if (!task) {
114
- F.error('Task bulunamadı: ' + id);
116
+ F.error(L('Task bulunamadı: ', 'Task not found: ') + id);
115
117
  process.exit(1);
116
118
  }
117
119
 
@@ -121,27 +123,27 @@ function showTaskHandler(id, opts) {
121
123
  }
122
124
 
123
125
  F.header('Task: ' + task.id);
124
- F.kv('Durum', task.status);
126
+ F.kv(L('Durum', 'Status'), task.status);
125
127
  F.kv('Runtime', task.runtime);
126
128
  F.kv('Bot', task.botName);
127
- if (task.message) F.kv('Mesaj', task.message);
128
- F.kv('Oluşturma', formatTime(task.createdAt));
129
- if (task.startedAt) F.kv('Başlangıç', formatTime(task.startedAt));
130
- if (task.endedAt) F.kv('Bitiş', formatTime(task.endedAt));
131
- if (task.notifyPolicy) F.kv('Bildirim', task.notifyPolicy);
132
- if (task.childSessionKey) F.kv('Çocuk', task.childSessionKey);
129
+ if (task.message) F.kv(L('Mesaj', 'Message'), task.message);
130
+ F.kv(L('Oluşturma', 'Created'), formatTime(task.createdAt));
131
+ if (task.startedAt) F.kv(L('Başlangıç', 'Started'), formatTime(task.startedAt));
132
+ if (task.endedAt) F.kv(L('Bitiş', 'Ended'), formatTime(task.endedAt));
133
+ if (task.notifyPolicy) F.kv(L('Bildirim', 'Notification'), task.notifyPolicy);
134
+ if (task.childSessionKey) F.kv(L('Çocuk', 'Child'), task.childSessionKey);
133
135
  if (task.runId) F.kv('Run ID', task.runId);
134
136
 
135
137
  if (task.result) {
136
138
  console.log('');
137
- F.kv('Sonuç', task.result);
139
+ F.kv(L('Sonuç', 'Result'), task.result);
138
140
  }
139
141
  if (task.error) {
140
142
  console.log('');
141
- F.kv('Hata', task.error);
143
+ F.kv(L('Hata', 'Error'), task.error);
142
144
  }
143
145
  if (task.cleanupAfter) {
144
- F.meta('Temizlik: ' + formatTime(task.cleanupAfter));
146
+ F.meta(L('Temizlik: ', 'Cleanup: ') + formatTime(task.cleanupAfter));
145
147
  }
146
148
  if (task.metadata && Object.keys(task.metadata).length > 0) {
147
149
  console.log('');
@@ -152,21 +154,21 @@ function showTaskHandler(id, opts) {
152
154
 
153
155
  function cancelTaskHandler(id) {
154
156
  if (!id) {
155
- F.error('Task ID gerekli');
156
- F.meta('Kullanım: natureco tasks cancel <id>');
157
+ F.error(L('Task ID gerekli', 'Task ID required'));
158
+ F.meta(L('Kullanım: natureco tasks cancel <id>', 'Usage: natureco tasks cancel <id>'));
157
159
  process.exit(1);
158
160
  }
159
161
 
160
162
  const result = cancelTask(id);
161
163
  if (!result) {
162
- F.error('Task bulunamadı: ' + id);
164
+ F.error(L('Task bulunamadı: ', 'Task not found: ') + id);
163
165
  process.exit(1);
164
166
  }
165
167
 
166
168
  if (result.status === 'cancelled') {
167
- F.success('Task iptal edildi: ' + id);
169
+ F.success(L('Task iptal edildi: ', 'Task cancelled: ') + id);
168
170
  } else {
169
- F.warning('Task zaten terminal durumda: ' + result.status);
171
+ F.warning(L('Task zaten terminal durumda: ', 'Task already in terminal state: ') + result.status);
170
172
  }
171
173
  }
172
174
 
@@ -178,10 +180,10 @@ function auditHandler(opts) {
178
180
  return;
179
181
  }
180
182
 
181
- F.header('Task Denetimi');
183
+ F.header(L('Task Denetimi', 'Task Audit'));
182
184
 
183
185
  if (findings.length === 0) {
184
- F.success('Sorun bulunamadı.');
186
+ F.success(L('Sorun bulunamadı.', 'No issues found.'));
185
187
  return;
186
188
  }
187
189
 
@@ -191,7 +193,7 @@ function auditHandler(opts) {
191
193
  }
192
194
 
193
195
  if (filtered.length === 0) {
194
- F.meta('Filtreye uygun bulgu yok (severity=' + opts.severity + ')');
196
+ F.meta(L('Filtreye uygun bulgu yok (severity=', 'No findings match filter (severity=') + opts.severity + ')');
195
197
  return;
196
198
  }
197
199
 
@@ -203,33 +205,33 @@ function auditHandler(opts) {
203
205
  ]);
204
206
  F.table(['ID', 'Code', 'Severity', 'Message'], rows);
205
207
 
206
- F.meta('Toplam: ' + filtered.length + ' bulgu');
207
- F.meta('Bakım: natureco tasks maintenance --apply');
208
+ F.meta(L('Toplam: ', 'Total: ') + filtered.length + L(' bulgu', ' findings'));
209
+ F.meta(L('Bakım: natureco tasks maintenance --apply', 'Maintenance: natureco tasks maintenance --apply'));
208
210
  }
209
211
 
210
212
  function maintenanceHandler(opts) {
211
- F.header('Task Bakımı');
213
+ F.header(L('Task Bakımı', 'Task Maintenance'));
212
214
 
213
215
  const dryRun = !opts.apply;
214
216
  const result = maintenanceTasks(dryRun);
215
217
 
216
218
  if (dryRun) {
217
- F.info('Kuru çalışma (--apply ile uygula)');
219
+ F.info(L('Kuru çalışma (--apply ile uygula)', 'Dry run (apply with --apply)'));
218
220
  }
219
221
 
220
- F.kv('Temizlenen', result.pruned);
221
- F.kv('Düzeltilen', result.reconciled);
222
- F.kv('Etiketlenen', result.cleaned);
223
- F.kv('Kalan task', result.remaining);
222
+ F.kv(L('Temizlenen', 'Pruned'), result.pruned);
223
+ F.kv(L('Düzeltilen', 'Reconciled'), result.reconciled);
224
+ F.kv(L('Etiketlenen', 'Labeled'), result.cleaned);
225
+ F.kv(L('Kalan task', 'Remaining'), result.remaining);
224
226
 
225
227
  if (result.pruned > 0 || result.reconciled > 0 || result.cleaned > 0) {
226
228
  if (dryRun) {
227
- F.meta('Uygulamak için: natureco tasks maintenance --apply');
229
+ F.meta(L('Uygulamak için: natureco tasks maintenance --apply', 'To apply: natureco tasks maintenance --apply'));
228
230
  } else {
229
- F.success('Bakım uygulandı.');
231
+ F.success(L('Bakım uygulandı.', 'Maintenance applied.'));
230
232
  }
231
233
  } else {
232
- F.success('Bakım gerekmiyor.');
234
+ F.success(L('Bakım gerekmiyor.', 'No maintenance needed.'));
233
235
  }
234
236
  }
235
237
 
@@ -244,7 +246,7 @@ function flowListHandler(opts) {
244
246
  F.header('Task Flow');
245
247
 
246
248
  if (tasks.length === 0) {
247
- F.meta('Task Flow kaydı yok.');
249
+ F.meta(L('Task Flow kaydı yok.', 'No Task Flow records.'));
248
250
  return;
249
251
  }
250
252
 
@@ -255,12 +257,12 @@ function flowListHandler(opts) {
255
257
  ]);
256
258
  F.table(['ID', 'Status', 'Message'], rows);
257
259
 
258
- F.meta('Toplam: ' + tasks.length + ' flow');
260
+ F.meta(L('Toplam: ', 'Total: ') + tasks.length + ' flow');
259
261
  }
260
262
 
261
263
  function flowShowHandler(id, opts) {
262
264
  if (!id) {
263
- console.log(chalk.red('\n ❌ Flow ID gerekli\n'));
265
+ console.log(chalk.red(L('\n ❌ Flow ID gerekli\n', '\n ❌ Flow ID required\n')));
264
266
  process.exit(1);
265
267
  }
266
268
  return showTaskHandler(id, opts);
@@ -268,7 +270,7 @@ function flowShowHandler(id, opts) {
268
270
 
269
271
  function flowCancelHandler(id) {
270
272
  if (!id) {
271
- console.log(chalk.red('\n ❌ Flow ID gerekli\n'));
273
+ console.log(chalk.red(L('\n ❌ Flow ID gerekli\n', '\n ❌ Flow ID required\n')));
272
274
  process.exit(1);
273
275
  }
274
276
  return cancelTaskHandler(id);
@@ -284,11 +286,11 @@ function summaryHandler(opts) {
284
286
 
285
287
  console.log('');
286
288
  console.log(chalk.gray(' ' + '─'.repeat(48)));
287
- console.log(chalk.cyan.bold('\n Task Özeti\n'));
288
- console.log(chalk.gray(' Aktif : ') + (summary.active > 0 ? chalk.yellow(summary.active) : chalk.green('0')));
289
- console.log(chalk.gray(' Hatalı : ') + (summary.failures > 0 ? chalk.red(summary.failures) : chalk.green('0')));
290
- console.log(chalk.gray(' Toplam : ') + chalk.white(summary.total));
291
- console.log(chalk.gray('\n Runtime Dağılımı'));
289
+ console.log(chalk.cyan.bold(L('\n Task Özeti\n', '\n Task Summary\n')));
290
+ console.log(chalk.gray(L(' Aktif : ', ' Active : ')) + (summary.active > 0 ? chalk.yellow(summary.active) : chalk.green('0')));
291
+ console.log(chalk.gray(L(' Hatalı : ', ' Failed : ')) + (summary.failures > 0 ? chalk.red(summary.failures) : chalk.green('0')));
292
+ console.log(chalk.gray(L(' Toplam : ', ' Total : ')) + chalk.white(summary.total));
293
+ console.log(chalk.gray(L('\n Runtime Dağılımı', '\n Runtime Distribution')));
292
294
  Object.entries(summary.byRuntime).forEach(([rt, count]) => {
293
295
  if (count > 0) console.log(chalk.gray(` ${rt.padEnd(10)}: ${count}`));
294
296
  });
@@ -298,28 +300,28 @@ function summaryHandler(opts) {
298
300
  function getAgeString(dateStr) {
299
301
  const ms = Date.now() - new Date(dateStr).getTime();
300
302
  const sec = Math.floor(ms / 1000);
301
- if (sec < 60) return `${sec}s önce`;
303
+ if (sec < 60) return `${sec}${L('s önce', 's ago')}`;
302
304
  const min = Math.floor(sec / 60);
303
- if (min < 60) return `${min}dk önce`;
305
+ if (min < 60) return `${min}${L('dk önce', 'm ago')}`;
304
306
  const hr = Math.floor(min / 60);
305
- if (hr < 24) return `${hr}sa önce`;
307
+ if (hr < 24) return `${hr}${L('sa önce', 'h ago')}`;
306
308
  const days = Math.floor(hr / 24);
307
- return `${days}g önce`;
309
+ return `${days}${L('g önce', 'd ago')}`;
308
310
  }
309
311
 
310
312
  function formatTime(dateStr) {
311
- return new Date(dateStr).toLocaleString('tr-TR');
313
+ return new Date(dateStr).toLocaleString(_gl() === 'en' ? 'en-US' : 'tr-TR');
312
314
  }
313
315
 
314
316
  function notifyTaskHandler(id, message) {
315
317
  if (!id) {
316
- F.error('Task ID gerekli');
317
- F.meta('Kullanım: natureco tasks notify <id> [message]');
318
+ F.error(L('Task ID gerekli', 'Task ID required'));
319
+ F.meta(L('Kullanım: natureco tasks notify <id> [message]', 'Usage: natureco tasks notify <id> [message]'));
318
320
  process.exit(1);
319
321
  }
320
322
  const task = getTask(id);
321
323
  if (!task) {
322
- F.error('Task bulunamadı: ' + id);
324
+ F.error(L('Task bulunamadı: ', 'Task not found: ') + id);
323
325
  process.exit(1);
324
326
  }
325
327
  F.header('Task Notification');
@@ -331,8 +333,8 @@ function notifyTaskHandler(id, message) {
331
333
 
332
334
  async function delegateHandler(type, task) {
333
335
  if (!type || !task) {
334
- F.error('Kullanım: natureco tasks delegate <type> <task>');
335
- F.meta('Tipler: explore, general, review');
336
+ F.error(L('Kullanım: natureco tasks delegate <type> <task>', 'Usage: natureco tasks delegate <type> <task>'));
337
+ F.meta(L('Tipler: explore, general, review', 'Types: explore, general, review'));
336
338
  process.exit(1);
337
339
  }
338
340
 
@@ -342,38 +344,38 @@ async function delegateHandler(type, task) {
342
344
 
343
345
  try {
344
346
  const result = await spawnSubAgent(type, task);
345
- F.success('Sub-agent tamamlandı');
347
+ F.success(L('Sub-agent tamamlandı', 'Sub-agent completed'));
346
348
  F.divider();
347
349
  console.log(chalk.white(result.result));
348
350
  if (result.duration) {
349
- F.meta(`Süre: ${(result.duration / 1000).toFixed(1)}s`);
351
+ F.meta(`${L('Süre', 'Duration')}: ${(result.duration / 1000).toFixed(1)}s`);
350
352
  }
351
353
  if (result.usage) {
352
354
  F.meta(`Token: ${result.usage.prompt_tokens || result.usage.input_tokens || '?'} → ${result.usage.completion_tokens || result.usage.output_tokens || '?'}`);
353
355
  }
354
356
  } catch (err) {
355
- F.error('Sub-agent hatası: ' + err.message);
357
+ F.error(L('Sub-agent hatası: ', 'Sub-agent error: ') + err.message);
356
358
  process.exit(1);
357
359
  }
358
360
  }
359
361
 
360
362
  async function delegateParallelHandler(input) {
361
363
  if (!input) {
362
- F.error('Kullanım: natureco tasks delegate-parallel <type1> <task1> | <type2> <task2>');
363
- F.meta('Birden çok agent\'ı " | " (pipe) ile ayırın');
364
+ F.error(L('Kullanım: natureco tasks delegate-parallel <type1> <task1> | <type2> <task2>', 'Usage: natureco tasks delegate-parallel <type1> <task1> | <type2> <task2>'));
365
+ F.meta(L('Birden çok agent\'ı " | " (pipe) ile ayırın', 'Separate multiple agents with " | " (pipe)'));
364
366
  process.exit(1);
365
367
  }
366
368
 
367
369
  const parts = input.split(/\s+\|\s+/);
368
370
  if (parts.length < 2) {
369
- F.error('En az 2 agent belirtin, " | " ile ayırın');
371
+ F.error(L('En az 2 agent belirtin, " | " ile ayırın', 'Specify at least 2 agents, separated by " | "'));
370
372
  process.exit(1);
371
373
  }
372
374
 
373
375
  const agents = parts.map(p => {
374
376
  const trimmed = p.trim();
375
377
  const spaceIdx = trimmed.indexOf(' ');
376
- if (spaceIdx === -1) throw new Error(`Geçersiz agent: "${trimmed}" (type + task gerekli)`);
378
+ if (spaceIdx === -1) throw new Error(`${L('Geçersiz agent', 'Invalid agent')}: "${trimmed}" (type + task ${L('gerekli', 'required')})`);
377
379
  return {
378
380
  type: trimmed.slice(0, spaceIdx),
379
381
  task: trimmed.slice(spaceIdx + 1).trim(),
@@ -383,7 +385,7 @@ async function delegateParallelHandler(input) {
383
385
  F.header('Parallel Sub-agents (' + agents.length + ')');
384
386
  agents.forEach(a => F.kv(a.type, a.task.slice(0, 60)));
385
387
 
386
- F.info('Çalıştırılıyor...');
388
+ F.info(L('Çalıştırılıyor...', 'Running...'));
387
389
 
388
390
  const { results, failed } = await spawnParallel(agents);
389
391
 
@@ -392,16 +394,16 @@ async function delegateParallelHandler(input) {
392
394
  results.forEach((r, i) => {
393
395
  const agent = agents[i];
394
396
  if (r.status === 'fulfilled') {
395
- F.success(`${agent.type} — tamamlandı (${(r.value.duration / 1000).toFixed(1)}s)`);
397
+ F.success(`${agent.type} — ${L('tamamlandı', 'completed')} (${(r.value.duration / 1000).toFixed(1)}s)`);
396
398
  } else {
397
- F.error(`${agent.type} — hata: ${r.reason}`);
399
+ F.error(`${agent.type} — ${L('hata', 'error')}: ${r.reason}`);
398
400
  }
399
401
  });
400
402
 
401
403
  if (failed.length > 0) {
402
- F.warning(`${failed.length}/${agents.length} agent başarısız`);
404
+ F.warning(`${failed.length}/${agents.length} agent ${L('başarısız', 'failed')}`);
403
405
  } else {
404
- F.success('Tüm agent' + (agents.length > 1 ? 'lar' : '') + ' tamamlandı');
406
+ F.success(L('Tüm agent' + (agents.length > 1 ? 'lar' : '') + ' tamamlandı', 'All agents completed'));
405
407
  }
406
408
  }
407
409
 
@@ -410,15 +412,15 @@ function subStatusHandler() {
410
412
 
411
413
  if (status.total === 0) {
412
414
  F.header('Sub-agent Status');
413
- F.meta('Henüz sub-agent kaydı yok.');
415
+ F.meta(L('Henüz sub-agent kaydı yok.', 'No sub-agent records yet.'));
414
416
  return;
415
417
  }
416
418
 
417
419
  F.header('Sub-agent Status');
418
- F.kv('Toplam', status.total);
419
- F.kv('Çalışan', String(status.running));
420
- F.kv('Tamamlanan', String(status.completed));
421
- F.kv('Hatalı', String(status.failed));
420
+ F.kv(L('Toplam', 'Total'), status.total);
421
+ F.kv(L('Çalışan', 'Running'), String(status.running));
422
+ F.kv(L('Tamamlanan', 'Completed'), String(status.completed));
423
+ F.kv(L('Hatalı', 'Failed'), String(status.failed));
422
424
 
423
425
  if (status.agents.length > 0) {
424
426
  console.log('');
@@ -427,7 +429,7 @@ function subStatusHandler() {
427
429
  a.type,
428
430
  a.status === 'completed' ? chalk.green('✓') : a.status === 'failed' ? chalk.red('✗') : chalk.cyan('⟳'),
429
431
  a.task.slice(0, 40),
430
- a.completedAt ? new Date(a.completedAt).toLocaleString('tr-TR') : '—',
432
+ a.completedAt ? new Date(a.completedAt).toLocaleString(_gl() === 'en' ? 'en-US' : 'tr-TR') : '—',
431
433
  ]);
432
434
  F.table(['ID', 'Type', '', 'Task', 'Completed'], rows);
433
435
  }