natureco-cli 2.23.32 → 4.4.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/AUDIT.md +178 -0
- package/CHANGELOG.md +422 -0
- package/DEPLOY_v2.0.0.md +400 -0
- package/README.md +159 -1
- package/bin/natureco.js +170 -8
- package/package.json +43 -11
- package/skills/code-review/SKILL.md +0 -0
- package/skills/summarize/SKILL.md +0 -0
- package/skills/translate/SKILL.md +0 -0
- package/src/commands/acp.js +0 -0
- package/src/commands/admin-rpc.js +0 -0
- package/src/commands/agent.js +0 -0
- package/src/commands/agents.js +0 -0
- package/src/commands/approvals.js +0 -0
- package/src/commands/ask.js +0 -0
- package/src/commands/audit.js +209 -0
- package/src/commands/backup.js +0 -0
- package/src/commands/bonjour.js +0 -0
- package/src/commands/bots.js +0 -0
- package/src/commands/browser.js +0 -0
- package/src/commands/capability.js +0 -0
- package/src/commands/channels.js +0 -0
- package/src/commands/chat.js +0 -0
- package/src/commands/clawbot.js +0 -0
- package/src/commands/clickclack.js +0 -0
- package/src/commands/code.js +0 -0
- package/src/commands/commands.js +0 -0
- package/src/commands/commitments.js +0 -0
- package/src/commands/completion.js +0 -0
- package/src/commands/config.js +0 -0
- package/src/commands/configure.js +0 -0
- package/src/commands/cost.js +210 -0
- package/src/commands/crestodian.js +0 -0
- package/src/commands/cron.js +0 -0
- package/src/commands/daemon.js +0 -0
- package/src/commands/dashboard.js +126 -45
- package/src/commands/device-pair.js +0 -0
- package/src/commands/devices.js +0 -0
- package/src/commands/directory.js +0 -0
- package/src/commands/discord.js +0 -0
- package/src/commands/dns.js +0 -0
- package/src/commands/docs.js +0 -0
- package/src/commands/doctor.js +134 -15
- package/src/commands/exec-policy.js +0 -0
- package/src/commands/gateway-server.js +0 -0
- package/src/commands/gateway.js +0 -0
- package/src/commands/git.js +0 -0
- package/src/commands/health.js +0 -0
- package/src/commands/help.js +0 -0
- package/src/commands/hooks.js +0 -0
- package/src/commands/imessage.js +0 -0
- package/src/commands/infer.js +0 -0
- package/src/commands/init.js +0 -0
- package/src/commands/irc.js +0 -0
- package/src/commands/login.js +0 -0
- package/src/commands/logout.js +0 -0
- package/src/commands/logs.js +0 -0
- package/src/commands/mattermost.js +0 -0
- package/src/commands/mcp.js +0 -0
- package/src/commands/medium.js +206 -0
- package/src/commands/memory-cmd.js +0 -0
- package/src/commands/memory.js +0 -0
- package/src/commands/message.js +0 -0
- package/src/commands/migrate.js +0 -0
- package/src/commands/models.js +0 -0
- package/src/commands/naturehub.js +156 -0
- package/src/commands/node.js +0 -0
- package/src/commands/nodes.js +0 -0
- package/src/commands/oc-path.js +0 -0
- package/src/commands/onboard.js +0 -0
- package/src/commands/open-prose.js +0 -0
- package/src/commands/pairing.js +0 -0
- package/src/commands/path.js +0 -0
- package/src/commands/plugins.js +0 -0
- package/src/commands/policy.js +0 -0
- package/src/commands/proxy.js +0 -0
- package/src/commands/qr.js +0 -0
- package/src/commands/reset.js +0 -0
- package/src/commands/run.js +0 -0
- package/src/commands/sandbox.js +0 -0
- package/src/commands/secrets.js +0 -0
- package/src/commands/security.js +0 -0
- package/src/commands/seo.js +268 -0
- package/src/commands/sessions.js +0 -0
- package/src/commands/setup.js +6 -6
- package/src/commands/signal.js +0 -0
- package/src/commands/skills.js +82 -1
- package/src/commands/slack.js +0 -0
- package/src/commands/sms.js +0 -0
- package/src/commands/status.js +0 -0
- package/src/commands/system.js +0 -0
- package/src/commands/tasks.js +0 -0
- package/src/commands/team.js +171 -0
- package/src/commands/telegram.js +0 -0
- package/src/commands/terminal.js +0 -0
- package/src/commands/thread-ownership.js +0 -0
- package/src/commands/transcripts.js +0 -0
- package/src/commands/tui.js +0 -0
- package/src/commands/ultrareview.js +0 -0
- package/src/commands/uninstall.js +0 -0
- package/src/commands/update.js +0 -0
- package/src/commands/voice.js +0 -0
- package/src/commands/vydra.js +0 -0
- package/src/commands/web-fetch.js +0 -0
- package/src/commands/webhooks.js +0 -0
- package/src/commands/whatsapp.js +0 -0
- package/src/commands/wiki.js +0 -0
- package/src/commands/workboard.js +0 -0
- package/src/commands/xp.js +194 -0
- package/src/tools/audio_understanding.js +0 -0
- package/src/tools/bash.js +0 -0
- package/src/tools/browser.js +0 -0
- package/src/tools/canvas.js +0 -0
- package/src/tools/document_extract.js +0 -0
- package/src/tools/duckduckgo.js +0 -0
- package/src/tools/exa_search.js +0 -0
- package/src/tools/filesystem.js +0 -0
- package/src/tools/firecrawl.js +0 -0
- package/src/tools/git.js +0 -0
- package/src/tools/http.js +0 -0
- package/src/tools/image_generation.js +0 -0
- package/src/tools/list_dir.js +0 -0
- package/src/tools/llm_task.js +43 -11
- package/src/tools/media_understanding.js +0 -0
- package/src/tools/music_generation.js +0 -0
- package/src/tools/parallel_search.js +0 -0
- package/src/tools/phone_control.js +0 -0
- package/src/tools/phone_control_enhanced.js +0 -0
- package/src/tools/read_file.js +0 -0
- package/src/tools/searxng.js +0 -0
- package/src/tools/speech_to_text.js +0 -0
- package/src/tools/text_to_speech.js +0 -0
- package/src/tools/thread_ownership.js +0 -0
- package/src/tools/video_generation.js +0 -0
- package/src/tools/web_readability.js +0 -0
- package/src/tools/web_search.js +0 -0
- package/src/tools/write_file.js +0 -0
- package/src/utils/agents-md.js +0 -0
- package/src/utils/agents.js +0 -0
- package/src/utils/api.js +5 -1
- package/src/utils/approvals.js +0 -0
- package/src/utils/audit.js +199 -0
- package/src/utils/background.js +0 -0
- package/src/utils/baileys.js +0 -0
- package/src/utils/branding.js +136 -0
- package/src/utils/commands.js +0 -0
- package/src/utils/config.js +0 -0
- package/src/utils/cost-tracker.js +360 -0
- package/src/utils/cron.js +0 -0
- package/src/utils/dashboard-server.js +284 -0
- package/src/utils/errors.js +0 -0
- package/src/utils/format.js +7 -10
- package/src/utils/gateway-ws.js +0 -0
- package/src/utils/headless.js +0 -0
- package/src/utils/history.js +0 -0
- package/src/utils/hooks.js +0 -0
- package/src/utils/inquirer-wrapper.js +0 -0
- package/src/utils/mcp-client.js +0 -0
- package/src/utils/mcp.js +0 -0
- package/src/utils/memory.js +0 -0
- package/src/utils/parallel-tools.js +0 -0
- package/src/utils/path-utils.js +0 -0
- package/src/utils/pattern-detector.js +314 -0
- package/src/utils/plugin-registry.js +0 -0
- package/src/utils/secret-scanner.js +204 -0
- package/src/utils/secrets.js +0 -0
- package/src/utils/sessions.js +0 -0
- package/src/utils/skills.js +0 -0
- package/src/utils/sub-agent.js +6 -0
- package/src/utils/token-budget.js +0 -0
- package/src/utils/tool-adapter.js +0 -0
- package/src/utils/tool-runner.js +0 -0
- package/src/utils/tui.js +750 -0
- package/src/utils/web-fetch.js +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* natureco xp — NatureCo XP/Level sistemi (Phase 6)
|
|
3
|
+
*
|
|
4
|
+
* Parton'un hedeflerinden biri: kullanıcıları ödüllendirmek.
|
|
5
|
+
* XP kazanma yolları:
|
|
6
|
+
* - Komut çalıştırma (1 XP)
|
|
7
|
+
* - Audit log kaydı (0.1 XP)
|
|
8
|
+
* - Skill kabul etme (5 XP)
|
|
9
|
+
* - Bir bug raporlama (10 XP)
|
|
10
|
+
* - Haftalık aktif kullanım (50 XP bonus)
|
|
11
|
+
*
|
|
12
|
+
* Kullanım:
|
|
13
|
+
* natureco xp Mevcut durum
|
|
14
|
+
* natureco xp stats Detaylı istatistikler
|
|
15
|
+
* natureco xp leaderboard Top kullanıcılar
|
|
16
|
+
* natureco xp rewards Aktif ödüller
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const chalk = require('chalk');
|
|
20
|
+
const tui = require('../utils/tui');
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const os = require('os');
|
|
24
|
+
|
|
25
|
+
const XP_FILE = path.join(os.homedir(), '.natureco', 'xp.json');
|
|
26
|
+
const LEVELS = [
|
|
27
|
+
{ level: 1, minXP: 0, title: '🌱 Tohum', color: chalk.green },
|
|
28
|
+
{ level: 2, minXP: 100, title: '🌿 Filiz', color: chalk.green },
|
|
29
|
+
{ level: 3, minXP: 300, title: '🍃 Yaprak', color: chalk.cyan },
|
|
30
|
+
{ level: 4, minXP: 700, title: '🌳 Ağaç', color: chalk.blue },
|
|
31
|
+
{ level: 5, minXP: 1500, title: '🌲 Orman', color: chalk.yellow },
|
|
32
|
+
{ level: 6, minXP: 3000, title: '🏔️ Dağ', color: chalk.magenta },
|
|
33
|
+
{ level: 7, minXP: 6000, title: '⭐ Yıldız', color: chalk.red.bold },
|
|
34
|
+
{ level: 8, minXP: 12000,title: '🌌 Galaksi', color: chalk.hex('#a78bfa').bold },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
function loadXP() {
|
|
38
|
+
try {
|
|
39
|
+
if (fs.existsSync(XP_FILE)) return JSON.parse(fs.readFileSync(XP_FILE, 'utf8'));
|
|
40
|
+
} catch {}
|
|
41
|
+
return { xp: 0, history: [], username: os.userInfo().username };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function saveXP(data) {
|
|
45
|
+
const dir = path.dirname(XP_FILE);
|
|
46
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
47
|
+
fs.writeFileSync(XP_FILE, JSON.stringify(data, null, 2), 'utf8');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getLevel(xp) {
|
|
51
|
+
let current = LEVELS[0];
|
|
52
|
+
for (const lv of LEVELS) {
|
|
53
|
+
if (xp >= lv.minXP) current = lv;
|
|
54
|
+
}
|
|
55
|
+
return current;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function getNextLevel(xp) {
|
|
59
|
+
for (const lv of LEVELS) {
|
|
60
|
+
if (lv.minXP > xp) return lv;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function addXP(amount, reason) {
|
|
66
|
+
const data = loadXP();
|
|
67
|
+
data.xp += amount;
|
|
68
|
+
data.history.push({ ts: new Date().toISOString(), amount, reason });
|
|
69
|
+
// Son 100 history tut
|
|
70
|
+
if (data.history.length > 100) data.history = data.history.slice(-100);
|
|
71
|
+
saveXP(data);
|
|
72
|
+
return data;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function cmdStatus() {
|
|
76
|
+
const data = loadXP();
|
|
77
|
+
const current = getLevel(data.xp);
|
|
78
|
+
const next = getNextLevel(data.xp);
|
|
79
|
+
|
|
80
|
+
console.log('\n' + tui.styled(' ⭐ NatureCo XP Sistemi', { color: tui.PALETTE.accent, bold: true }));
|
|
81
|
+
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
82
|
+
|
|
83
|
+
// Üst metrik kartı
|
|
84
|
+
const w = 50;
|
|
85
|
+
const lines = [];
|
|
86
|
+
lines.push(tui.styled(' ╭' + '─'.repeat(w) + '╮', { color: tui.PALETTE.border }));
|
|
87
|
+
lines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('Kullanıcı ') + tui.styled(data.username.padEnd(20), { color: tui.PALETTE.text, bold: true }) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
88
|
+
lines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('XP ') + tui.styled(data.xp.toLocaleString().padStart(8), { color: tui.PALETTE.primary, bold: true }) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
89
|
+
lines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('Seviye ') + current.color(`Lv.${current.level} ${current.title}`.padEnd(20)) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
90
|
+
lines.push(tui.styled(' ╰' + '─'.repeat(w) + '╯', { color: tui.PALETTE.border }));
|
|
91
|
+
console.log(lines.join('\n'));
|
|
92
|
+
|
|
93
|
+
if (next) {
|
|
94
|
+
const needed = next.minXP - data.xp;
|
|
95
|
+
const progress = ((data.xp - current.minXP) / (next.minXP - current.minXP)) * 100;
|
|
96
|
+
const filled = Math.floor(progress / 5);
|
|
97
|
+
const bar = tui.progressBar(data.xp - current.minXP, next.minXP - current.minXP, {
|
|
98
|
+
width: 40, showPercent: true,
|
|
99
|
+
});
|
|
100
|
+
console.log('\n ' + tui.C.muted('Sonraki: ') + next.color(`${next.title}`) + tui.C.muted(` (${needed} XP kaldı)`));
|
|
101
|
+
console.log(' ' + bar);
|
|
102
|
+
} else {
|
|
103
|
+
console.log('\n ' + tui.styled(' 🌟 Maksimum seviye!', { color: tui.PALETTE.success, bold: true }));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Son kazanımlar — TUI tablo
|
|
107
|
+
if (data.history.length > 0) {
|
|
108
|
+
console.log('\n' + tui.styled(' 📜 Son XP Kazanımları', { color: tui.PALETTE.secondary, bold: true }));
|
|
109
|
+
const rows = data.history.slice(-5).reverse().map(h => ({
|
|
110
|
+
amount: (h.amount > 0 ? '+' : '') + h.amount,
|
|
111
|
+
ts: new Date(h.ts).toLocaleString(),
|
|
112
|
+
reason: h.reason,
|
|
113
|
+
}));
|
|
114
|
+
console.log('\n' + tui.table(rows, [
|
|
115
|
+
{ key: 'amount', label: 'XP', minWidth: 8, render: r => tui.styled(r.amount, { color: r.amount.startsWith('+') ? tui.PALETTE.success : tui.PALETTE.danger, bold: true }) },
|
|
116
|
+
{ key: 'ts', label: 'Zaman', minWidth: 22, render: r => tui.C.muted(r.ts) },
|
|
117
|
+
{ key: 'reason', label: 'Sebep', minWidth: 30, render: r => tui.C.text(r.reason) },
|
|
118
|
+
], { borderStyle: 'round', zebra: true }));
|
|
119
|
+
}
|
|
120
|
+
console.log('');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function cmdStats() {
|
|
124
|
+
const data = loadXP();
|
|
125
|
+
console.log(chalk.bold('\n 📊 XP İstatistikleri\n'));
|
|
126
|
+
console.log(chalk.gray(' Toplam XP: ') + chalk.cyan(data.xp.toLocaleString()));
|
|
127
|
+
console.log(chalk.gray(' Toplam kayıt: ') + chalk.cyan(data.history.length));
|
|
128
|
+
|
|
129
|
+
// Reason bazlı
|
|
130
|
+
const byReason = {};
|
|
131
|
+
for (const h of data.history) {
|
|
132
|
+
byReason[h.reason] = (byReason[h.reason] || 0) + h.amount;
|
|
133
|
+
}
|
|
134
|
+
if (Object.keys(byReason).length > 0) {
|
|
135
|
+
console.log(chalk.bold('\n 🏷️ Kaynak Bazlı XP:\n'));
|
|
136
|
+
for (const [reason, amount] of Object.entries(byReason).sort((a, b) => b[1] - a[1])) {
|
|
137
|
+
console.log(` ${reason.padEnd(30)} ${chalk.cyan((amount > 0 ? '+' : '') + amount)} XP`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
console.log('');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function cmdLeaderboard() {
|
|
144
|
+
console.log(chalk.cyan('\n 🏆 Liderlik Tablosu\n'));
|
|
145
|
+
console.log(chalk.gray(' Bu özellik api.natureco.me hazır olunca tam çalışacak.\n'));
|
|
146
|
+
console.log(chalk.gray(' Şimdilik senin sıralaman local XP dosyanda.\n'));
|
|
147
|
+
cmdStatus();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function cmdRewards() {
|
|
151
|
+
console.log('\n' + tui.styled(' 🎁 Aktif Ödüller', { color: tui.PALETTE.accent, bold: true }));
|
|
152
|
+
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
153
|
+
|
|
154
|
+
const rows = [
|
|
155
|
+
{ level: 'Lv.2', xp: '100 XP', reward: 'NatureCo sticker paketi', color: tui.PALETTE.success },
|
|
156
|
+
{ level: 'Lv.3', xp: '300 XP', reward: 'NatureBot\'ta özel bot erişimi', color: tui.PALETTE.success },
|
|
157
|
+
{ level: 'Lv.4', xp: '700 XP', reward: 'Medium\'da otomatik yayınlama', color: tui.PALETTE.secondary },
|
|
158
|
+
{ level: 'Lv.5', xp: '1500 XP', reward: 'NatureCo Pro ayda 1 ay ücretsiz', color: tui.PALETTE.secondary },
|
|
159
|
+
{ level: 'Lv.6', xp: '3000 XP', reward: 'Özel NatureCo rozeti', color: tui.PALETTE.accent },
|
|
160
|
+
{ level: 'Lv.7', xp: '6000 XP', reward: '@Naturecofficial\'dan mention', color: tui.PALETTE.warning },
|
|
161
|
+
{ level: 'Lv.8', xp: '12000 XP', reward: 'Founder statüsü (sınırlı)', color: tui.PALETTE.danger },
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
console.log('\n' + tui.table(rows, [
|
|
165
|
+
{ key: 'level', label: 'Seviye', minWidth: 8, render: r => tui.styled(r.level, { color: r.color, bold: true }) },
|
|
166
|
+
{ key: 'xp', label: 'Eşik', minWidth: 10, render: r => tui.C.brand(r.xp) },
|
|
167
|
+
{ key: 'reward', label: 'Ödül', minWidth: 35, render: r => tui.C.text(r.reward) },
|
|
168
|
+
], { borderStyle: 'round', zebra: true }));
|
|
169
|
+
console.log('');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function xp(args) {
|
|
173
|
+
const [action] = args || [];
|
|
174
|
+
if (!action) return cmdStatus();
|
|
175
|
+
if (action === 'stats') return cmdStats();
|
|
176
|
+
if (action === 'leaderboard') return cmdLeaderboard();
|
|
177
|
+
if (action === 'rewards') return cmdRewards();
|
|
178
|
+
if (action === 'help') {
|
|
179
|
+
console.log(chalk.yellow('\n Kullanım:'));
|
|
180
|
+
console.log(chalk.gray(' natureco xp Mevcut durum'));
|
|
181
|
+
console.log(chalk.gray(' natureco xp stats İstatistikler'));
|
|
182
|
+
console.log(chalk.gray(' natureco xp leaderboard Liderlik'));
|
|
183
|
+
console.log(chalk.gray(' natureco xp rewards Aktif ödüller'));
|
|
184
|
+
console.log('');
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
console.log(chalk.red(`\n Bilinmeyen: ${action}\n`));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Export addXP — diğer modüller XP kazandırabilsin
|
|
191
|
+
xp.addXP = addXP;
|
|
192
|
+
xp.getXP = () => loadXP().xp;
|
|
193
|
+
|
|
194
|
+
module.exports = xp;
|
|
File without changes
|
package/src/tools/bash.js
CHANGED
|
File without changes
|
package/src/tools/browser.js
CHANGED
|
File without changes
|
package/src/tools/canvas.js
CHANGED
|
File without changes
|
|
File without changes
|
package/src/tools/duckduckgo.js
CHANGED
|
File without changes
|
package/src/tools/exa_search.js
CHANGED
|
File without changes
|
package/src/tools/filesystem.js
CHANGED
|
File without changes
|
package/src/tools/firecrawl.js
CHANGED
|
File without changes
|
package/src/tools/git.js
CHANGED
|
File without changes
|
package/src/tools/http.js
CHANGED
|
File without changes
|
|
File without changes
|
package/src/tools/list_dir.js
CHANGED
|
File without changes
|
package/src/tools/llm_task.js
CHANGED
|
@@ -38,8 +38,9 @@ module.exports = {
|
|
|
38
38
|
schema: { type: 'object', description: 'Optional JSON Schema to validate the returned JSON' },
|
|
39
39
|
provider: { type: 'string', description: 'Provider override (e.g. openai, anthropic)' },
|
|
40
40
|
model: { type: 'string', description: 'Model override' },
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
// LLM'ler JSON'da sayıları string olarak dönebiliyor — esnek schema
|
|
42
|
+
temperature: { type: ['number', 'string'], description: 'Temperature override' },
|
|
43
|
+
maxTokens: { type: ['number', 'string'], description: 'Max tokens override' }
|
|
43
44
|
},
|
|
44
45
|
required: ['prompt']
|
|
45
46
|
},
|
|
@@ -50,13 +51,21 @@ module.exports = {
|
|
|
50
51
|
const provider = params.provider || config.provider || 'openai';
|
|
51
52
|
const model = params.model || config.model || 'gpt-4o';
|
|
52
53
|
|
|
54
|
+
// LLM'ler sayıları string olarak dönebiliyor — cast et
|
|
55
|
+
const temperature = typeof params.temperature === 'string' ? parseFloat(params.temperature) : (params.temperature ?? 0.1);
|
|
56
|
+
const maxTokens = typeof params.maxTokens === 'string' ? parseInt(params.maxTokens, 10) : (params.maxTokens ?? 4096);
|
|
57
|
+
|
|
53
58
|
let apiKey;
|
|
54
59
|
if (provider === 'openai') apiKey = params.apiKey || config.openaiApiKey || process.env.OPENAI_API_KEY;
|
|
55
60
|
else if (provider === 'anthropic') apiKey = params.apiKey || config.anthropicApiKey || process.env.ANTHROPIC_API_KEY;
|
|
56
61
|
else if (provider === 'groq') apiKey = params.apiKey || config.groqApiKey || process.env.GROQ_API_KEY;
|
|
62
|
+
else if (provider === 'groq' || provider === 'together' || provider === 'openrouter') {
|
|
63
|
+
// Yeni provider presetler için ana providerApiKey'i kullan
|
|
64
|
+
apiKey = config.providerApiKey;
|
|
65
|
+
}
|
|
57
66
|
|
|
58
67
|
if (!apiKey) {
|
|
59
|
-
return { success: false, error: `API key required for ${provider}. Set: natureco config set ${provider}ApiKey <key
|
|
68
|
+
return { success: false, error: `API key required for ${provider}. Set: natureco config set ${provider}ApiKey <key> veya providerApiKey` };
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
const systemPrompt = [
|
|
@@ -70,15 +79,37 @@ module.exports = {
|
|
|
70
79
|
const inputJson = JSON.stringify(params.input ?? null, null, 2);
|
|
71
80
|
const fullPrompt = `${systemPrompt}\n\nTASK:\n${params.prompt}\n\nINPUT:\n${inputJson}\n`;
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
// Provider URL'ini config'ten al (Groq, MiniMax, OpenRouter için)
|
|
83
|
+
let baseUrl = provider === 'openai' ? 'https://api.openai.com/v1' : `https://api.${provider}.com/v1`;
|
|
84
|
+
if (provider === 'groq') baseUrl = config.providerUrl || 'https://api.groq.com/openai/v1';
|
|
85
|
+
if (provider === 'openrouter') baseUrl = 'https://openrouter.ai/api/v1';
|
|
86
|
+
// MiniMax özel endpoint: /v1/text/chatcompletion_v2 (OpenAI uyumlu DEĞİL)
|
|
87
|
+
if (provider === 'minimax') {
|
|
88
|
+
baseUrl = config.providerUrl || 'https://api.minimax.io';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// MiniMax özel mi, OpenAI uyumlu mu?
|
|
92
|
+
const isMiniMax = provider === 'minimax' || baseUrl.includes('minimax.io') || baseUrl.includes('minimaxi.com');
|
|
93
|
+
const endpoint = isMiniMax
|
|
94
|
+
? `${baseUrl}/v1/text/chatcompletion_v2`
|
|
95
|
+
: `${baseUrl}/chat/completions`;
|
|
96
|
+
|
|
97
|
+
// MiniMax özel request format
|
|
98
|
+
const requestBody = isMiniMax
|
|
99
|
+
? {
|
|
100
|
+
model,
|
|
101
|
+
messages: [{ role: 'user', content: fullPrompt }],
|
|
102
|
+
temperature,
|
|
103
|
+
max_tokens: maxTokens,
|
|
104
|
+
}
|
|
105
|
+
: {
|
|
106
|
+
model,
|
|
107
|
+
messages: [{ role: 'user', content: fullPrompt }],
|
|
108
|
+
temperature,
|
|
109
|
+
max_tokens: maxTokens
|
|
110
|
+
};
|
|
80
111
|
|
|
81
|
-
const response = await fetch(
|
|
112
|
+
const response = await fetch(endpoint, {
|
|
82
113
|
method: 'POST',
|
|
83
114
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },
|
|
84
115
|
body: JSON.stringify(requestBody)
|
|
@@ -89,6 +120,7 @@ module.exports = {
|
|
|
89
120
|
}
|
|
90
121
|
|
|
91
122
|
const data = await response.json();
|
|
123
|
+
// MiniMax response format: choices[0].message.content (OpenAI ile aynı)
|
|
92
124
|
const text = data.choices?.[0]?.message?.content?.trim();
|
|
93
125
|
if (!text) return { success: false, error: 'LLM returned empty output' };
|
|
94
126
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/tools/read_file.js
CHANGED
|
File without changes
|
package/src/tools/searxng.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/tools/web_search.js
CHANGED
|
File without changes
|
package/src/tools/write_file.js
CHANGED
|
File without changes
|
package/src/utils/agents-md.js
CHANGED
|
File without changes
|
package/src/utils/agents.js
CHANGED
|
File without changes
|
package/src/utils/api.js
CHANGED
|
@@ -430,7 +430,11 @@ function formatToolsForAnthropic() {
|
|
|
430
430
|
*/
|
|
431
431
|
async function sendMessageOpenAICompatible(providerConfig, messages, tools) {
|
|
432
432
|
const baseUrl = providerConfig.url.replace(/\/+$/, '');
|
|
433
|
-
|
|
433
|
+
// MiniMax özel endpoint tespiti
|
|
434
|
+
const isMiniMax = baseUrl.includes('minimax.io') || baseUrl.includes('minimaxi.com') || baseUrl.includes('minimax.cn');
|
|
435
|
+
const endpoint = isMiniMax
|
|
436
|
+
? `${baseUrl}/v1/text/chatcompletion_v2`
|
|
437
|
+
: `${baseUrl}/chat/completions`;
|
|
434
438
|
const requestBody = {
|
|
435
439
|
model: providerConfig.model,
|
|
436
440
|
messages: messages,
|
package/src/utils/approvals.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NatureCo CLI — Audit Log (Phase 2)
|
|
3
|
+
*
|
|
4
|
+
* Tüm kullanıcı işlemlerini (komut, onay, tool call, hata) JSONL olarak kaydeder.
|
|
5
|
+
* Bu log güvenlik denetimi, hata ayıklama ve compliance için kullanılır.
|
|
6
|
+
*
|
|
7
|
+
* Format: Her satır bir JSON objesi. Sıralı append, async-non-blocking.
|
|
8
|
+
*
|
|
9
|
+
* Varsayılan: ~/.natureco/audit/audit-YYYY-MM-DD.jsonl
|
|
10
|
+
* 30 günden eski loglar otomatik temizlenir.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const os = require('os');
|
|
16
|
+
|
|
17
|
+
const AUDIT_DIR = path.join(os.homedir(), '.natureco', 'audit');
|
|
18
|
+
const RETENTION_DAYS = 30;
|
|
19
|
+
|
|
20
|
+
// Action tipleri
|
|
21
|
+
const ACTIONS = {
|
|
22
|
+
COMMAND_RUN: 'command.run', // Bir CLI komutu çalıştırıldı
|
|
23
|
+
COMMAND_FAIL: 'command.fail', // Komut hata verdi
|
|
24
|
+
APPROVAL_ASK: 'approval.ask', // Onay istendi
|
|
25
|
+
APPROVAL_GRANT: 'approval.grant', // Kullanıcı onayladı
|
|
26
|
+
APPROVAL_DENY: 'approval.deny', // Kullanıcı reddetti
|
|
27
|
+
TOOL_CALL: 'tool.call', // Agent bir tool çağırdı
|
|
28
|
+
TOOL_BLOCK: 'tool.block', // Tehlikeli tool çağrısı engellendi
|
|
29
|
+
AUTH_LOGIN: 'auth.login', // Login
|
|
30
|
+
AUTH_LOGOUT: 'auth.logout', // Logout
|
|
31
|
+
SECRET_READ: 'secret.read', // Secret çözüldü
|
|
32
|
+
SECRET_LEAK: 'secret.leak', // Potansiyel secret sızıntısı tespit
|
|
33
|
+
CONFIG_CHANGE: 'config.change', // Config değişti
|
|
34
|
+
CRON_RUN: 'cron.run', // Cron job çalıştı
|
|
35
|
+
SKILL_INSTALL: 'skill.install', // Skill yüklendi
|
|
36
|
+
SKILL_AUTO: 'skill.auto', // Self-evolving skill oluştu
|
|
37
|
+
ERROR: 'error', // Genel hata
|
|
38
|
+
INFO: 'info', // Bilgi mesajı
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
let _stream = null;
|
|
42
|
+
let _streamPath = null;
|
|
43
|
+
let _writeQueue = Promise.resolve();
|
|
44
|
+
|
|
45
|
+
function ensureDir() {
|
|
46
|
+
if (!fs.existsSync(AUDIT_DIR)) fs.mkdirSync(AUDIT_DIR, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function todayFile() {
|
|
50
|
+
const d = new Date().toISOString().slice(0, 10);
|
|
51
|
+
return path.join(AUDIT_DIR, `audit-${d}.jsonl`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getStream() {
|
|
55
|
+
const target = todayFile();
|
|
56
|
+
if (_stream && target === _streamPath) return _stream;
|
|
57
|
+
if (_stream) {
|
|
58
|
+
try { _stream.end(); } catch {}
|
|
59
|
+
}
|
|
60
|
+
ensureDir();
|
|
61
|
+
_stream = fs.createWriteStream(target, { flags: 'a' });
|
|
62
|
+
_streamPath = target;
|
|
63
|
+
return _stream;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Ana audit kayıt fonksiyonu. Non-blocking — queue'ya ekler ve döner.
|
|
68
|
+
*
|
|
69
|
+
* @param {string} action - ACTIONS enum'undan
|
|
70
|
+
* @param {object} data - Ek bağlam
|
|
71
|
+
* @returns {Promise<void>}
|
|
72
|
+
*/
|
|
73
|
+
function log(action, data = {}) {
|
|
74
|
+
ensureDir();
|
|
75
|
+
const entry = {
|
|
76
|
+
ts: new Date().toISOString(),
|
|
77
|
+
pid: process.pid,
|
|
78
|
+
ppid: process.ppid,
|
|
79
|
+
user: os.userInfo().username,
|
|
80
|
+
cwd: process.cwd(),
|
|
81
|
+
argv: process.argv.slice(2).slice(0, 5), // ilk 5 argüman
|
|
82
|
+
action,
|
|
83
|
+
...data,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
_writeQueue = _writeQueue.then(() => new Promise((resolve) => {
|
|
87
|
+
try {
|
|
88
|
+
const stream = getStream();
|
|
89
|
+
stream.write(JSON.stringify(entry) + '\n', () => resolve());
|
|
90
|
+
} catch (e) {
|
|
91
|
+
// Audit log hatası uygulamayı kıramamalı
|
|
92
|
+
resolve();
|
|
93
|
+
}
|
|
94
|
+
})).catch(() => {});
|
|
95
|
+
|
|
96
|
+
return _writeQueue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Senkron versiyon — kritik olaylarda çağrılabilir (örn: approval deny).
|
|
101
|
+
* Hata durumunda null döner, exception fırlatmaz.
|
|
102
|
+
*/
|
|
103
|
+
function logSync(action, data = {}) {
|
|
104
|
+
try {
|
|
105
|
+
ensureDir();
|
|
106
|
+
const entry = {
|
|
107
|
+
ts: new Date().toISOString(),
|
|
108
|
+
pid: process.pid,
|
|
109
|
+
user: os.userInfo().username,
|
|
110
|
+
cwd: process.cwd(),
|
|
111
|
+
action,
|
|
112
|
+
...data,
|
|
113
|
+
};
|
|
114
|
+
fs.appendFileSync(todayFile(), JSON.stringify(entry) + '\n', 'utf8');
|
|
115
|
+
return true;
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Tüm log dosyalarını döner — gün ismine göre sıralı.
|
|
123
|
+
*/
|
|
124
|
+
function listLogFiles() {
|
|
125
|
+
ensureDir();
|
|
126
|
+
return fs.readdirSync(AUDIT_DIR)
|
|
127
|
+
.filter(f => f.startsWith('audit-') && f.endsWith('.jsonl'))
|
|
128
|
+
.sort()
|
|
129
|
+
.reverse();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Belirli bir günün loglarını parse eder.
|
|
134
|
+
*/
|
|
135
|
+
function readLog(dateStr) {
|
|
136
|
+
const file = path.join(AUDIT_DIR, `audit-${dateStr}.jsonl`);
|
|
137
|
+
if (!fs.existsSync(file)) return [];
|
|
138
|
+
return fs.readFileSync(file, 'utf8')
|
|
139
|
+
.split('\n')
|
|
140
|
+
.filter(Boolean)
|
|
141
|
+
.map(l => {
|
|
142
|
+
try { return JSON.parse(l); } catch { return null; }
|
|
143
|
+
})
|
|
144
|
+
.filter(Boolean);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Retention temizliği — RETENTION_DAYS günden eski dosyaları siler.
|
|
149
|
+
*/
|
|
150
|
+
function cleanup() {
|
|
151
|
+
ensureDir();
|
|
152
|
+
const cutoff = Date.now() - RETENTION_DAYS * 86400 * 1000;
|
|
153
|
+
let removed = 0;
|
|
154
|
+
for (const file of fs.readdirSync(AUDIT_DIR)) {
|
|
155
|
+
if (!file.startsWith('audit-') || !file.endsWith('.jsonl')) continue;
|
|
156
|
+
const filePath = path.join(AUDIT_DIR, file);
|
|
157
|
+
const stat = fs.statSync(filePath);
|
|
158
|
+
if (stat.mtimeMs < cutoff) {
|
|
159
|
+
try { fs.unlinkSync(filePath); removed++; } catch {}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return removed;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Basit istatistik — son 24 saatte hangi actionlar kaç kez?
|
|
167
|
+
*/
|
|
168
|
+
function stats24h() {
|
|
169
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
170
|
+
const yesterday = new Date(Date.now() - 86400000).toISOString().slice(0, 10);
|
|
171
|
+
const entries = [...readLog(today), ...readLog(yesterday)];
|
|
172
|
+
const counts = {};
|
|
173
|
+
for (const e of entries) {
|
|
174
|
+
counts[e.action] = (counts[e.action] || 0) + 1;
|
|
175
|
+
}
|
|
176
|
+
return { total: entries.length, byAction: counts, period: `${yesterday} → ${today}` };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Flush — bekleyen yazma işlemlerini tamamla. Çıkışta çağrılır.
|
|
181
|
+
*/
|
|
182
|
+
async function flush() {
|
|
183
|
+
await _writeQueue;
|
|
184
|
+
if (_stream) {
|
|
185
|
+
return new Promise((resolve) => _stream.end(resolve));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
module.exports = {
|
|
190
|
+
ACTIONS,
|
|
191
|
+
log,
|
|
192
|
+
logSync,
|
|
193
|
+
listLogFiles,
|
|
194
|
+
readLog,
|
|
195
|
+
cleanup,
|
|
196
|
+
stats24h,
|
|
197
|
+
flush,
|
|
198
|
+
AUDIT_DIR,
|
|
199
|
+
};
|
package/src/utils/background.js
CHANGED
|
File without changes
|
package/src/utils/baileys.js
CHANGED
|
File without changes
|