natureco-cli 5.54.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.
- package/package.json +1 -1
- package/src/commands/agent.js +14 -12
- package/src/commands/agents.js +26 -24
- package/src/commands/bots.js +10 -8
- package/src/commands/config.js +31 -29
- package/src/commands/cost.js +61 -58
- package/src/commands/memory-cmd.js +70 -68
- package/src/commands/models.js +623 -621
- package/src/commands/tasks.js +78 -76
- package/src/commands/team.js +172 -170
- package/src/commands/workboard.js +15 -13
package/src/commands/cost.js
CHANGED
|
@@ -1,41 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* natureco cost —
|
|
2
|
+
* natureco cost — cost tracking and budget management (Phase 4)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* natureco cost
|
|
6
|
-
* natureco cost today
|
|
7
|
-
* natureco cost week
|
|
8
|
-
* natureco cost month
|
|
9
|
-
* natureco cost all
|
|
10
|
-
* natureco cost budget
|
|
11
|
-
* natureco cost set <key> <val>
|
|
12
|
-
* natureco cost model <prompt>
|
|
13
|
-
* natureco cost prices
|
|
4
|
+
* Usage:
|
|
5
|
+
* natureco cost Show today's cost
|
|
6
|
+
* natureco cost today Today's cost
|
|
7
|
+
* natureco cost week This week's cost
|
|
8
|
+
* natureco cost month This month's cost
|
|
9
|
+
* natureco cost all All time
|
|
10
|
+
* natureco cost budget Budget status and warnings
|
|
11
|
+
* natureco cost set <key> <val> Set a budget (dailyLimit 5, monthlyLimit 100, warnAt 0.75)
|
|
12
|
+
* natureco cost model <prompt> Show the suggested model for a prompt
|
|
13
|
+
* natureco cost prices List all prices
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const chalk = require('chalk');
|
|
17
17
|
const tui = require('../utils/tui');
|
|
18
18
|
const cost = require('../utils/cost-tracker');
|
|
19
19
|
const audit = require('../utils/audit');
|
|
20
|
+
const { getLang } = require('../utils/i18n');
|
|
21
|
+
|
|
22
|
+
const L = (tr, en) => (getLang() === 'en' ? en : tr);
|
|
20
23
|
|
|
21
24
|
function showPeriod(period) {
|
|
22
25
|
const data = cost.totalForPeriod(period);
|
|
23
26
|
const icon = { today: '📅', week: '📆', month: '🗓️', all: '♾️ ' }[period] || '💰';
|
|
24
|
-
console.log(tui.styled(`\n ${icon} Maliyet Raporu · ${period.toUpperCase()}`, { color: tui.PALETTE.primary, bold: true }));
|
|
27
|
+
console.log(tui.styled(`\n ${icon} ${L('Maliyet Raporu', 'Cost Report')} · ${period.toUpperCase()}`, { color: tui.PALETTE.primary, bold: true }));
|
|
25
28
|
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
26
29
|
|
|
27
|
-
//
|
|
30
|
+
// Top metric card
|
|
28
31
|
const cardWidth = 54;
|
|
29
32
|
const cardLines = [];
|
|
30
33
|
cardLines.push(tui.styled(' ╭' + '─'.repeat(cardWidth) + '╮', { color: tui.PALETTE.border }));
|
|
31
|
-
cardLines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('Toplam maliyet:') + ' ' + tui.styled(cost.formatUSD(data.totalCost).padStart(12), { color: tui.PALETTE.primary, bold: true }) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
32
|
-
cardLines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('Toplam token:') + ' ' + tui.C.text((data.totalInput + data.totalOutput).toLocaleString().padStart(8) + ` (${data.totalInput.toLocaleString()} in / ${data.totalOutput.toLocaleString()} out)`) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
33
|
-
cardLines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('Çağrı sayısı:') + ' ' + tui.C.text(String(data.entries).padStart(8)) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
34
|
+
cardLines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted(L('Toplam maliyet:', 'Total cost:')) + ' ' + tui.styled(cost.formatUSD(data.totalCost).padStart(12), { color: tui.PALETTE.primary, bold: true }) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
35
|
+
cardLines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted(L('Toplam token:', 'Total tokens:')) + ' ' + tui.C.text((data.totalInput + data.totalOutput).toLocaleString().padStart(8) + ` (${data.totalInput.toLocaleString()} in / ${data.totalOutput.toLocaleString()} out)`) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
36
|
+
cardLines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted(L('Çağrı sayısı:', 'Calls:')) + ' ' + tui.C.text(String(data.entries).padStart(8)) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
34
37
|
cardLines.push(tui.styled(' ╰' + '─'.repeat(cardWidth) + '╯', { color: tui.PALETTE.border }));
|
|
35
38
|
console.log(cardLines.join('\n'));
|
|
36
39
|
|
|
37
40
|
if (Object.keys(data.byProvider).length > 0) {
|
|
38
|
-
console.log('\n' + tui.styled(' 💵 Provider Bazlı Maliyet', { color: tui.PALETTE.secondary, bold: true }));
|
|
41
|
+
console.log('\n' + tui.styled(' 💵 ' + L('Provider Bazlı Maliyet', 'Cost by Provider'), { color: tui.PALETTE.secondary, bold: true }));
|
|
39
42
|
const providerRows = Object.entries(data.byProvider)
|
|
40
43
|
.sort((a, b) => b[1] - a[1])
|
|
41
44
|
.map(([provider, amount]) => ({
|
|
@@ -45,13 +48,13 @@ function showPeriod(period) {
|
|
|
45
48
|
}));
|
|
46
49
|
console.log('\n' + tui.table(providerRows, [
|
|
47
50
|
{ key: 'provider', label: 'Provider', minWidth: 12 },
|
|
48
|
-
{ key: 'amount', label: 'Maliyet', minWidth: 10, render: r => tui.C.brand(r.amount) },
|
|
49
|
-
{ key: 'pct', label: 'Dağılım', minWidth: 20, render: r => tui.styled(r.pct, { color: tui.PALETTE.primary }) },
|
|
51
|
+
{ key: 'amount', label: L('Maliyet', 'Cost'), minWidth: 10, render: r => tui.C.brand(r.amount) },
|
|
52
|
+
{ key: 'pct', label: L('Dağılım', 'Distribution'), minWidth: 20, render: r => tui.styled(r.pct, { color: tui.PALETTE.primary }) },
|
|
50
53
|
], { borderStyle: 'round', zebra: true }));
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
if (Object.keys(data.byModel).length > 0) {
|
|
54
|
-
console.log('\n' + tui.styled(' 🤖 Model Bazlı Maliyet (Top 5)', { color: tui.PALETTE.accent, bold: true }));
|
|
57
|
+
console.log('\n' + tui.styled(' 🤖 ' + L('Model Bazlı Maliyet (Top 5)', 'Cost by Model (Top 5)'), { color: tui.PALETTE.accent, bold: true }));
|
|
55
58
|
const sortedModels = Object.entries(data.byModel).sort((a, b) => b[1] - a[1]).slice(0, 5);
|
|
56
59
|
const modelRows = sortedModels.map(([model, amount]) => ({
|
|
57
60
|
model,
|
|
@@ -59,7 +62,7 @@ function showPeriod(period) {
|
|
|
59
62
|
}));
|
|
60
63
|
console.log('\n' + tui.table(modelRows, [
|
|
61
64
|
{ key: 'model', label: 'Model', minWidth: 40, render: r => tui.C.muted(r.model) },
|
|
62
|
-
{ key: 'amount', label: 'Maliyet', minWidth: 10, render: r => tui.C.brand(r.amount) },
|
|
65
|
+
{ key: 'amount', label: L('Maliyet', 'Cost'), minWidth: 10, render: r => tui.C.brand(r.amount) },
|
|
63
66
|
], { borderStyle: 'round', zebra: true }));
|
|
64
67
|
}
|
|
65
68
|
console.log('');
|
|
@@ -69,52 +72,52 @@ function showBudget() {
|
|
|
69
72
|
const status = cost.checkBudget();
|
|
70
73
|
const budget = cost.loadBudget();
|
|
71
74
|
|
|
72
|
-
console.log('\n' + tui.styled(' 🛡️ Bütçe Durumu', { color: tui.PALETTE.primary, bold: true }));
|
|
75
|
+
console.log('\n' + tui.styled(' 🛡️ ' + L('Bütçe Durumu', 'Budget Status'), { color: tui.PALETTE.primary, bold: true }));
|
|
73
76
|
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
74
77
|
|
|
75
|
-
//
|
|
78
|
+
// Daily
|
|
76
79
|
const dailyBar = tui.progressBar(status.daily.usage, 1, {
|
|
77
80
|
width: 25, showPercent: true,
|
|
78
81
|
fillChar: status.daily.exceeded ? '▓' : status.daily.warning ? '▒' : '█',
|
|
79
82
|
});
|
|
80
83
|
const dailyColor = status.daily.exceeded ? tui.PALETTE.danger : status.daily.warning ? tui.PALETTE.warning : tui.PALETTE.success;
|
|
81
|
-
console.log(`\n ${tui.C.muted('Günlük limit')} ${tui.C.brand(cost.formatUSD(budget.dailyLimit).padStart(10))} ${tui.styled(dailyBar, { color: dailyColor })}`);
|
|
82
|
-
if (status.daily.exceeded) console.log(' ' + tui.styled('⚠️ Günlük limit aşıldı!', { color: tui.PALETTE.danger, bold: true }));
|
|
83
|
-
else if (status.daily.warning) console.log(' ' + tui.styled(
|
|
84
|
+
console.log(`\n ${tui.C.muted(L('Günlük limit', 'Daily limit'))} ${tui.C.brand(cost.formatUSD(budget.dailyLimit).padStart(10))} ${tui.styled(dailyBar, { color: dailyColor })}`);
|
|
85
|
+
if (status.daily.exceeded) console.log(' ' + tui.styled('⚠️ ' + L('Günlük limit aşıldı!', 'Daily limit exceeded!'), { color: tui.PALETTE.danger, bold: true }));
|
|
86
|
+
else if (status.daily.warning) console.log(' ' + tui.styled('⚠️ ' + L(`%${(budget.warnAt * 100)} eşiğine yaklaşıldı`, `approaching the ${(budget.warnAt * 100)}% threshold`), { color: tui.PALETTE.warning }));
|
|
84
87
|
|
|
85
88
|
console.log('');
|
|
86
89
|
|
|
87
|
-
//
|
|
90
|
+
// Monthly
|
|
88
91
|
const monthlyBar = tui.progressBar(status.monthly.usage, 1, {
|
|
89
92
|
width: 25, showPercent: true,
|
|
90
93
|
fillChar: status.monthly.exceeded ? '▓' : status.monthly.warning ? '▒' : '█',
|
|
91
94
|
});
|
|
92
95
|
const monthlyColor = status.monthly.exceeded ? tui.PALETTE.danger : status.monthly.warning ? tui.PALETTE.warning : tui.PALETTE.success;
|
|
93
|
-
console.log(` ${tui.C.muted('Aylık limit')} ${tui.C.brand(cost.formatUSD(budget.monthlyLimit).padStart(10))} ${tui.styled(monthlyBar, { color: monthlyColor })}`);
|
|
94
|
-
if (status.monthly.exceeded) console.log(' ' + tui.styled('⚠️ Aylık limit aşıldı!', { color: tui.PALETTE.danger, bold: true }));
|
|
95
|
-
else if (status.monthly.warning) console.log(' ' + tui.styled(
|
|
96
|
+
console.log(` ${tui.C.muted(L('Aylık limit', 'Monthly limit'))} ${tui.C.brand(cost.formatUSD(budget.monthlyLimit).padStart(10))} ${tui.styled(monthlyBar, { color: monthlyColor })}`);
|
|
97
|
+
if (status.monthly.exceeded) console.log(' ' + tui.styled('⚠️ ' + L('Aylık limit aşıldı!', 'Monthly limit exceeded!'), { color: tui.PALETTE.danger, bold: true }));
|
|
98
|
+
else if (status.monthly.warning) console.log(' ' + tui.styled('⚠️ ' + L(`%${(budget.warnAt * 100)} eşiğine yaklaşıldı`, `approaching the ${(budget.warnAt * 100)}% threshold`), { color: tui.PALETTE.warning }));
|
|
96
99
|
|
|
97
100
|
if (status.shouldDowngrade) {
|
|
98
|
-
console.log('\n' + tui.styled(' ⬇️ Otomatik downgrade önerilir — basit soruları ucuz modele yönlendir.', { color: tui.PALETTE.warning, bold: true }));
|
|
101
|
+
console.log('\n' + tui.styled(' ⬇️ ' + L('Otomatik downgrade önerilir — basit soruları ucuz modele yönlendir.', 'Auto-downgrade recommended — route simple questions to a cheaper model.'), { color: tui.PALETTE.warning, bold: true }));
|
|
99
102
|
}
|
|
100
103
|
|
|
101
|
-
console.log('\n' + tui.C.muted(' Ayarlamak için: ') + tui.C.brand('natureco cost set <key> <value>'));
|
|
104
|
+
console.log('\n' + tui.C.muted(' ' + L('Ayarlamak için: ', 'To configure: ')) + tui.C.brand('natureco cost set <key> <value>'));
|
|
102
105
|
console.log('');
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
function setBudget(args) {
|
|
106
109
|
const [key, value] = args;
|
|
107
110
|
if (!key || value === undefined) {
|
|
108
|
-
console.log(chalk.red('\n Kullanım: natureco cost set <key> <value
|
|
109
|
-
console.log(chalk.gray(' Anahtarlar: dailyLimit, monthlyLimit, warnAt, downgradeAt'));
|
|
110
|
-
console.log(chalk.gray(' Örnek: natureco cost set dailyLimit 3.00'));
|
|
111
|
+
console.log(chalk.red('\n ' + L('Kullanım: natureco cost set <key> <value>', 'Usage: natureco cost set <key> <value>') + '\n'));
|
|
112
|
+
console.log(chalk.gray(' ' + L('Anahtarlar: dailyLimit, monthlyLimit, warnAt, downgradeAt', 'Keys: dailyLimit, monthlyLimit, warnAt, downgradeAt')));
|
|
113
|
+
console.log(chalk.gray(' ' + L('Örnek: natureco cost set dailyLimit 3.00', 'Example: natureco cost set dailyLimit 3.00')));
|
|
111
114
|
console.log('');
|
|
112
115
|
return;
|
|
113
116
|
}
|
|
114
117
|
const budget = cost.loadBudget();
|
|
115
118
|
const num = parseFloat(value);
|
|
116
119
|
if (isNaN(num) && key !== 'preset') {
|
|
117
|
-
console.log(chalk.red(`\n Geçersiz
|
|
120
|
+
console.log(chalk.red(`\n ${L('Geçersiz sayı', 'Invalid number')}: ${value}\n`));
|
|
118
121
|
return;
|
|
119
122
|
}
|
|
120
123
|
budget[key] = num;
|
|
@@ -126,25 +129,25 @@ function setBudget(args) {
|
|
|
126
129
|
function suggestModel(args) {
|
|
127
130
|
const prompt = args.join(' ');
|
|
128
131
|
if (!prompt) {
|
|
129
|
-
console.log(chalk.red('\n Kullanım: natureco cost model "<prompt>"\n'));
|
|
132
|
+
console.log(chalk.red('\n ' + L('Kullanım: natureco cost model "<prompt>"', 'Usage: natureco cost model "<prompt>"') + '\n'));
|
|
130
133
|
return;
|
|
131
134
|
}
|
|
132
135
|
const suggestion = cost.suggestModel(prompt);
|
|
133
136
|
if (!suggestion) return;
|
|
134
137
|
|
|
135
|
-
console.log(chalk.bold('\n 🎯 Model Önerisi\n'));
|
|
136
|
-
console.log(chalk.gray(' Prompt karmaşıklığı: ') + chalk.cyan(suggestion.complexity));
|
|
138
|
+
console.log(chalk.bold('\n 🎯 ' + L('Model Önerisi', 'Model Suggestion') + '\n'));
|
|
139
|
+
console.log(chalk.gray(' ' + L('Prompt karmaşıklığı: ', 'Prompt complexity: ')) + chalk.cyan(suggestion.complexity));
|
|
137
140
|
console.log(chalk.gray(` ${cost.ROUTING[suggestion.complexity].description}\n`));
|
|
138
|
-
console.log(chalk.gray(' Önerilen model: ') + chalk.bold(`${suggestion.provider}:${suggestion.model}`));
|
|
139
|
-
console.log(chalk.gray(' Neden: ') + chalk.gray(suggestion.reason));
|
|
141
|
+
console.log(chalk.gray(' ' + L('Önerilen model: ', 'Suggested model: ')) + chalk.bold(`${suggestion.provider}:${suggestion.model}`));
|
|
142
|
+
console.log(chalk.gray(' ' + L('Neden: ', 'Reason: ')) + chalk.gray(suggestion.reason));
|
|
140
143
|
|
|
141
144
|
const pricing = cost.getPricing(suggestion.provider, suggestion.model);
|
|
142
|
-
console.log(chalk.gray(' Fiyat: ') + chalk.cyan(`${cost.formatUSD(pricing.input)} in / ${cost.formatUSD(pricing.output)} out (per 1M)`));
|
|
145
|
+
console.log(chalk.gray(' ' + L('Fiyat: ', 'Price: ')) + chalk.cyan(`${cost.formatUSD(pricing.input)} in / ${cost.formatUSD(pricing.output)} out (per 1M)`));
|
|
143
146
|
|
|
144
147
|
if (suggestion.optimal) {
|
|
145
|
-
console.log(chalk.green('\n ✓ Mevcut model zaten optimal
|
|
148
|
+
console.log(chalk.green('\n ✓ ' + L('Mevcut model zaten optimal.', 'Current model is already optimal.') + '\n'));
|
|
146
149
|
} else {
|
|
147
|
-
console.log(chalk.yellow('\n ⚠️ Mevcut model optimal değil. Değiştirmek için:'));
|
|
150
|
+
console.log(chalk.yellow('\n ⚠️ ' + L('Mevcut model optimal değil. Değiştirmek için:', 'Current model is not optimal. To change it:')));
|
|
148
151
|
console.log(chalk.cyan(` natureco config set providerUrl <url>`));
|
|
149
152
|
console.log(chalk.cyan(` natureco config set providerModel ${suggestion.model}`));
|
|
150
153
|
console.log('');
|
|
@@ -152,10 +155,10 @@ function suggestModel(args) {
|
|
|
152
155
|
}
|
|
153
156
|
|
|
154
157
|
function showPrices() {
|
|
155
|
-
console.log(chalk.bold('\n 💵 Model Fiyatları (USD / 1M token)\n'));
|
|
158
|
+
console.log(chalk.bold('\n 💵 ' + L('Model Fiyatları (USD / 1M token)', 'Model Prices (USD / 1M tokens)') + '\n'));
|
|
156
159
|
console.log(chalk.gray(' ' + '─'.repeat(60)));
|
|
157
160
|
|
|
158
|
-
//
|
|
161
|
+
// Group by provider
|
|
159
162
|
const grouped = {};
|
|
160
163
|
for (const [key, price] of Object.entries(cost.PRICING)) {
|
|
161
164
|
const [provider] = key.split(':');
|
|
@@ -166,8 +169,8 @@ function showPrices() {
|
|
|
166
169
|
for (const [provider, models] of Object.entries(grouped)) {
|
|
167
170
|
console.log(chalk.bold(`\n ${provider.toUpperCase()}`));
|
|
168
171
|
for (const m of models) {
|
|
169
|
-
const inPrice = m.input === 0 ? chalk.green('ücretsiz') : cost.formatUSD(m.input);
|
|
170
|
-
const outPrice = m.output === 0 ? chalk.green('ücretsiz') : cost.formatUSD(m.output);
|
|
172
|
+
const inPrice = m.input === 0 ? chalk.green(L('ücretsiz', 'free')) : cost.formatUSD(m.input);
|
|
173
|
+
const outPrice = m.output === 0 ? chalk.green(L('ücretsiz', 'free')) : cost.formatUSD(m.output);
|
|
171
174
|
console.log(` ${m.model.padEnd(40)} ${inPrice.padStart(10)} in ${outPrice.padStart(10)} out`);
|
|
172
175
|
}
|
|
173
176
|
}
|
|
@@ -194,16 +197,16 @@ function cost_cmd(args) {
|
|
|
194
197
|
|
|
195
198
|
if (action === 'prices') { showPrices(); return; }
|
|
196
199
|
|
|
197
|
-
//
|
|
198
|
-
console.log(chalk.yellow('\n Kullanım:'));
|
|
199
|
-
console.log(chalk.gray(' natureco cost Bugünün maliyeti'));
|
|
200
|
-
console.log(chalk.gray(' natureco cost week Bu hafta'));
|
|
201
|
-
console.log(chalk.gray(' natureco cost month Bu ay'));
|
|
202
|
-
console.log(chalk.gray(' natureco cost all Tüm zamanlar'));
|
|
203
|
-
console.log(chalk.gray(' natureco cost budget Bütçe durumu'));
|
|
204
|
-
console.log(chalk.gray(' natureco cost set <k> <v> Bütçe ayarla'));
|
|
205
|
-
console.log(chalk.gray(' natureco cost model "<p>" Model önerisi'));
|
|
206
|
-
console.log(chalk.gray(' natureco cost prices Fiyat listesi'));
|
|
200
|
+
// Help
|
|
201
|
+
console.log(chalk.yellow('\n ' + L('Kullanım:', 'Usage:')));
|
|
202
|
+
console.log(chalk.gray(' natureco cost ' + L('Bugünün maliyeti', "Today's cost")));
|
|
203
|
+
console.log(chalk.gray(' natureco cost week ' + L('Bu hafta', 'This week')));
|
|
204
|
+
console.log(chalk.gray(' natureco cost month ' + L('Bu ay', 'This month')));
|
|
205
|
+
console.log(chalk.gray(' natureco cost all ' + L('Tüm zamanlar', 'All time')));
|
|
206
|
+
console.log(chalk.gray(' natureco cost budget ' + L('Bütçe durumu', 'Budget status')));
|
|
207
|
+
console.log(chalk.gray(' natureco cost set <k> <v> ' + L('Bütçe ayarla', 'Set a budget')));
|
|
208
|
+
console.log(chalk.gray(' natureco cost model "<p>" ' + L('Model önerisi', 'Model suggestion')));
|
|
209
|
+
console.log(chalk.gray(' natureco cost prices ' + L('Fiyat listesi', 'Price list')));
|
|
207
210
|
console.log('');
|
|
208
211
|
}
|
|
209
212
|
|