natureco-cli 2.23.32 → 4.4.1
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 +13 -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,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NatureCo CLI — Secret Scanner (Phase 2)
|
|
3
|
+
*
|
|
4
|
+
* Kod metinlerinde veya dosya içeriklerinde hardcoded API key,
|
|
5
|
+
* token, password gibi hassas verilerin sızmasını önceden tespit eder.
|
|
6
|
+
*
|
|
7
|
+
* OpenClaw'ın en büyük güvenlik açıklarından biri buydu —
|
|
8
|
+
* kullanıcı farkında olmadan key'ini GitHub'a push'luyordu.
|
|
9
|
+
*
|
|
10
|
+
* Bu modül:
|
|
11
|
+
* - Statik metin tarama (regex)
|
|
12
|
+
* - Entropy analizi (rastgele yüksek entropi = muhtemelen secret)
|
|
13
|
+
* - Dosya tarama (skip: .git, node_modules, .natureco, lock dosyaları)
|
|
14
|
+
* - Pre-commit hook entegrasyonu için tasarlandı
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const crypto = require('crypto');
|
|
20
|
+
|
|
21
|
+
// Bilinen secret pattern'leri — provider/format eşleşmesi
|
|
22
|
+
const SECRET_PATTERNS = [
|
|
23
|
+
{ name: 'OpenAI', regex: /\bsk-[A-Za-z0-9]{20,}(?:T3BlbkFJ[A-Za-z0-9]{20,})?/g, severity: 'critical' },
|
|
24
|
+
{ name: 'Anthropic', regex: /\bsk-ant-[A-Za-z0-9-]{20,}/g, severity: 'critical' },
|
|
25
|
+
{ name: 'Groq', regex: /\bgsk_[A-Za-z0-20]{20,}/g, severity: 'critical' },
|
|
26
|
+
{ name: 'Google API', regex: /\bAIza[A-Za-z0-9_-]{35}/g, severity: 'critical' },
|
|
27
|
+
{ name: 'AWS Access Key', regex: /\bAKIA[0-9A-Z]{16}/g, severity: 'critical' },
|
|
28
|
+
{ name: 'AWS Secret Key', regex: /\b[A-Za-z0-9/+=]{40}\b/g, severity: 'high' }, // false positive riski yüksek
|
|
29
|
+
{ name: 'GitHub Token', regex: /\bgh[pousr]_[A-Za-z0-9]{36,}/g, severity: 'critical' },
|
|
30
|
+
{ name: 'GitHub Fine-grained', regex: /\bgithub_pat_[A-Za-z0-9_]{82}/g, severity: 'critical' },
|
|
31
|
+
{ name: 'Slack Token', regex: /\bxox[baprs]-[A-Za-z0-9-]{10,}/g, severity: 'critical' },
|
|
32
|
+
{ name: 'Stripe Live', regex: /\bsk_live_[A-Za-z0-9]{24,}/g, severity: 'critical' },
|
|
33
|
+
{ name: 'Stripe Test', regex: /\bsk_test_[A-Za-z0-9]{24,}/g, severity: 'medium' },
|
|
34
|
+
{ name: 'Tavily', regex: /\btvly-[A-Za-z0-9_-]{20,}/g, severity: 'critical' },
|
|
35
|
+
{ name: 'OpenAI Project', regex: /\bsk-proj-[A-Za-z0-9_-]{20,}/g, severity: 'critical' },
|
|
36
|
+
{ name: 'HuggingFace', regex: /\bhf_[A-Za-z0-9]{20,}/g, severity: 'critical' },
|
|
37
|
+
{ name: 'Replicate', regex: /\br8_[A-Za-z0-9]{40,}/g, severity: 'critical' },
|
|
38
|
+
{ name: 'Firecrawl', regex: /\bfc-[A-Za-z0-9]{20,}/g, severity: 'critical' },
|
|
39
|
+
{ name: 'NatureCo', regex: /\bnc_[A-Za-z0-9]{20,}/g, severity: 'critical' },
|
|
40
|
+
{ name: 'NatureCo Legacy', regex: /\bnco_[A-Za-z0-9]{20,}/g, severity: 'critical' },
|
|
41
|
+
{ name: 'JWT', regex: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g, severity: 'high' },
|
|
42
|
+
{ name: 'Private Key', regex: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g, severity: 'critical' },
|
|
43
|
+
{ name: 'Generic Password Assignment', regex: /(?:password|passwd|pwd|secret)\s*[=:]\s*['"]([^'"]{8,})['"]/gi, severity: 'medium' },
|
|
44
|
+
{ name: 'Bearer Token', regex: /\bBearer\s+[A-Za-z0-9_-]{20,}/g, severity: 'high' },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
// Tarama dışı dosyalar
|
|
48
|
+
const SKIP_DIRS = new Set([
|
|
49
|
+
'node_modules', '.git', '.natureco', 'dist', 'build',
|
|
50
|
+
'coverage', '.next', '.cache', '.venv', 'venv',
|
|
51
|
+
]);
|
|
52
|
+
const SKIP_EXT = new Set([
|
|
53
|
+
'.png', '.jpg', '.jpeg', '.gif', '.pdf', '.zip', '.tar', '.gz',
|
|
54
|
+
'.mp4', '.mp3', '.mov', '.ico', '.woff', '.woff2', '.ttf',
|
|
55
|
+
'.lock', '.bin', '.exe', '.dmg', '.dylib', '.so',
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
// Entropy hesaplama (Shannon)
|
|
59
|
+
function shannonEntropy(str) {
|
|
60
|
+
if (!str || str.length < 16) return 0;
|
|
61
|
+
const freq = {};
|
|
62
|
+
for (const c of str) freq[c] = (freq[c] || 0) + 1;
|
|
63
|
+
let entropy = 0;
|
|
64
|
+
const len = str.length;
|
|
65
|
+
for (const c in freq) {
|
|
66
|
+
const p = freq[c] / len;
|
|
67
|
+
entropy -= p * Math.log2(p);
|
|
68
|
+
}
|
|
69
|
+
return entropy;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Bir metin parçasını tarar, bulunan secret'ları döner.
|
|
74
|
+
*/
|
|
75
|
+
function scanText(text, options = {}) {
|
|
76
|
+
const { minEntropy = 4.0 } = options;
|
|
77
|
+
const findings = [];
|
|
78
|
+
|
|
79
|
+
for (const { name, regex, severity } of SECRET_PATTERNS) {
|
|
80
|
+
regex.lastIndex = 0;
|
|
81
|
+
let m;
|
|
82
|
+
while ((m = regex.exec(text)) !== null) {
|
|
83
|
+
findings.push({
|
|
84
|
+
type: name,
|
|
85
|
+
severity,
|
|
86
|
+
match: redactSecret(m[0]),
|
|
87
|
+
index: m.index,
|
|
88
|
+
});
|
|
89
|
+
if (!regex.global) break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Entropy tabanlı genel tarama (bilinmeyen format)
|
|
94
|
+
// Yüksek entropili 32+ karakterlik ardışık dizileri yakala
|
|
95
|
+
const highEntropyRe = /[A-Za-z0-9_\-+/=]{32,}/g;
|
|
96
|
+
let m;
|
|
97
|
+
while ((m = highEntropyRe.exec(text)) !== null) {
|
|
98
|
+
const candidate = m[0];
|
|
99
|
+
if (shannonEntropy(candidate) >= minEntropy) {
|
|
100
|
+
// Zaten bilinen bir pattern tarafından yakalanmadıysa ekle
|
|
101
|
+
if (!findings.some(f => Math.abs(f.index - m.index) < 10)) {
|
|
102
|
+
findings.push({
|
|
103
|
+
type: 'HighEntropyString',
|
|
104
|
+
severity: 'low',
|
|
105
|
+
match: redactSecret(candidate),
|
|
106
|
+
entropy: shannonEntropy(candidate).toFixed(2),
|
|
107
|
+
index: m.index,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return findings;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Secret'ı güvenli şekilde maskele (ilk 4 + son 4 karakter, ortası ***).
|
|
118
|
+
*/
|
|
119
|
+
function redactSecret(secret) {
|
|
120
|
+
if (!secret || secret.length < 12) return '***';
|
|
121
|
+
return secret.slice(0, 4) + '***' + secret.slice(-4);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Bir dosyayı tara.
|
|
126
|
+
*/
|
|
127
|
+
function scanFile(filePath, options = {}) {
|
|
128
|
+
try {
|
|
129
|
+
const stat = fs.statSync(filePath);
|
|
130
|
+
if (stat.size > 5 * 1024 * 1024) return []; // 5 MB'dan büyük dosyaları atla
|
|
131
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
132
|
+
const findings = scanText(content, options);
|
|
133
|
+
return findings.map(f => ({ ...f, file: filePath, line: lineFromIndex(content, f.index) }));
|
|
134
|
+
} catch {
|
|
135
|
+
return [];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function lineFromIndex(text, idx) {
|
|
140
|
+
return text.slice(0, idx).split('\n').length;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Bir dizini recursive olarak tara.
|
|
145
|
+
*/
|
|
146
|
+
function scanDir(dirPath, options = {}) {
|
|
147
|
+
const { maxFiles = 10000 } = options;
|
|
148
|
+
const findings = [];
|
|
149
|
+
let count = 0;
|
|
150
|
+
|
|
151
|
+
function walk(dir) {
|
|
152
|
+
if (count >= maxFiles) return;
|
|
153
|
+
let entries;
|
|
154
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
|
155
|
+
for (const entry of entries) {
|
|
156
|
+
if (count >= maxFiles) return;
|
|
157
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
158
|
+
const p = path.join(dir, entry.name);
|
|
159
|
+
if (entry.isDirectory()) {
|
|
160
|
+
walk(p);
|
|
161
|
+
} else if (entry.isFile()) {
|
|
162
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
163
|
+
if (SKIP_EXT.has(ext)) continue;
|
|
164
|
+
findings.push(...scanFile(p));
|
|
165
|
+
count++;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
walk(dirPath);
|
|
170
|
+
return findings;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Tarama sonuçlarını kritik/yüksek/orta/düşük olarak özetler.
|
|
175
|
+
*/
|
|
176
|
+
function summarize(findings) {
|
|
177
|
+
const counts = { critical: 0, high: 0, medium: 0, low: 0 };
|
|
178
|
+
for (const f of findings) counts[f.severity] = (counts[f.severity] || 0) + 1;
|
|
179
|
+
return counts;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Hızlı tahlil — verilen bir dizinde tarama yapar ve özet döner.
|
|
184
|
+
*/
|
|
185
|
+
function quickScan(dirPath) {
|
|
186
|
+
const findings = scanDir(dirPath);
|
|
187
|
+
return {
|
|
188
|
+
dir: dirPath,
|
|
189
|
+
timestamp: new Date().toISOString(),
|
|
190
|
+
findings,
|
|
191
|
+
summary: summarize(findings),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
module.exports = {
|
|
196
|
+
scanText,
|
|
197
|
+
scanFile,
|
|
198
|
+
scanDir,
|
|
199
|
+
summarize,
|
|
200
|
+
quickScan,
|
|
201
|
+
shannonEntropy,
|
|
202
|
+
redactSecret,
|
|
203
|
+
SECRET_PATTERNS,
|
|
204
|
+
};
|
package/src/utils/secrets.js
CHANGED
|
File without changes
|
package/src/utils/sessions.js
CHANGED
|
File without changes
|
package/src/utils/skills.js
CHANGED
|
File without changes
|
package/src/utils/sub-agent.js
CHANGED
|
@@ -9,6 +9,12 @@ const SYSTEM_PROMPTS = {
|
|
|
9
9
|
explore: 'You are a research agent. Find information, explore codebases, search files. Be concise.',
|
|
10
10
|
general: 'You are a general-purpose implementation agent. Write code, fix bugs, refactor.',
|
|
11
11
|
review: 'You are a code review agent. Analyze code for bugs, security, performance, style.',
|
|
12
|
+
// Phase 7 — NatureCo specialized agents
|
|
13
|
+
seo: 'Sen bir SEO uzmanısın. Anahtar kelime analizi, meta tag önerisi, içerik optimizasyonu yaparsın. Türkçe ve İngilizce içerik için öneri ver.',
|
|
14
|
+
content: 'Sen bir içerik yazarısın. NatureCo için SEO uyumlu, özgün blog yazıları ve sosyal medya içerikleri üretirsin. Hedef kitle: doğa ve teknoloji meraklıları, geliştiriciler.',
|
|
15
|
+
security: 'Sen bir güvenlik uzmanısın. OWASP top 10, dependency güvenliği, secret sızıntısı tespiti yapar, remediation önerirsin.',
|
|
16
|
+
translator: 'Sen bir çevirmensin. Doğal, akıcı, bağlama uygun çeviriler yaparsın. Teknik terimleri koruyarak sade dil kullanırsın.',
|
|
17
|
+
debugger: 'Sen bir debugging uzmanısın. Hata mesajlarını analiz eder, kök nedeni bulur, minimal bir fix önerir veya uygularsın.',
|
|
12
18
|
};
|
|
13
19
|
|
|
14
20
|
function ensureDir() {
|
|
File without changes
|
|
File without changes
|
package/src/utils/tool-runner.js
CHANGED
|
File without changes
|