natureco-cli 2.23.27 → 2.23.29
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 +68 -6
- package/package.json +10 -6
- package/src/commands/channels.js +94 -4
- package/src/commands/chat.js +11 -25
- package/src/commands/code.js +12 -11
- package/src/commands/config.js +111 -68
- package/src/commands/doctor.js +121 -16
- package/src/commands/gateway-server.js +35 -21
- package/src/commands/gateway.js +11 -20
- package/src/commands/help.js +6 -0
- package/src/commands/imessage.js +55 -0
- package/src/commands/irc.js +70 -0
- package/src/commands/mattermost.js +62 -0
- package/src/commands/message.js +24 -4
- package/src/commands/models.js +584 -216
- package/src/commands/plugins.js +415 -172
- package/src/commands/security.js +149 -1
- package/src/commands/setup.js +1 -3
- package/src/commands/signal.js +66 -0
- package/src/commands/skills.js +20 -29
- package/src/commands/sms.js +64 -0
- package/src/commands/tasks.js +328 -79
- package/src/commands/webhooks.js +79 -0
- package/src/commands/whatsapp.js +7 -21
- package/src/tools/bash.js +63 -29
- package/src/utils/api.js +3 -20
- package/src/utils/approvals.js +297 -0
- package/src/utils/background.js +223 -66
- package/src/utils/baileys.js +21 -0
- package/src/utils/config.js +141 -10
- package/src/utils/errors.js +148 -0
- package/src/utils/inquirer-wrapper.js +1 -2
- package/src/utils/path-utils.js +13 -13
- package/src/utils/plugin-registry.js +238 -0
- package/src/utils/secrets.js +177 -0
- package/src/utils/skills.js +10 -23
package/src/commands/plugins.js
CHANGED
|
@@ -1,172 +1,415 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const os = require('os');
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
console.log(chalk.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
console.log(chalk.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
console.log(chalk.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
console.log(chalk.
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
const { PluginError, handleError } = require('../utils/errors');
|
|
7
|
+
const { loadRegistry, saveRegistry, scanInstalled, getPlugin, installPlugin, uninstallPlugin, updatePlugin, searchRegistry, validateManifest, PLUGINS_DIR } = require('../utils/plugin-registry');
|
|
8
|
+
|
|
9
|
+
async function plugins(args) {
|
|
10
|
+
const [action, ...params] = (args || []);
|
|
11
|
+
const opts = parseFlags(params);
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
if (!action || action === 'list') return listPlugins(opts);
|
|
15
|
+
if (action === 'install') return installHandler(params[0], opts);
|
|
16
|
+
if (action === 'uninstall' || action === 'remove') return uninstallHandler(params[0], opts);
|
|
17
|
+
if (action === 'enable') return toggleHandler(params[0], true);
|
|
18
|
+
if (action === 'disable') return toggleHandler(params[0], false);
|
|
19
|
+
if (action === 'info' || action === 'inspect') return infoHandler(params[0], opts);
|
|
20
|
+
if (action === 'update') return updateHandler(params[0], opts);
|
|
21
|
+
if (action === 'search') return searchHandler(params.join(' '), opts);
|
|
22
|
+
if (action === 'doctor') return doctorHandler();
|
|
23
|
+
if (action === 'registry') return registryHandler(opts);
|
|
24
|
+
|
|
25
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
26
|
+
console.log(chalk.gray(' Kullanım: natureco plugins [list|install|uninstall|enable|disable|info|update|search|doctor|registry]\n'));
|
|
27
|
+
process.exit(1);
|
|
28
|
+
} catch (err) {
|
|
29
|
+
handleError(err);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parseFlags(params) {
|
|
34
|
+
return {
|
|
35
|
+
json: params.includes('--json') || params.includes('-j'),
|
|
36
|
+
verbose: params.includes('--verbose') || params.includes('-v'),
|
|
37
|
+
all: params.includes('--all') || params.includes('-a'),
|
|
38
|
+
enabled: params.includes('--enabled'),
|
|
39
|
+
force: params.includes('--force') || params.includes('-f'),
|
|
40
|
+
keepFiles: params.includes('--keep-files'),
|
|
41
|
+
dryRun: params.includes('--dry-run'),
|
|
42
|
+
limit: extractInt(params, '--limit', 20),
|
|
43
|
+
directory: extractFlag(params, '--directory'),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function extractFlag(params, name) {
|
|
48
|
+
const idx = params.indexOf(name);
|
|
49
|
+
return idx >= 0 && idx + 1 < params.length ? params[idx + 1] : null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function extractInt(params, name, def) {
|
|
53
|
+
const v = extractFlag(params, name);
|
|
54
|
+
return v ? parseInt(v, 10) || def : def;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function listPlugins(opts) {
|
|
58
|
+
const allPlugins = scanInstalled();
|
|
59
|
+
const registry = loadRegistry();
|
|
60
|
+
const filtered = opts.enabled ? allPlugins.filter(p => p.enabled) : allPlugins;
|
|
61
|
+
|
|
62
|
+
if (opts.json) {
|
|
63
|
+
console.log(JSON.stringify({
|
|
64
|
+
plugins: filtered.map(p => ({
|
|
65
|
+
slug: p.slug, name: p.name, version: p.version, enabled: p.enabled,
|
|
66
|
+
source: registry.plugins.find(r => r.id === p.slug)?.source || 'unknown',
|
|
67
|
+
description: p.description, author: p.author, license: p.license,
|
|
68
|
+
installPath: p.installPath,
|
|
69
|
+
})),
|
|
70
|
+
total: filtered.length,
|
|
71
|
+
registry: { total: registry.plugins.length, updatedAt: registry.updatedAt },
|
|
72
|
+
}, null, 2));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log('');
|
|
77
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
78
|
+
console.log(chalk.cyan.bold('\n Plugins\n'));
|
|
79
|
+
|
|
80
|
+
if (filtered.length === 0) {
|
|
81
|
+
console.log(chalk.gray(' Yüklü plugin yok.\n'));
|
|
82
|
+
console.log(chalk.gray(' Yüklemek için: ') + chalk.cyan('natureco plugins install <paket-adı|./path|git:url>'));
|
|
83
|
+
console.log(chalk.gray(' Aramak için: ') + chalk.cyan('natureco plugins search <query>\n'));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
filtered.forEach(p => {
|
|
88
|
+
const status = p.enabled ? chalk.green('✓ aktif') : chalk.gray('○ pasif');
|
|
89
|
+
const source = registry.plugins.find(r => r.id === p.slug)?.source || 'local';
|
|
90
|
+
const sourceIcon = source === 'npm' ? '📦' : source === 'git' ? '🌐' : source === 'local' ? '📁' : '❓';
|
|
91
|
+
console.log(` ${sourceIcon} ${chalk.white(p.name)} ${chalk.gray(`v${p.version}`)} ${status}`);
|
|
92
|
+
if (p.description) console.log(chalk.gray(` ${p.description}`));
|
|
93
|
+
if (opts.verbose) {
|
|
94
|
+
console.log(chalk.gray(` Kaynak: ${source} | Yol: ${p.installPath}`));
|
|
95
|
+
if (p.author) console.log(chalk.gray(` Yazar: ${p.author}`));
|
|
96
|
+
}
|
|
97
|
+
console.log('');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
101
|
+
console.log(chalk.gray(` Toplam: ${filtered.length} plugin (${allPlugins.length - filtered.length} pasif)`));
|
|
102
|
+
console.log(chalk.gray(' Detay: ') + chalk.cyan('natureco plugins list --verbose'));
|
|
103
|
+
console.log(chalk.gray(' JSON: ') + chalk.cyan('natureco plugins list --json\n'));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function installHandler(spec, opts) {
|
|
107
|
+
if (!spec) {
|
|
108
|
+
console.log(chalk.red('\n ❌ Paket adı gerekli\n'));
|
|
109
|
+
console.log(chalk.gray(' Kullanım: natureco plugins install <paket-adı|./path|git:url|clawhub:<id>>\n'));
|
|
110
|
+
console.log(chalk.gray(' Örnekler:'));
|
|
111
|
+
console.log(chalk.gray(' natureco plugins install my-plugin'));
|
|
112
|
+
console.log(chalk.gray(' natureco plugins install npm:my-plugin'));
|
|
113
|
+
console.log(chalk.gray(' natureco plugins install ./yerel-klasor'));
|
|
114
|
+
console.log(chalk.gray(' natureco plugins install git:github.com/user/repo'));
|
|
115
|
+
console.log(chalk.gray(' natureco plugins install clawhub:plugin-id\n'));
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (opts.dryRun) {
|
|
120
|
+
console.log(chalk.gray(`\n 📋 Kuru çalışma: "${spec}" yüklenecek\n`));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
console.log(chalk.gray(`\n "${spec}" yükleniyor...\n`));
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const result = await installPlugin(spec);
|
|
128
|
+
console.log(chalk.green(` ✓ Plugin yüklendi: ${result.name} v${result.version}\n`));
|
|
129
|
+
console.log(chalk.gray(` Kaynak: ${result.source}`));
|
|
130
|
+
console.log(chalk.gray(` Slug: ${result.slug}\n`));
|
|
131
|
+
} catch (err) {
|
|
132
|
+
console.log(chalk.red(`\n ❌ Yükleme başarısız: ${err.message}\n`));
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function uninstallHandler(slug, opts) {
|
|
138
|
+
if (!slug) {
|
|
139
|
+
console.log(chalk.red('\n ❌ Plugin adı gerekli\n'));
|
|
140
|
+
console.log(chalk.gray(' Kullanım: natureco plugins uninstall <slug>\n'));
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (opts.dryRun) {
|
|
145
|
+
console.log(chalk.gray(`\n 📋 Kuru çalışma: "${slug}" kaldırılacak\n`));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const result = await uninstallPlugin(slug, { keepFiles: opts.keepFiles });
|
|
151
|
+
console.log(chalk.green(`\n ✓ Plugin kaldırıldı: ${result.name}\n`));
|
|
152
|
+
} catch (err) {
|
|
153
|
+
console.log(chalk.red(`\n ❌ Kaldırma başarısız: ${err.message}\n`));
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function toggleHandler(slug, enable) {
|
|
159
|
+
if (!slug) {
|
|
160
|
+
console.log(chalk.red(`\n ❌ Plugin adı gerekli\n`));
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
const pluginDir = path.join(PLUGINS_DIR, slug);
|
|
164
|
+
if (!fs.existsSync(pluginDir)) {
|
|
165
|
+
console.log(chalk.red(`\n ❌ Plugin bulunamadı: ${slug}\n`));
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
const disabledFile = path.join(pluginDir, '.disabled');
|
|
169
|
+
if (enable) {
|
|
170
|
+
if (fs.existsSync(disabledFile)) fs.unlinkSync(disabledFile);
|
|
171
|
+
console.log(chalk.green(`\n ✓ Plugin aktif: ${slug}\n`));
|
|
172
|
+
} else {
|
|
173
|
+
fs.writeFileSync(disabledFile, '');
|
|
174
|
+
console.log(chalk.gray(`\n ○ Plugin pasif: ${slug}\n`));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function infoHandler(slug, opts) {
|
|
179
|
+
if (!slug && !opts.all) {
|
|
180
|
+
console.log(chalk.red('\n ❌ Plugin adı gerekli\n'));
|
|
181
|
+
console.log(chalk.gray(' Kullanım: natureco plugins info <slug>\n'));
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (opts.all) {
|
|
186
|
+
const all = scanInstalled();
|
|
187
|
+
console.log(chalk.cyan.bold('\n Plugin Detayları\n'));
|
|
188
|
+
all.forEach(p => {
|
|
189
|
+
showPluginDetail(p);
|
|
190
|
+
});
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const p = getPlugin(slug);
|
|
195
|
+
if (!p) {
|
|
196
|
+
console.log(chalk.red(`\n ❌ Plugin bulunamadı: ${slug}\n`));
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (opts.json) {
|
|
201
|
+
console.log(JSON.stringify({
|
|
202
|
+
slug: p.slug, name: p.name, version: p.version, enabled: p.enabled,
|
|
203
|
+
description: p.description, author: p.author, license: p.license,
|
|
204
|
+
keywords: p.keywords || [], installPath: p.installPath,
|
|
205
|
+
entry: p.entry, dependencies: p.dependencies || {},
|
|
206
|
+
openclaw: p.openclaw || {},
|
|
207
|
+
}, null, 2));
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
showPluginDetail(p);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function showPluginDetail(p) {
|
|
215
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
216
|
+
console.log(chalk.cyan.bold(`\n ${p.name}\n`));
|
|
217
|
+
console.log(chalk.gray(' Slug : ') + chalk.white(p.slug));
|
|
218
|
+
console.log(chalk.gray(' Versiyon : ') + chalk.white(p.version));
|
|
219
|
+
console.log(chalk.gray(' Durum : ') + (p.enabled ? chalk.green('aktif') : chalk.gray('pasif')));
|
|
220
|
+
if (p.description) console.log(chalk.gray(' Açıklama : ') + chalk.white(p.description));
|
|
221
|
+
if (p.author) console.log(chalk.gray(' Yazar : ') + chalk.white(p.author));
|
|
222
|
+
if (p.license) console.log(chalk.gray(' Lisans : ') + chalk.white(p.license));
|
|
223
|
+
if (p.keywords?.length) console.log(chalk.gray(' Etiketler : ') + chalk.white(p.keywords.join(', ')));
|
|
224
|
+
console.log(chalk.gray(' Yol : ') + chalk.gray(p.installPath));
|
|
225
|
+
if (p.entry) console.log(chalk.gray(' Giriş : ') + chalk.white(p.entry));
|
|
226
|
+
if (p.dependencies && Object.keys(p.dependencies).length > 0) {
|
|
227
|
+
console.log(chalk.gray(' Bağımlılıklar:'));
|
|
228
|
+
Object.entries(p.dependencies).forEach(([k, v]) => {
|
|
229
|
+
const depPath = path.join(p.installPath, 'node_modules', k);
|
|
230
|
+
const installed = fs.existsSync(depPath) ? chalk.green('✓') : chalk.yellow('✗');
|
|
231
|
+
console.log(chalk.gray(` ${installed} ${k}: ${v}`));
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
if (p.openclaw?.tool) {
|
|
235
|
+
console.log(chalk.gray(' OpenClaw Tool Plugin: ') + chalk.white(p.openclaw.tool));
|
|
236
|
+
}
|
|
237
|
+
console.log('');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async function updateHandler(slug, opts) {
|
|
241
|
+
if (!slug && !opts.all) {
|
|
242
|
+
console.log(chalk.red('\n ❌ Plugin adı gerekli\n'));
|
|
243
|
+
console.log(chalk.gray(' Kullanım: natureco plugins update <slug>'));
|
|
244
|
+
console.log(chalk.gray(' Tümü: natureco plugins update --all\n'));
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (opts.all) {
|
|
249
|
+
const all = scanInstalled();
|
|
250
|
+
console.log(chalk.cyan('\n Tüm pluginler güncelleniyor...\n'));
|
|
251
|
+
for (const p of all) {
|
|
252
|
+
try {
|
|
253
|
+
const result = await updatePlugin(p.slug);
|
|
254
|
+
console.log(chalk.green(` ✓ ${p.name}: ${p.version} → ${result.version}\n`));
|
|
255
|
+
} catch (err) {
|
|
256
|
+
console.log(chalk.yellow(` ⚠ ${p.name}: ${err.message}\n`));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (opts.dryRun) {
|
|
263
|
+
console.log(chalk.gray(`\n 📋 Kuru çalışma: "${slug}" güncellenecek\n`));
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
const result = await updatePlugin(slug);
|
|
269
|
+
console.log(chalk.green(`\n ✓ Plugin güncellendi: ${result.name} → v${result.version}\n`));
|
|
270
|
+
} catch (err) {
|
|
271
|
+
console.log(chalk.red(`\n ❌ Güncelleme başarısız: ${err.message}\n`));
|
|
272
|
+
process.exit(1);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async function searchHandler(query, opts) {
|
|
277
|
+
if (!query) {
|
|
278
|
+
console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n'));
|
|
279
|
+
console.log(chalk.gray(' Kullanım: natureco plugins search <query>\n'));
|
|
280
|
+
process.exit(1);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
console.log(chalk.gray(`\n "${query}" aranıyor...\n`));
|
|
284
|
+
|
|
285
|
+
const results = [];
|
|
286
|
+
|
|
287
|
+
// Yerel kayıt defterinde ara
|
|
288
|
+
const local = searchRegistry(query);
|
|
289
|
+
local.forEach(p => results.push({ ...p, source: 'registry' }));
|
|
290
|
+
|
|
291
|
+
// NatureHub'da ara
|
|
292
|
+
try {
|
|
293
|
+
const res = await fetch(`https://natureco.me/api/plugins/search?q=${encodeURIComponent(query)}&limit=${opts.limit}`, {
|
|
294
|
+
signal: AbortSignal.timeout(5000),
|
|
295
|
+
});
|
|
296
|
+
if (res.ok) {
|
|
297
|
+
const data = await res.json();
|
|
298
|
+
(data.plugins || data.results || []).forEach(p => {
|
|
299
|
+
if (!results.some(r => r.id === p.id || r.id === p.name)) {
|
|
300
|
+
results.push({ id: p.id || p.name, name: p.name || p.id, version: p.version || 'latest', description: p.description || '', source: 'naturehub' });
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
} catch {}
|
|
305
|
+
|
|
306
|
+
// ClawHub'da ara
|
|
307
|
+
try {
|
|
308
|
+
const res = await fetch(`https://clawhub.ai/api/plugins?q=${encodeURIComponent(query)}&limit=${opts.limit}`, {
|
|
309
|
+
signal: AbortSignal.timeout(5000),
|
|
310
|
+
});
|
|
311
|
+
if (res.ok) {
|
|
312
|
+
const data = await res.json();
|
|
313
|
+
(data.plugins || data.results || []).forEach(p => {
|
|
314
|
+
if (!results.some(r => r.id === p.id || r.id === p.name)) {
|
|
315
|
+
results.push({ id: p.id || p.name, name: p.name || p.id, version: p.version || 'latest', description: p.description || '', source: 'clawhub' });
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
} catch {}
|
|
320
|
+
|
|
321
|
+
if (opts.json) {
|
|
322
|
+
console.log(JSON.stringify({ query, results, total: results.length }, null, 2));
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (results.length === 0) {
|
|
327
|
+
console.log(chalk.yellow(` "${query}" için sonuç bulunamadı.\n`));
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
console.log(chalk.cyan(` ${results.length} sonuç\n`));
|
|
332
|
+
results.slice(0, opts.limit).forEach(p => {
|
|
333
|
+
const sourceIcon = p.source === 'clawhub' ? '🦞' : p.source === 'naturehub' ? '🌿' : '📋';
|
|
334
|
+
console.log(` ${sourceIcon} ${chalk.white(p.name)} ${chalk.gray(`v${p.version}`)}`);
|
|
335
|
+
if (p.description) console.log(chalk.gray(` ${p.description.slice(0, 80)}`));
|
|
336
|
+
const installHint = p.source === 'clawhub' ? `clawhub:${p.id}` : p.source === 'naturehub' ? p.id : p.id;
|
|
337
|
+
console.log(chalk.gray(` Yüklemek: natureco plugins install ${installHint}\n`));
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function doctorHandler() {
|
|
342
|
+
const list = scanInstalled();
|
|
343
|
+
const registry = loadRegistry();
|
|
344
|
+
|
|
345
|
+
console.log(chalk.cyan.bold('\n Plugin Tanılama\n'));
|
|
346
|
+
|
|
347
|
+
if (list.length === 0 && registry.plugins.length === 0) {
|
|
348
|
+
console.log(chalk.gray(' Yüklü plugin yok.\n'));
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
let issues = 0;
|
|
353
|
+
|
|
354
|
+
list.forEach(p => {
|
|
355
|
+
const hasEntry = fs.existsSync(path.join(p.installPath, p.entry || 'index.js'));
|
|
356
|
+
const hasPackage = fs.existsSync(path.join(p.installPath, 'package.json'));
|
|
357
|
+
const manifestErrors = validateManifest(p);
|
|
358
|
+
|
|
359
|
+
if (!hasPackage) {
|
|
360
|
+
console.log(chalk.yellow(` ⚠ ${p.name}: package.json eksik`));
|
|
361
|
+
issues++;
|
|
362
|
+
}
|
|
363
|
+
if (!hasEntry) {
|
|
364
|
+
console.log(chalk.yellow(` ⚠ ${p.name}: ${p.entry || 'index.js'} bulunamadı`));
|
|
365
|
+
issues++;
|
|
366
|
+
}
|
|
367
|
+
if (manifestErrors.length > 0) {
|
|
368
|
+
console.log(chalk.yellow(` ⚠ ${p.name}: ${manifestErrors.join(', ')}`));
|
|
369
|
+
issues++;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (hasPackage && hasEntry && manifestErrors.length === 0) {
|
|
373
|
+
console.log(` ${chalk.green('✓')} ${p.name} v${p.version} — sağlıklı`);
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
registry.plugins.forEach(r => {
|
|
378
|
+
if (!list.some(p => p.slug === r.id)) {
|
|
379
|
+
console.log(chalk.yellow(` ⚠ Kayıtlı ama diskte yok: ${r.id} (kayıttan temizlenecek)`));
|
|
380
|
+
issues++;
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
if (issues === 0 && list.length > 0) {
|
|
385
|
+
console.log(chalk.green(' ✓ Tüm pluginler sağlıklı.\n'));
|
|
386
|
+
} else if (issues > 0) {
|
|
387
|
+
console.log(chalk.yellow(`\n ⚠ ${issues} sorun bulundu.\n`));
|
|
388
|
+
}
|
|
389
|
+
console.log('');
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function registryHandler(opts) {
|
|
393
|
+
const registry = loadRegistry();
|
|
394
|
+
|
|
395
|
+
if (opts.json) {
|
|
396
|
+
console.log(JSON.stringify(registry, null, 2));
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
console.log(chalk.cyan.bold('\n Plugin Kayıt Defteri\n'));
|
|
401
|
+
console.log(chalk.gray(' Versiyon : ') + chalk.white(`v${registry.version}`));
|
|
402
|
+
console.log(chalk.gray(' Güncelleme: ') + chalk.white(registry.updatedAt || 'hiç'));
|
|
403
|
+
console.log(chalk.gray(' Kayıtlı : ') + chalk.white(`${registry.plugins.length} plugin`));
|
|
404
|
+
|
|
405
|
+
if (registry.plugins.length > 0) {
|
|
406
|
+
console.log(chalk.cyan('\n Kayıtlı Pluginler\n'));
|
|
407
|
+
registry.plugins.forEach(p => {
|
|
408
|
+
const installed = scanInstalled().some(s => s.slug === p.id) ? chalk.green('✓') : chalk.yellow('✗');
|
|
409
|
+
console.log(` ${installed} ${chalk.white(p.name || p.id)} ${chalk.gray(`v${p.version} [${p.source}]`)}`);
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
console.log('');
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
module.exports = plugins;
|