natureco-cli 2.23.30 → 2.23.32
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/bin/natureco.js +178 -167
- package/package.json +1 -1
- package/src/commands/acp.js +39 -0
- package/src/commands/admin-rpc.js +83 -0
- package/src/commands/agent.js +214 -23
- package/src/commands/agents.js +114 -30
- package/src/commands/approvals.js +172 -11
- package/src/commands/ask.js +1 -1
- package/src/commands/browser.js +815 -0
- package/src/commands/capability.js +195 -22
- package/src/commands/channels.js +422 -267
- package/src/commands/chat.js +5 -8
- package/src/commands/clawbot.js +19 -0
- package/src/commands/code.js +3 -2
- package/src/commands/commitments.js +125 -9
- package/src/commands/completion.js +40 -32
- package/src/commands/config.js +228 -30
- package/src/commands/configure.js +84 -67
- package/src/commands/cron.js +239 -19
- package/src/commands/daemon.js +34 -4
- package/src/commands/dashboard.js +47 -374
- package/src/commands/devices.js +53 -26
- package/src/commands/directory.js +146 -14
- package/src/commands/dns.js +148 -10
- package/src/commands/docs.js +119 -26
- package/src/commands/doctor.js +143 -492
- package/src/commands/exec-policy.js +57 -48
- package/src/commands/gateway.js +492 -249
- package/src/commands/health.js +141 -11
- package/src/commands/help.js +24 -25
- package/src/commands/hooks.js +141 -87
- package/src/commands/infer.js +1442 -41
- package/src/commands/logs.js +122 -99
- package/src/commands/mcp.js +121 -309
- package/src/commands/memory.js +128 -0
- package/src/commands/message.js +720 -140
- package/src/commands/models.js +39 -1
- package/src/commands/node.js +77 -77
- package/src/commands/nodes.js +278 -22
- package/src/commands/onboard.js +115 -56
- package/src/commands/pairing.js +108 -107
- package/src/commands/path.js +206 -0
- package/src/commands/plugins.js +35 -1
- package/src/commands/proxy.js +159 -8
- package/src/commands/qr.js +55 -13
- package/src/commands/reset.js +101 -94
- package/src/commands/secrets.js +104 -21
- package/src/commands/sessions.js +110 -51
- package/src/commands/setup.js +229 -649
- package/src/commands/skills.js +67 -1
- package/src/commands/status.js +101 -127
- package/src/commands/tasks.js +208 -100
- package/src/commands/terminal.js +130 -12
- package/src/commands/transcripts.js +24 -1
- package/src/commands/tui.js +41 -0
- package/src/commands/uninstall.js +73 -92
- package/src/commands/update.js +146 -91
- package/src/commands/web-fetch.js +34 -0
- package/src/commands/webhooks.js +58 -66
- package/src/commands/wiki.js +783 -0
- package/src/utils/agents-md.js +85 -0
- package/src/utils/api.js +40 -41
- package/src/utils/format.js +144 -0
- package/src/utils/headless.js +2 -1
- package/src/utils/parallel-tools.js +106 -0
- package/src/utils/sub-agent.js +148 -0
- package/src/utils/token-budget.js +304 -0
- package/src/utils/tool-runner.js +7 -5
- package/src/utils/web-fetch.js +107 -0
package/src/commands/secrets.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
|
+
const F = require('../utils/format');
|
|
2
3
|
const { getConfig, saveConfig } = require('../utils/config');
|
|
3
4
|
|
|
4
5
|
function secrets(args) {
|
|
@@ -9,9 +10,12 @@ function secrets(args) {
|
|
|
9
10
|
if (action === 'get') return getSecret(params[0]);
|
|
10
11
|
if (action === 'unset') return unsetSecret(params[0]);
|
|
11
12
|
if (action === 'audit') return auditSecrets();
|
|
13
|
+
if (action === 'reload') return reloadSecrets();
|
|
14
|
+
if (action === 'configure') return configureProvider(params[0]);
|
|
15
|
+
if (action === 'apply') return applySecrets();
|
|
12
16
|
|
|
13
17
|
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
14
|
-
console.log(chalk.gray(' Kullanım: natureco secrets [list|set|get|unset|audit]\n'));
|
|
18
|
+
console.log(chalk.gray(' Kullanım: natureco secrets [list|set|get|unset|audit|reload|configure|apply]\n'));
|
|
15
19
|
process.exit(1);
|
|
16
20
|
}
|
|
17
21
|
|
|
@@ -21,20 +25,19 @@ function listSecrets() {
|
|
|
21
25
|
k.toLowerCase().includes('key') || k.toLowerCase().includes('token') || k.toLowerCase().includes('secret')
|
|
22
26
|
);
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
28
|
+
F.header('Secrets');
|
|
26
29
|
|
|
27
30
|
if (secretKeys.length === 0) {
|
|
28
|
-
|
|
31
|
+
F.info('No secrets stored.');
|
|
29
32
|
return;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
const rows = secretKeys.sort().map(key => {
|
|
33
36
|
const val = config[key];
|
|
34
37
|
const masked = val ? val.substring(0, 6) + '…' + val.slice(-4) : '(empty)';
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
+
return [key, masked, '-'];
|
|
39
|
+
});
|
|
40
|
+
F.table(['Name', 'Masked', 'Updated'], rows);
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
function setSecret(key, value) {
|
|
@@ -46,7 +49,7 @@ function setSecret(key, value) {
|
|
|
46
49
|
const config = getConfig();
|
|
47
50
|
config[key] = value;
|
|
48
51
|
saveConfig(config);
|
|
49
|
-
|
|
52
|
+
F.success(`Secret set: ${key}`);
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
function getSecret(key) {
|
|
@@ -59,11 +62,11 @@ function getSecret(key) {
|
|
|
59
62
|
const value = config[key];
|
|
60
63
|
|
|
61
64
|
if (!value) {
|
|
62
|
-
|
|
65
|
+
F.warning(`Secret not found: ${key}`);
|
|
63
66
|
return;
|
|
64
67
|
}
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
F.kv(key, value);
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
function unsetSecret(key) {
|
|
@@ -75,7 +78,7 @@ function unsetSecret(key) {
|
|
|
75
78
|
const config = getConfig();
|
|
76
79
|
delete config[key];
|
|
77
80
|
saveConfig(config);
|
|
78
|
-
|
|
81
|
+
F.success(`Secret removed: ${key}`);
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
function auditSecrets() {
|
|
@@ -92,27 +95,107 @@ function auditSecrets() {
|
|
|
92
95
|
'WHATSAPP_API_KEY'
|
|
93
96
|
];
|
|
94
97
|
|
|
95
|
-
|
|
96
|
-
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
98
|
+
F.header('Secrets Audit');
|
|
97
99
|
|
|
98
|
-
|
|
100
|
+
const rows = [];
|
|
99
101
|
for (const key of secrets.sort()) {
|
|
100
102
|
const val = config[key];
|
|
101
|
-
|
|
102
|
-
console.log(` ${chalk.gray('●')} ${key}: ${status}`);
|
|
103
|
+
rows.push([key, 'config', val ? 'set' : 'empty']);
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
console.log(chalk.white('\n Environment Variables:'));
|
|
106
106
|
let found = 0;
|
|
107
107
|
for (const envKey of envKeys) {
|
|
108
108
|
if (process.env[envKey]) {
|
|
109
|
-
|
|
109
|
+
rows.push([envKey, 'env', 'set']);
|
|
110
110
|
found++;
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
if (found === 0) console.log(chalk.gray(' (none set in environment)'));
|
|
114
113
|
|
|
115
|
-
|
|
114
|
+
F.table(['Key', 'Type', 'Status'], rows);
|
|
115
|
+
|
|
116
|
+
if (found === 0) F.info('(none set in environment)');
|
|
117
|
+
|
|
118
|
+
F.meta(`Total: ${secrets.length} config + ${found} env`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function reloadSecrets() {
|
|
122
|
+
const config = getConfig();
|
|
123
|
+
const envMappings = {
|
|
124
|
+
OPENAI_API_KEY: 'openaiApiKey',
|
|
125
|
+
ANTHROPIC_API_KEY: 'anthropicApiKey',
|
|
126
|
+
GROQ_API_KEY: 'groqApiKey',
|
|
127
|
+
TAVILY_API_KEY: 'tavilyApiKey',
|
|
128
|
+
ELEVENLABS_API_KEY: 'elevenlabsApiKey',
|
|
129
|
+
DEEPGRAM_API_KEY: 'deepgramApiKey',
|
|
130
|
+
FAL_KEY: 'falKey',
|
|
131
|
+
TOGETHER_API_KEY: 'togetherApiKey',
|
|
132
|
+
TELEGRAM_BOT_TOKEN: 'telegramToken',
|
|
133
|
+
DISCORD_BOT_TOKEN: 'discordToken',
|
|
134
|
+
SLACK_BOT_TOKEN: 'slackToken',
|
|
135
|
+
};
|
|
136
|
+
let count = 0;
|
|
137
|
+
for (const [envVar, configKey] of Object.entries(envMappings)) {
|
|
138
|
+
if (process.env[envVar] && !config[configKey]) {
|
|
139
|
+
config[configKey] = process.env[envVar];
|
|
140
|
+
count++;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (count > 0) {
|
|
144
|
+
saveConfig(config);
|
|
145
|
+
F.success(`${count} secrets loaded from environment`);
|
|
146
|
+
} else {
|
|
147
|
+
F.warning('No new secrets found in environment');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function configureProvider(provider) {
|
|
152
|
+
if (!provider) {
|
|
153
|
+
console.log(chalk.red('\n ❌ Provider name required\n'));
|
|
154
|
+
console.log(chalk.gray(' Available: openai, anthropic, groq, together, deepseek, mistral, perplexity, elevenlabs, deepgram, fal\n'));
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const instructions = {
|
|
159
|
+
openai: { key: 'openaiApiKey', env: 'OPENAI_API_KEY', url: 'https://platform.openai.com/api-keys' },
|
|
160
|
+
anthropic: { key: 'anthropicApiKey', env: 'ANTHROPIC_API_KEY', url: 'https://console.anthropic.com/keys' },
|
|
161
|
+
groq: { key: 'groqApiKey', env: 'GROQ_API_KEY', url: 'https://console.groq.com/keys' },
|
|
162
|
+
together: { key: 'togetherApiKey', env: 'TOGETHER_API_KEY', url: 'https://together.ai/settings/api-keys' },
|
|
163
|
+
deepseek: { key: 'deepseekApiKey', env: 'DEEPSEEK_API_KEY', url: 'https://platform.deepseek.com/api-keys' },
|
|
164
|
+
mistral: { key: 'mistralApiKey', env: 'MISTRAL_API_KEY', url: 'https://console.mistral.ai/api-keys' },
|
|
165
|
+
perplexity: { key: 'perplexityApiKey', env: 'PERPLEXITY_API_KEY', url: 'https://www.perplexity.ai/settings/api' },
|
|
166
|
+
elevenlabs: { key: 'elevenlabsApiKey', env: 'ELEVENLABS_API_KEY', url: 'https://elevenlabs.io/app/settings/api-keys' },
|
|
167
|
+
deepgram: { key: 'deepgramApiKey', env: 'DEEPGRAM_API_KEY', url: 'https://console.deepgram.com/keys' },
|
|
168
|
+
fal: { key: 'falKey', env: 'FAL_KEY', url: 'https://fal.ai/dashboard/keys' },
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const info = instructions[provider.toLowerCase()];
|
|
172
|
+
|
|
173
|
+
if (!info) {
|
|
174
|
+
console.log(chalk.red(`\n ❌ Unknown provider: ${provider}\n`));
|
|
175
|
+
console.log(chalk.gray(' Available: openai, anthropic, groq, together, deepseek, mistral, perplexity, elevenlabs, deepgram, fal\n'));
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
F.section(`Configure ${provider}`);
|
|
180
|
+
|
|
181
|
+
F.list([
|
|
182
|
+
{ label: 'Config key', value: info.key },
|
|
183
|
+
{ label: 'Env var', value: info.env },
|
|
184
|
+
{ label: 'Get key', value: info.url },
|
|
185
|
+
]);
|
|
186
|
+
|
|
187
|
+
F.info(`Set it: natureco secrets set ${info.key} <your-key>`);
|
|
188
|
+
F.info(`Or set env: $env:${info.env}="your-key"`);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function applySecrets() {
|
|
192
|
+
F.header('Apply Secrets');
|
|
193
|
+
F.info('Secrets are stored locally in config.json');
|
|
194
|
+
F.info('To make them available to running processes:');
|
|
195
|
+
F.list([
|
|
196
|
+
'Set environment variables and restart',
|
|
197
|
+
'Or use: natureco secrets reload',
|
|
198
|
+
]);
|
|
116
199
|
}
|
|
117
200
|
|
|
118
201
|
module.exports = secrets;
|
package/src/commands/sessions.js
CHANGED
|
@@ -1,70 +1,129 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
1
2
|
const fs = require('fs');
|
|
2
3
|
const path = require('path');
|
|
3
4
|
const os = require('os');
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (!
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
|
|
6
|
+
const SESSIONS_DIR = path.join(os.homedir(), '.natureco', 'sessions');
|
|
7
|
+
|
|
8
|
+
function ensureDir(dir) {
|
|
9
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function sessions(args) {
|
|
13
|
+
const [action, ...params] = args || [];
|
|
14
|
+
|
|
15
|
+
if (!action || action === 'list') return cmdList();
|
|
16
|
+
if (action === 'show') return cmdShow(params[0]);
|
|
17
|
+
if (action === 'cleanup') return cmdCleanup();
|
|
18
|
+
if (action === 'prune') return cmdPrune(parseInt(params[0], 10));
|
|
19
|
+
|
|
20
|
+
console.log(chalk.red(`\n Unknown sessions action: ${action}\n`));
|
|
21
|
+
console.log(chalk.gray(' Usage: natureco sessions <action> [params]'));
|
|
22
|
+
console.log(chalk.gray(' Actions: list, show <id>, cleanup, prune <days>\n'));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getSessions() {
|
|
27
|
+
ensureDir(SESSIONS_DIR);
|
|
28
|
+
const files = fs.readdirSync(SESSIONS_DIR).filter(f => f.endsWith('.json'));
|
|
29
|
+
const sessions = [];
|
|
30
|
+
for (const file of files) {
|
|
31
|
+
const fp = path.join(SESSIONS_DIR, file);
|
|
32
|
+
try {
|
|
33
|
+
const data = JSON.parse(fs.readFileSync(fp, 'utf8'));
|
|
34
|
+
sessions.push({ id: path.basename(file, '.json'), file, data });
|
|
35
|
+
} catch {}
|
|
17
36
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
return sessions;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function cmdList() {
|
|
41
|
+
const sessions = getSessions();
|
|
42
|
+
|
|
43
|
+
console.log(chalk.cyan(`\n Sessions (${sessions.length})\n`));
|
|
44
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
45
|
+
|
|
46
|
+
if (sessions.length === 0) {
|
|
47
|
+
console.log(chalk.gray(' No sessions found.\n'));
|
|
48
|
+
return;
|
|
26
49
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
50
|
+
|
|
51
|
+
for (const s of sessions) {
|
|
52
|
+
const msgCount = (s.data.messages || []).length;
|
|
53
|
+
const preview = s.data.preview || s.data.id || s.id;
|
|
54
|
+
const updated = s.data.updatedAt || s.data.savedAt || '';
|
|
55
|
+
console.log(` ${chalk.white(s.id)}`);
|
|
56
|
+
console.log(chalk.gray(` Messages: ${msgCount} · ${preview.toString().slice(0, 60)}`));
|
|
57
|
+
if (updated) console.log(chalk.gray(` Updated: ${updated.slice(0, 10)}`));
|
|
58
|
+
}
|
|
59
|
+
console.log('');
|
|
30
60
|
}
|
|
31
61
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
62
|
+
function cmdShow(id) {
|
|
63
|
+
if (!id) {
|
|
64
|
+
console.log(chalk.red('\n Usage: natureco sessions show <id>\n'));
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const sessions = getSessions();
|
|
69
|
+
const found = sessions.find(s => s.id.includes(id));
|
|
70
|
+
|
|
71
|
+
if (!found) {
|
|
72
|
+
console.log(chalk.yellow(`\n Session not found: ${id}\n`));
|
|
36
73
|
return;
|
|
37
74
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
75
|
+
|
|
76
|
+
console.log(chalk.cyan(`\n Session: ${found.id}\n`));
|
|
77
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
78
|
+
const msgs = found.data.messages || [];
|
|
79
|
+
console.log(` ${chalk.white('Messages:')} ${chalk.cyan(msgs.length)}`);
|
|
80
|
+
for (const msg of msgs.slice(-10)) {
|
|
81
|
+
const role = msg.role === 'user' ? chalk.green('You') : chalk.cyan('Bot');
|
|
82
|
+
const content = (msg.content || '').slice(0, 200);
|
|
83
|
+
console.log(` ${role}: ${chalk.white(content)}`);
|
|
84
|
+
}
|
|
85
|
+
if (msgs.length > 10) console.log(chalk.gray(` ... and ${msgs.length - 10} more`));
|
|
86
|
+
console.log('');
|
|
42
87
|
}
|
|
43
88
|
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
89
|
+
function cmdCleanup() {
|
|
90
|
+
const sessions = getSessions();
|
|
91
|
+
let removed = 0;
|
|
92
|
+
|
|
93
|
+
for (const s of sessions) {
|
|
94
|
+
const msgs = s.data.messages || [];
|
|
95
|
+
if (msgs.length === 0) {
|
|
96
|
+
try {
|
|
97
|
+
fs.unlinkSync(path.join(SESSIONS_DIR, s.file));
|
|
98
|
+
removed++;
|
|
99
|
+
} catch {}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.log(chalk.gray(`\n Cleaned up ${removed} empty session(s).\n`));
|
|
48
104
|
}
|
|
49
105
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
console.log(chalk.red(`\n ❌ Oturum bulunamadı: ${sessionId}\n`));
|
|
106
|
+
function cmdPrune(days) {
|
|
107
|
+
if (!days || isNaN(days) || days < 1) {
|
|
108
|
+
console.log(chalk.red('\n Usage: natureco sessions prune <days>\n'));
|
|
54
109
|
process.exit(1);
|
|
55
110
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
111
|
+
|
|
112
|
+
const cutoff = Date.now() - days * 86400000;
|
|
113
|
+
const sessions = getSessions();
|
|
114
|
+
let removed = 0;
|
|
115
|
+
|
|
116
|
+
for (const s of sessions) {
|
|
117
|
+
const ts = s.data.updatedAt || s.data.savedAt || '';
|
|
118
|
+
if (ts && new Date(ts).getTime() < cutoff) {
|
|
119
|
+
try {
|
|
120
|
+
fs.unlinkSync(path.join(SESSIONS_DIR, s.file));
|
|
121
|
+
removed++;
|
|
122
|
+
} catch {}
|
|
123
|
+
}
|
|
60
124
|
}
|
|
61
|
-
|
|
62
|
-
console.log(chalk.
|
|
63
|
-
console.log(chalk.gray(` ${data.savedAt} · ${data.messages.length} mesaj\n`));
|
|
64
|
-
data.messages.forEach((msg, i) => {
|
|
65
|
-
console.log(chalk.white(` ${msg.role === 'user' ? 'You' : 'Bot'}: ${msg.content?.slice(0, 200)}`));
|
|
66
|
-
});
|
|
67
|
-
console.log();
|
|
125
|
+
|
|
126
|
+
console.log(chalk.gray(`\n Pruned ${removed} session(s) older than ${days} day(s).\n`));
|
|
68
127
|
}
|
|
69
128
|
|
|
70
129
|
module.exports = sessions;
|