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,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* natureco seo — SEO analiz aracı (Phase 6)
|
|
3
|
+
*
|
|
4
|
+
* Herhangi bir URL için hızlı SEO denetimi.
|
|
5
|
+
* Meta tags, başlık yapısı, performans ipuçları, schema.org kontrolü.
|
|
6
|
+
*
|
|
7
|
+
* Kullanım:
|
|
8
|
+
* natureco seo audit <url> Tam SEO denetimi
|
|
9
|
+
* natureco seo meta <url> Meta tag analizi
|
|
10
|
+
* natureco seo speed <url> Hız ipuçları
|
|
11
|
+
* natureco seo keywords <url> <k> Keyword density
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const chalk = require('chalk');
|
|
15
|
+
const tui = require('../utils/tui');
|
|
16
|
+
const https = require('https');
|
|
17
|
+
const http = require('http');
|
|
18
|
+
const { URL } = require('url');
|
|
19
|
+
const audit = require('../utils/audit');
|
|
20
|
+
|
|
21
|
+
function fetchUrl(targetUrl, options = {}) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const url = new URL(targetUrl);
|
|
24
|
+
const client = url.protocol === 'https:' ? https : http;
|
|
25
|
+
const req = client.request({
|
|
26
|
+
hostname: url.hostname,
|
|
27
|
+
path: url.pathname + url.search,
|
|
28
|
+
method: 'GET',
|
|
29
|
+
headers: {
|
|
30
|
+
'User-Agent': 'NatureCo-SEO-Audit/3.5',
|
|
31
|
+
'Accept': 'text/html,application/xhtml+xml',
|
|
32
|
+
...options.headers,
|
|
33
|
+
},
|
|
34
|
+
timeout: 15000,
|
|
35
|
+
}, (res) => {
|
|
36
|
+
// Redirect takip (max 3)
|
|
37
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
38
|
+
const redirect = new URL(res.headers.location, url).toString();
|
|
39
|
+
return fetchUrl(redirect).then(resolve).catch(reject);
|
|
40
|
+
}
|
|
41
|
+
let data = '';
|
|
42
|
+
res.on('data', (c) => data += c);
|
|
43
|
+
res.on('end', () => resolve({
|
|
44
|
+
statusCode: res.statusCode,
|
|
45
|
+
headers: res.headers,
|
|
46
|
+
body: data,
|
|
47
|
+
url: targetUrl,
|
|
48
|
+
}));
|
|
49
|
+
});
|
|
50
|
+
req.on('error', reject);
|
|
51
|
+
req.on('timeout', () => { req.destroy(); reject(new Error('Timeout')); });
|
|
52
|
+
req.end();
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function extractMeta(html) {
|
|
57
|
+
const result = {};
|
|
58
|
+
// Title
|
|
59
|
+
const titleMatch = html.match(/<title[^>]*>([\s\S]*?)<\/title>/i);
|
|
60
|
+
result.title = titleMatch ? titleMatch[1].trim() : null;
|
|
61
|
+
// Meta description
|
|
62
|
+
const descMatch = html.match(/<meta\s+name=["']description["']\s+content=["']([\s\S]*?)["']/i);
|
|
63
|
+
result.description = descMatch ? descMatch[1].trim() : null;
|
|
64
|
+
// Canonical
|
|
65
|
+
const canonMatch = html.match(/<link\s+rel=["']canonical["']\s+href=["']([\s\S]*?)["']/i);
|
|
66
|
+
result.canonical = canonMatch ? canonMatch[1].trim() : null;
|
|
67
|
+
// Open Graph
|
|
68
|
+
result.og = {};
|
|
69
|
+
const ogRe = /<meta\s+property=["']og:(\w+)["']\s+content=["']([\s\S]*?)["']/gi;
|
|
70
|
+
let m;
|
|
71
|
+
while ((m = ogRe.exec(html)) !== null) {
|
|
72
|
+
result.og[m[1]] = m[2].trim();
|
|
73
|
+
}
|
|
74
|
+
// Twitter Card
|
|
75
|
+
result.twitter = {};
|
|
76
|
+
const twRe = /<meta\s+name=["']twitter:(\w+)["']\s+content=["']([\s\S]*?)["']/gi;
|
|
77
|
+
while ((m = twRe.exec(html)) !== null) {
|
|
78
|
+
result.twitter[m[1]] = m[2].trim();
|
|
79
|
+
}
|
|
80
|
+
// H1-H6
|
|
81
|
+
result.headings = { h1: [], h2: [], h3: [] };
|
|
82
|
+
for (const tag of ['h1', 'h2', 'h3']) {
|
|
83
|
+
const re = new RegExp(`<${tag}[^>]*>([\\s\\S]*?)<\\/${tag}>`, 'gi');
|
|
84
|
+
while ((m = re.exec(html)) !== null) {
|
|
85
|
+
const text = m[1].replace(/<[^>]+>/g, '').trim();
|
|
86
|
+
if (text) result.headings[tag].push(text);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Images without alt
|
|
90
|
+
const imgRe = /<img\s[^>]*>/gi;
|
|
91
|
+
result.imagesWithoutAlt = 0;
|
|
92
|
+
result.totalImages = 0;
|
|
93
|
+
while ((m = imgRe.exec(html)) !== null) {
|
|
94
|
+
result.totalImages++;
|
|
95
|
+
if (!/\salt=/.test(m[0]) || /\salt=["']\s*["']/.test(m[0])) {
|
|
96
|
+
result.imagesWithoutAlt++;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Schema.org
|
|
100
|
+
result.hasSchema = /<script\s+type=["']application\/ld\+json["']/.test(html) ||
|
|
101
|
+
/itemtype=["']https?:\/\/schema\.org/.test(html);
|
|
102
|
+
// Word count (basit)
|
|
103
|
+
const text = html.replace(/<script[\s\S]*?<\/script>/gi, '')
|
|
104
|
+
.replace(/<style[\s\S]*?<\/style>/gi, '')
|
|
105
|
+
.replace(/<[^>]+>/g, ' ')
|
|
106
|
+
.replace(/\s+/g, ' ').trim();
|
|
107
|
+
result.wordCount = text.split(/\s+/).filter(Boolean).length;
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function cmdAudit(args) {
|
|
112
|
+
const targetUrl = args[0];
|
|
113
|
+
if (!targetUrl) {
|
|
114
|
+
console.log(tui.C.red('\n Kullanım: natureco seo audit <url>\n'));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.log('\n' + tui.styled(` 🔍 SEO Denetimi: ${targetUrl}`, { color: tui.PALETTE.primary, bold: true }));
|
|
119
|
+
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
120
|
+
|
|
121
|
+
// Spinner göster
|
|
122
|
+
const spinner = new tui.Spinner('Sayfa yükleniyor', { style: 'dots' }).start();
|
|
123
|
+
let response;
|
|
124
|
+
try {
|
|
125
|
+
response = await fetchUrl(targetUrl);
|
|
126
|
+
} catch (e) {
|
|
127
|
+
spinner.stop(tui.C.red('✗ Hata: ' + e.message));
|
|
128
|
+
console.log('');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (response.statusCode !== 200) {
|
|
133
|
+
spinner.stop(tui.C.yellow(`⚠ HTTP ${response.statusCode} yanıtı alındı`));
|
|
134
|
+
} else {
|
|
135
|
+
spinner.stop(tui.C.green('✓ Sayfa yüklendi'));
|
|
136
|
+
}
|
|
137
|
+
console.log('');
|
|
138
|
+
|
|
139
|
+
const meta = extractMeta(response.body);
|
|
140
|
+
const issues = [];
|
|
141
|
+
const passes = [];
|
|
142
|
+
|
|
143
|
+
// Title
|
|
144
|
+
if (!meta.title) {
|
|
145
|
+
issues.push({ severity: 'high', msg: 'Title tag eksik' });
|
|
146
|
+
} else if (meta.title.length < 30) {
|
|
147
|
+
issues.push({ severity: 'medium', msg: `Title çok kısa (${meta.title.length} karakter, ideal: 50-60)` });
|
|
148
|
+
} else if (meta.title.length > 60) {
|
|
149
|
+
issues.push({ severity: 'medium', msg: `Title çok uzun (${meta.title.length} karakter, ideal: 50-60)` });
|
|
150
|
+
} else {
|
|
151
|
+
passes.push(`Title (${meta.title.length} karakter)`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Description
|
|
155
|
+
if (!meta.description) {
|
|
156
|
+
issues.push({ severity: 'high', msg: 'Meta description eksik' });
|
|
157
|
+
} else if (meta.description.length < 120) {
|
|
158
|
+
issues.push({ severity: 'low', msg: `Description kısa (${meta.description.length} karakter, ideal: 150-160)` });
|
|
159
|
+
} else if (meta.description.length > 160) {
|
|
160
|
+
issues.push({ severity: 'low', msg: `Description uzun (${meta.description.length} karakter, ideal: 150-160)` });
|
|
161
|
+
} else {
|
|
162
|
+
passes.push(`Description (${meta.description.length} karakter)`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Canonical
|
|
166
|
+
if (meta.canonical) passes.push('Canonical URL var');
|
|
167
|
+
else issues.push({ severity: 'medium', msg: 'Canonical URL tanımlı değil' });
|
|
168
|
+
|
|
169
|
+
// OG
|
|
170
|
+
if (Object.keys(meta.og).length > 0) passes.push(`Open Graph (${Object.keys(meta.og).length} tag)`);
|
|
171
|
+
else issues.push({ severity: 'low', msg: 'Open Graph tag yok (sosyal medya paylaşımı için)' });
|
|
172
|
+
|
|
173
|
+
// Twitter
|
|
174
|
+
if (Object.keys(meta.twitter).length > 0) passes.push(`Twitter Card (${Object.keys(meta.twitter).length} tag)`);
|
|
175
|
+
else issues.push({ severity: 'low', msg: 'Twitter Card tag yok' });
|
|
176
|
+
|
|
177
|
+
// H1
|
|
178
|
+
if (meta.headings.h1.length === 0) issues.push({ severity: 'high', msg: 'H1 tag eksik' });
|
|
179
|
+
else if (meta.headings.h1.length > 1) issues.push({ severity: 'medium', msg: `Birden fazla H1 var (${meta.headings.h1.length}, ideal: 1)` });
|
|
180
|
+
else passes.push(`H1 var: "${meta.headings.h1[0].slice(0, 50)}"`);
|
|
181
|
+
|
|
182
|
+
// Images
|
|
183
|
+
if (meta.totalImages > 0) {
|
|
184
|
+
if (meta.imagesWithoutAlt > 0) {
|
|
185
|
+
issues.push({ severity: 'medium', msg: `${meta.imagesWithoutAlt}/${meta.totalImages} image alt tag eksik` });
|
|
186
|
+
} else {
|
|
187
|
+
passes.push(`Tüm image'larda alt var (${meta.totalImages})`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Schema
|
|
192
|
+
if (meta.hasSchema) passes.push('Schema.org markup var');
|
|
193
|
+
else issues.push({ severity: 'low', msg: 'Schema.org markup yok (rich snippets için)' });
|
|
194
|
+
|
|
195
|
+
// Content
|
|
196
|
+
if (meta.wordCount < 300) issues.push({ severity: 'medium', msg: `İçerik kısa (${meta.wordCount} kelime, ideal: 600+)` });
|
|
197
|
+
else passes.push(`İçerik uzunluğu (${meta.wordCount} kelime)`);
|
|
198
|
+
|
|
199
|
+
// Sonuçları tablo halinde göster
|
|
200
|
+
console.log(tui.styled(' 📊 Sonuçlar', { color: tui.PALETTE.primary, bold: true }));
|
|
201
|
+
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
202
|
+
|
|
203
|
+
// Geçenler
|
|
204
|
+
if (passes.length > 0) {
|
|
205
|
+
console.log('\n' + tui.styled(' ✅ Geçenler', { color: tui.PALETTE.success, bold: true }));
|
|
206
|
+
const passRows = passes.map((p, i) => ({
|
|
207
|
+
icon: tui.styled(' ✓ ', { bg: tui.PALETTE.success, color: '#000', bold: true }),
|
|
208
|
+
msg: p,
|
|
209
|
+
}));
|
|
210
|
+
console.log(tui.table(passRows, [
|
|
211
|
+
{ key: 'icon', label: ' ', minWidth: 5 },
|
|
212
|
+
{ key: 'msg', label: 'Kontrol', minWidth: 40, render: r => tui.C.text(r.msg) },
|
|
213
|
+
], { borderStyle: 'round', zebra: true }));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// İyileştirme alanları
|
|
217
|
+
if (issues.length > 0) {
|
|
218
|
+
console.log('\n' + tui.styled(' ⚠️ İyileştirme Alanları', { color: tui.PALETTE.warning, bold: true }));
|
|
219
|
+
const issueRows = issues.map(i => ({
|
|
220
|
+
icon: i.severity === 'high' ? tui.styled(' ✗ ', { bg: tui.PALETTE.danger, color: '#000', bold: true })
|
|
221
|
+
: i.severity === 'medium' ? tui.styled(' ⚠ ', { bg: tui.PALETTE.warning, color: '#000', bold: true })
|
|
222
|
+
: tui.styled(' ℹ ', { bg: tui.PALETTE.info, color: '#000', bold: true }),
|
|
223
|
+
msg: i.msg,
|
|
224
|
+
}));
|
|
225
|
+
console.log(tui.table(issueRows, [
|
|
226
|
+
{ key: 'icon', label: ' ', minWidth: 5 },
|
|
227
|
+
{ key: 'msg', label: 'Sorun', minWidth: 40, render: r => tui.C.text(r.msg) },
|
|
228
|
+
], { borderStyle: 'round', zebra: true }));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Skor (büyük, prominent)
|
|
232
|
+
const score = Math.max(0, Math.min(100, 100 - (issues.filter(i => i.severity === 'high').length * 15 + issues.filter(i => i.severity === 'medium').length * 7 + issues.filter(i => i.severity === 'low').length * 3)));
|
|
233
|
+
const scoreColor = score >= 80 ? tui.PALETTE.success : score >= 50 ? tui.PALETTE.warning : tui.PALETTE.danger;
|
|
234
|
+
const scoreGrade = score >= 80 ? '🟢 Mükemmel' : score >= 50 ? '🟡 İyi' : '🔴 Geliştirilmeli';
|
|
235
|
+
|
|
236
|
+
console.log('\n' + tui.styled(' ╭────────────────────────────────────────────────────╮', { color: tui.PALETTE.border }));
|
|
237
|
+
console.log(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('SEO Skoru:') + ' ' +
|
|
238
|
+
tui.styled(String(score).padStart(3), { color: scoreColor, bold: true }) + tui.C.muted('/100 ') +
|
|
239
|
+
tui.styled(scoreGrade, { color: scoreColor }) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
240
|
+
console.log(tui.styled(' ╰────────────────────────────────────────────────────╯', { color: tui.PALETTE.border }));
|
|
241
|
+
console.log('');
|
|
242
|
+
|
|
243
|
+
audit.log(audit.ACTIONS.INFO, { source: 'seo', url: targetUrl, score, issues: issues.length });
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async function seo(args) {
|
|
247
|
+
const [action, ...params] = args || [];
|
|
248
|
+
if (!action || action === 'help') {
|
|
249
|
+
console.log(chalk.yellow('\n Kullanım:'));
|
|
250
|
+
console.log(chalk.gray(' natureco seo audit <url> Tam SEO denetimi'));
|
|
251
|
+
console.log(chalk.gray(' natureco seo meta <url> Meta tag analizi'));
|
|
252
|
+
console.log(chalk.gray(' natureco seo speed <url> Hız ipuçları'));
|
|
253
|
+
console.log('');
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (action === 'audit') return cmdAudit(params);
|
|
257
|
+
if (action === 'meta') {
|
|
258
|
+
console.log(chalk.gray('\n Meta analizi audit\'in bir parçası olarak geliyor.\n'));
|
|
259
|
+
return cmdAudit(params);
|
|
260
|
+
}
|
|
261
|
+
if (action === 'speed') {
|
|
262
|
+
console.log(chalk.gray('\n Hız analizi: PageSpeed Insights API entegrasyonu eklenecek (Phase 7).\n'));
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
console.log(chalk.red(`\n Bilinmeyen: ${action}\n`));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
module.exports = seo;
|
package/src/commands/sessions.js
CHANGED
|
File without changes
|
package/src/commands/setup.js
CHANGED
|
@@ -4,6 +4,8 @@ const path = require('path');
|
|
|
4
4
|
const os = require('os');
|
|
5
5
|
const readline = require('readline');
|
|
6
6
|
const inquirer = require('../utils/inquirer-wrapper');
|
|
7
|
+
const brand = require('../utils/branding');
|
|
8
|
+
const { COLORS, FULL_LOGO } = brand;
|
|
7
9
|
|
|
8
10
|
const BASE_DIR = path.join(os.homedir(), '.natureco');
|
|
9
11
|
const CONFIG_FILE = path.join(BASE_DIR, 'config.json');
|
|
@@ -59,13 +61,11 @@ async function setup(params) {
|
|
|
59
61
|
|
|
60
62
|
async function cmdWizard() {
|
|
61
63
|
console.clear();
|
|
64
|
+
// Tam NatureCo logosu — brand kimliği
|
|
65
|
+
for (const line of FULL_LOGO) console.log(COLORS.primary(line));
|
|
62
66
|
console.log('');
|
|
63
|
-
console.log(
|
|
64
|
-
console.log(
|
|
65
|
-
console.log(chalk.green(' />🌿'));
|
|
66
|
-
console.log('');
|
|
67
|
-
console.log(chalk.green.bold(' NatureCo CLI — Setup Wizard'));
|
|
68
|
-
console.log(chalk.gray(' Choose your AI provider and enter your API key.\n'));
|
|
67
|
+
console.log(COLORS.secondary.bold(' ⚡ Setup Wizard — 60 saniyede hazır'));
|
|
68
|
+
console.log(COLORS.muted(' Provider seç, API key gir, hemen başla.\n'));
|
|
69
69
|
|
|
70
70
|
// Ensure directories
|
|
71
71
|
if (!fs.existsSync(BASE_DIR)) fs.mkdirSync(BASE_DIR, { recursive: true });
|
package/src/commands/signal.js
CHANGED
|
File without changes
|
package/src/commands/skills.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
|
+
const tui = require('../utils/tui');
|
|
2
3
|
const path = require('path');
|
|
3
4
|
const fs = require('fs');
|
|
4
5
|
const os = require('os');
|
|
5
6
|
const inquirer = require('../utils/inquirer-wrapper');
|
|
6
7
|
const { getSkills, installSkill, removeSkill, updateAllSkills, createSkillTemplate, getPopularSkills } = require('../utils/skills');
|
|
7
8
|
const { NatureCoError, SkillError, handleError } = require('../utils/errors');
|
|
9
|
+
const detector = require('../utils/pattern-detector');
|
|
10
|
+
const audit = require('../utils/audit');
|
|
8
11
|
|
|
9
12
|
async function skills(args) {
|
|
10
13
|
const [action, ...params] = args;
|
|
@@ -77,8 +80,40 @@ async function skills(args) {
|
|
|
77
80
|
return;
|
|
78
81
|
}
|
|
79
82
|
|
|
83
|
+
if (action === 'suggest' || action === 'proposals') {
|
|
84
|
+
await listProposals();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (action === 'accept') {
|
|
89
|
+
const proposalId = params[0];
|
|
90
|
+
if (!proposalId) {
|
|
91
|
+
console.log(chalk.red('\n❌ Kullanım: natureco skills accept <proposal-id>\n'));
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
await acceptProposalCommand(proposalId);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (action === 'reject') {
|
|
99
|
+
const proposalId = params[0];
|
|
100
|
+
if (!proposalId) {
|
|
101
|
+
console.log(chalk.red('\n❌ Kullanım: natureco skills reject <proposal-id>\n'));
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
detector.rejectProposal(proposalId);
|
|
105
|
+
console.log(chalk.green(`\n✅ Proposal reddedildi: ${proposalId}\n`));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (action === 'forget') {
|
|
110
|
+
detector.reset();
|
|
111
|
+
console.log(chalk.yellow('\n🧹 Tüm pattern hafızası ve proposal\'lar silindi.\n'));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
80
115
|
console.log(chalk.red(`\n❌ Geçersiz action: ${action}\n`));
|
|
81
|
-
console.log(chalk.gray('Kullanım: natureco skills [list|install|remove|update|create|search|browse|info|check]\n'));
|
|
116
|
+
console.log(chalk.gray('Kullanım: natureco skills [list|install|remove|update|create|search|browse|info|check|suggest|accept|reject|forget]\n'));
|
|
82
117
|
process.exit(1);
|
|
83
118
|
}
|
|
84
119
|
|
|
@@ -330,4 +365,50 @@ async function checkSkills() {
|
|
|
330
365
|
}
|
|
331
366
|
}
|
|
332
367
|
|
|
368
|
+
async function listProposals() {
|
|
369
|
+
const proposals = detector.loadProposals();
|
|
370
|
+
const pending = proposals.filter(p => p.status === 'pending');
|
|
371
|
+
|
|
372
|
+
console.log('\n' + tui.styled(' 🧠 Self-Evolving Skill Proposals', { color: tui.PALETTE.primary, bold: true }));
|
|
373
|
+
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
374
|
+
console.log(' ' + tui.C.muted('Kullanımın tekrar eden pattern\'lerinden otomatik skill önerileri.\n'));
|
|
375
|
+
|
|
376
|
+
if (pending.length === 0) {
|
|
377
|
+
console.log(' ' + tui.C.muted('Şu an öneri yok. Daha fazla tool çağrısı yap, sistem öğrensin.'));
|
|
378
|
+
console.log(' ' + tui.C.muted('Pattern\'leri sıfırla: ') + tui.C.brand('natureco skills forget\n'));
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const rows = pending.map(p => ({
|
|
383
|
+
name: p.suggestedName,
|
|
384
|
+
count: p.count + 'x',
|
|
385
|
+
pattern: p.pattern.length > 50 ? p.pattern.slice(0, 47) + '...' : p.pattern,
|
|
386
|
+
first: new Date(p.firstSeen).toLocaleString(),
|
|
387
|
+
id: p.id,
|
|
388
|
+
}));
|
|
389
|
+
|
|
390
|
+
console.log(tui.table(rows, [
|
|
391
|
+
{ key: 'name', label: 'Öneri', minWidth: 25, render: r => tui.styled(r.name, { color: tui.PALETTE.primary, bold: true }) },
|
|
392
|
+
{ key: 'count', label: 'Tekrar', minWidth: 7, render: r => tui.styled(r.count, { color: tui.PALETTE.accent, bold: true }) },
|
|
393
|
+
{ key: 'pattern', label: 'Pattern', minWidth: 30, render: r => tui.C.muted(r.pattern) },
|
|
394
|
+
{ key: 'first', label: 'İlk', minWidth: 18, render: r => tui.C.muted(r.first) },
|
|
395
|
+
], { borderStyle: 'round', zebra: true }));
|
|
396
|
+
|
|
397
|
+
console.log('\n ' + tui.C.muted('Kabul et: ') + tui.C.brand('natureco skills accept <id>'));
|
|
398
|
+
console.log(' ' + tui.C.muted('Reddet: ') + tui.C.brand('natureco skills reject <id>\n'));
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
async function acceptProposalCommand(proposalId) {
|
|
402
|
+
console.log(chalk.yellow('\n⏳ Skill oluşturuluyor...\n'));
|
|
403
|
+
const result = detector.acceptProposal(proposalId);
|
|
404
|
+
if (!result.success) {
|
|
405
|
+
console.log(chalk.red(`\n❌ ${result.reason}\n`));
|
|
406
|
+
process.exit(1);
|
|
407
|
+
}
|
|
408
|
+
console.log(chalk.green(`✅ Yeni skill oluşturuldu: ${result.skillName}\n`));
|
|
409
|
+
console.log(chalk.gray(` Yol: ${result.path}\n`));
|
|
410
|
+
console.log(chalk.gray(' SKILL.md dosyasını düzenleyerek özelleştirebilirsin.\n'));
|
|
411
|
+
audit.log(audit.ACTIONS.SKILL_AUTO, { proposalId, skillName: result.skillName });
|
|
412
|
+
}
|
|
413
|
+
|
|
333
414
|
module.exports = skills;
|
package/src/commands/slack.js
CHANGED
|
File without changes
|
package/src/commands/sms.js
CHANGED
|
File without changes
|
package/src/commands/status.js
CHANGED
|
File without changes
|
package/src/commands/system.js
CHANGED
|
File without changes
|
package/src/commands/tasks.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* natureco team — Multi-agent orkestrasyon (Phase 7)
|
|
3
|
+
*
|
|
4
|
+
* Birden fazla uzman agent'ı aynı görev üzerinde paralel çalıştır.
|
|
5
|
+
* Her biri kendi system prompt'u ve tool setiyle bağımsız çalışır.
|
|
6
|
+
*
|
|
7
|
+
* Kullanım:
|
|
8
|
+
* natureco team list Mevcut agent tipleri
|
|
9
|
+
* natureco team status Son çalışan agent'lar
|
|
10
|
+
* natureco team spawn <type> <task> Tek agent çalıştır
|
|
11
|
+
* natureco team parallel <spec> Paralel çalıştır (JSON)
|
|
12
|
+
*
|
|
13
|
+
* Örnek:
|
|
14
|
+
* natureco team spawn seo "natureco.me için anahtar kelime öner"
|
|
15
|
+
* natureco team parallel '[{"type":"seo","task":"..."}, {"type":"content","task":"..."}]'
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const chalk = require('chalk');
|
|
19
|
+
const tui = require('../utils/tui');
|
|
20
|
+
const subAgent = require('../utils/sub-agent');
|
|
21
|
+
const audit = require('../utils/audit');
|
|
22
|
+
|
|
23
|
+
async function cmdList() {
|
|
24
|
+
console.log('\n' + tui.styled(' 🤖 Mevcut Agent Tipleri', { color: tui.PALETTE.primary, bold: true }));
|
|
25
|
+
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
26
|
+
|
|
27
|
+
const rows = Object.entries(subAgent.SYSTEM_PROMPTS).map(([type, prompt]) => ({
|
|
28
|
+
type,
|
|
29
|
+
prompt: prompt.length > 80 ? prompt.slice(0, 77) + '...' : prompt,
|
|
30
|
+
}));
|
|
31
|
+
console.log('\n' + tui.table(rows, [
|
|
32
|
+
{ key: 'type', label: 'Tip', minWidth: 14, render: r => tui.styled(r.type, { color: tui.PALETTE.primary, bold: true }) },
|
|
33
|
+
{ key: 'prompt', label: 'Sistem Prompt', minWidth: 50, render: r => tui.C.muted(r.prompt) },
|
|
34
|
+
], { borderStyle: 'round', zebra: true }));
|
|
35
|
+
console.log('');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function cmdStatus() {
|
|
39
|
+
const status = subAgent.getStatus();
|
|
40
|
+
console.log('\n' + tui.styled(' 📊 Sub-Agent İstatistikleri', { color: tui.PALETTE.primary, bold: true }));
|
|
41
|
+
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
42
|
+
|
|
43
|
+
// Üst metrik kartı
|
|
44
|
+
const w = 50;
|
|
45
|
+
const lines = [];
|
|
46
|
+
lines.push(tui.styled(' ╭' + '─'.repeat(w) + '╮', { color: tui.PALETTE.border }));
|
|
47
|
+
lines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('Toplam ') + tui.styled(String(status.total).padStart(8), { color: tui.PALETTE.text, bold: true }) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
48
|
+
lines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('Çalışan ') + tui.styled(String(status.running).padStart(8), { color: tui.PALETTE.warning, bold: true }) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
49
|
+
lines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('Tamamlanan ') + tui.styled(String(status.completed).padStart(8), { color: tui.PALETTE.success, bold: true }) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
50
|
+
lines.push(tui.styled(' │', { color: tui.PALETTE.border }) + ' ' + tui.C.muted('Başarısız ') + tui.styled(String(status.failed).padStart(8), { color: tui.PALETTE.danger, bold: true }) + ' ' + tui.styled('│', { color: tui.PALETTE.border }));
|
|
51
|
+
lines.push(tui.styled(' ╰' + '─'.repeat(w) + '╯', { color: tui.PALETTE.border }));
|
|
52
|
+
console.log('\n' + lines.join('\n'));
|
|
53
|
+
|
|
54
|
+
if (status.agents.length > 0) {
|
|
55
|
+
console.log('\n' + tui.styled(' 📜 Son 10 Agent', { color: tui.PALETTE.secondary, bold: true }));
|
|
56
|
+
const rows = status.agents.slice(0, 10).map(a => {
|
|
57
|
+
const icon = a.status === 'completed'
|
|
58
|
+
? tui.styled(' ✓ ', { bg: tui.PALETTE.success, color: '#000', bold: true })
|
|
59
|
+
: a.status === 'failed'
|
|
60
|
+
? tui.styled(' ✗ ', { bg: tui.PALETTE.danger, color: '#000', bold: true })
|
|
61
|
+
: tui.styled(' ⋯ ', { bg: tui.PALETTE.warning, color: '#000', bold: true });
|
|
62
|
+
const dur = a.completedAt ? Math.round((new Date(a.completedAt) - new Date(a.startedAt)) / 100) / 10 : '-';
|
|
63
|
+
return { icon, type: a.type, task: a.task.slice(0, 60), dur: dur + 's' };
|
|
64
|
+
});
|
|
65
|
+
console.log('\n' + tui.table(rows, [
|
|
66
|
+
{ key: 'icon', label: ' ', minWidth: 5 },
|
|
67
|
+
{ key: 'type', label: 'Tip', minWidth: 12, render: r => tui.styled(r.type, { color: tui.PALETTE.primary }) },
|
|
68
|
+
{ key: 'task', label: 'Görev', minWidth: 30, render: r => tui.C.muted(r.task) },
|
|
69
|
+
{ key: 'dur', label: 'Süre', minWidth: 8, render: r => tui.C.text(r.dur) },
|
|
70
|
+
], { borderStyle: 'round', zebra: true }));
|
|
71
|
+
}
|
|
72
|
+
console.log('');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function cmdSpawn(args) {
|
|
76
|
+
const [type, ...taskParts] = args;
|
|
77
|
+
const task = taskParts.join(' ');
|
|
78
|
+
|
|
79
|
+
if (!type || !task) {
|
|
80
|
+
console.log(chalk.red('\n Kullanım: natureco team spawn <type> <task>\n'));
|
|
81
|
+
console.log(chalk.gray(' Tipler: ') + Object.keys(subAgent.SYSTEM_PROMPTS).join(', '));
|
|
82
|
+
console.log('');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!subAgent.SYSTEM_PROMPTS[type]) {
|
|
86
|
+
console.log(chalk.red(`\n Bilinmeyen agent tipi: ${type}`));
|
|
87
|
+
console.log(chalk.gray(' Tipler: ') + Object.keys(subAgent.SYSTEM_PROMPTS).join(', ') + '\n');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
console.log(chalk.cyan(`\n 🤖 ${type} agent başlatılıyor...\n`));
|
|
92
|
+
console.log(chalk.gray(` Görev: ${task.slice(0, 100)}\n`));
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const { result, usage, duration } = await subAgent.spawnSubAgent(type, task);
|
|
96
|
+
console.log(chalk.green(` ✓ Tamamlandı (${duration}ms)\n`));
|
|
97
|
+
console.log(chalk.gray(' ' + '─'.repeat(50)));
|
|
98
|
+
console.log(result);
|
|
99
|
+
console.log(chalk.gray(' ' + '─'.repeat(50)));
|
|
100
|
+
if (usage?.total_tokens) {
|
|
101
|
+
console.log(chalk.gray(` Token: ${usage.total_tokens} (${usage.prompt_tokens} in, ${usage.completion_tokens} out)\n`));
|
|
102
|
+
}
|
|
103
|
+
audit.log(audit.ACTIONS.TOOL_CALL, { source: 'team', type, task: task.slice(0, 100) });
|
|
104
|
+
} catch (e) {
|
|
105
|
+
console.log(chalk.red(`\n ❌ Hata: ${e.message}\n`));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function cmdParallel(args) {
|
|
110
|
+
const spec = args.join(' ');
|
|
111
|
+
if (!spec) {
|
|
112
|
+
console.log(chalk.red('\n Kullanım: natureco team parallel \'<json-spec>\'\n'));
|
|
113
|
+
console.log(chalk.gray(' Örnek: natureco team parallel \'[{"type":"seo","task":"..."},{"type":"content","task":"..."}]\'\n'));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let agents;
|
|
118
|
+
try { agents = JSON.parse(spec); }
|
|
119
|
+
catch (e) {
|
|
120
|
+
console.log(chalk.red(`\n Geçersiz JSON: ${e.message}\n`));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!Array.isArray(agents) || agents.length === 0) {
|
|
125
|
+
console.log(chalk.red('\n JSON array olmalı.\n'));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
console.log(chalk.cyan(`\n 🤝 ${agents.length} agent paralel başlatılıyor...\n`));
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const { results, failed } = await subAgent.spawnParallel(agents);
|
|
133
|
+
console.log(chalk.green(`\n ✓ ${results.length - failed.length}/${results.length} agent tamamlandı\n`));
|
|
134
|
+
|
|
135
|
+
for (let i = 0; i < results.length; i++) {
|
|
136
|
+
const r = results[i];
|
|
137
|
+
const a = agents[i];
|
|
138
|
+
console.log(chalk.bold(`\n ── Agent ${i+1}: ${a.type} ──`));
|
|
139
|
+
if (r.status === 'fulfilled') {
|
|
140
|
+
console.log(chalk.gray(` Görev: ${a.task.slice(0, 60)}`));
|
|
141
|
+
console.log(chalk.green(' ✓ Sonuç:'));
|
|
142
|
+
console.log(' ' + (r.value?.result || '').slice(0, 500));
|
|
143
|
+
} else {
|
|
144
|
+
console.log(chalk.red(` ✗ Hata: ${r.reason}`));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
console.log('');
|
|
148
|
+
} catch (e) {
|
|
149
|
+
console.log(chalk.red(`\n ❌ Hata: ${e.message}\n`));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async function team(args) {
|
|
154
|
+
const [action, ...params] = args || [];
|
|
155
|
+
if (!action || action === 'help') {
|
|
156
|
+
console.log(chalk.yellow('\n Kullanım:'));
|
|
157
|
+
console.log(chalk.gray(' natureco team list Agent tipleri'));
|
|
158
|
+
console.log(chalk.gray(' natureco team status Son çalışan agent\'lar'));
|
|
159
|
+
console.log(chalk.gray(' natureco team spawn <type> <task> Tek agent çalıştır'));
|
|
160
|
+
console.log(chalk.gray(' natureco team parallel <json> Paralel çalıştır'));
|
|
161
|
+
console.log('');
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (action === 'list') return cmdList();
|
|
165
|
+
if (action === 'status') return cmdStatus();
|
|
166
|
+
if (action === 'spawn') return cmdSpawn(params);
|
|
167
|
+
if (action === 'parallel') return cmdParallel(params);
|
|
168
|
+
console.log(chalk.red(`\n Bilinmeyen: ${action}\n`));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
module.exports = team;
|
package/src/commands/telegram.js
CHANGED
|
File without changes
|
package/src/commands/terminal.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/commands/tui.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/commands/update.js
CHANGED
|
File without changes
|
package/src/commands/voice.js
CHANGED
|
File without changes
|
package/src/commands/vydra.js
CHANGED
|
File without changes
|
|
File without changes
|
package/src/commands/webhooks.js
CHANGED
|
File without changes
|
package/src/commands/whatsapp.js
CHANGED
|
File without changes
|
package/src/commands/wiki.js
CHANGED
|
File without changes
|
|
File without changes
|