natureco-cli 2.23.29 β†’ 2.23.31

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.
Files changed (111) hide show
  1. package/README.md +94 -11
  2. package/bin/natureco.js +495 -94
  3. package/package.json +1 -1
  4. package/src/commands/acp.js +39 -0
  5. package/src/commands/admin-rpc.js +302 -0
  6. package/src/commands/agent.js +280 -0
  7. package/src/commands/agents.js +114 -30
  8. package/src/commands/approvals.js +214 -0
  9. package/src/commands/backup.js +124 -0
  10. package/src/commands/bonjour.js +167 -0
  11. package/src/commands/browser.js +815 -0
  12. package/src/commands/capability.js +237 -0
  13. package/src/commands/channels.js +422 -267
  14. package/src/commands/chat.js +5 -8
  15. package/src/commands/clawbot.js +19 -0
  16. package/src/commands/clickclack.js +130 -0
  17. package/src/commands/code.js +3 -2
  18. package/src/commands/commitments.js +148 -0
  19. package/src/commands/completion.js +84 -0
  20. package/src/commands/config.js +219 -30
  21. package/src/commands/configure.js +110 -0
  22. package/src/commands/crestodian.js +92 -0
  23. package/src/commands/cron.js +239 -19
  24. package/src/commands/daemon.js +90 -0
  25. package/src/commands/dashboard.js +47 -374
  26. package/src/commands/device-pair.js +248 -0
  27. package/src/commands/devices.js +137 -0
  28. package/src/commands/directory.js +179 -0
  29. package/src/commands/dns.js +196 -0
  30. package/src/commands/docs.js +136 -0
  31. package/src/commands/doctor.js +143 -492
  32. package/src/commands/exec-policy.js +80 -0
  33. package/src/commands/gateway-server.js +1155 -24
  34. package/src/commands/gateway.js +492 -249
  35. package/src/commands/health.js +148 -0
  36. package/src/commands/help.js +24 -25
  37. package/src/commands/hooks.js +141 -87
  38. package/src/commands/imessage.js +128 -14
  39. package/src/commands/infer.js +1474 -0
  40. package/src/commands/irc.js +64 -15
  41. package/src/commands/logs.js +122 -99
  42. package/src/commands/mattermost.js +114 -12
  43. package/src/commands/mcp.js +121 -309
  44. package/src/commands/memory-cmd.js +134 -1
  45. package/src/commands/memory.js +128 -0
  46. package/src/commands/message.js +720 -134
  47. package/src/commands/migrate.js +213 -2
  48. package/src/commands/models.js +39 -1
  49. package/src/commands/node.js +98 -0
  50. package/src/commands/nodes.js +362 -0
  51. package/src/commands/oc-path.js +200 -0
  52. package/src/commands/onboard.js +129 -0
  53. package/src/commands/open-prose.js +67 -0
  54. package/src/commands/pairing.js +108 -107
  55. package/src/commands/path.js +206 -0
  56. package/src/commands/plugins.js +35 -1
  57. package/src/commands/policy.js +176 -0
  58. package/src/commands/proxy.js +306 -0
  59. package/src/commands/qr.js +70 -0
  60. package/src/commands/reset.js +101 -94
  61. package/src/commands/sandbox.js +125 -0
  62. package/src/commands/secrets.js +201 -0
  63. package/src/commands/sessions.js +110 -51
  64. package/src/commands/setup.js +102 -543
  65. package/src/commands/signal.js +447 -18
  66. package/src/commands/skills.js +67 -1
  67. package/src/commands/sms.js +123 -19
  68. package/src/commands/status.js +101 -127
  69. package/src/commands/system.js +53 -0
  70. package/src/commands/tasks.js +208 -100
  71. package/src/commands/terminal.js +139 -0
  72. package/src/commands/thread-ownership.js +157 -0
  73. package/src/commands/transcripts.js +95 -0
  74. package/src/commands/tui.js +41 -0
  75. package/src/commands/uninstall.js +73 -92
  76. package/src/commands/update.js +146 -91
  77. package/src/commands/voice.js +82 -0
  78. package/src/commands/vydra.js +98 -0
  79. package/src/commands/webhooks.js +58 -66
  80. package/src/commands/wiki.js +783 -0
  81. package/src/commands/workboard.js +207 -0
  82. package/src/tools/audio_understanding.js +154 -0
  83. package/src/tools/browser.js +112 -0
  84. package/src/tools/canvas.js +104 -0
  85. package/src/tools/document_extract.js +84 -0
  86. package/src/tools/duckduckgo.js +54 -0
  87. package/src/tools/exa_search.js +66 -0
  88. package/src/tools/firecrawl.js +104 -0
  89. package/src/tools/image_generation.js +99 -0
  90. package/src/tools/llm_task.js +118 -0
  91. package/src/tools/media_understanding.js +128 -0
  92. package/src/tools/music_generation.js +113 -0
  93. package/src/tools/parallel_search.js +77 -0
  94. package/src/tools/phone_control.js +80 -0
  95. package/src/tools/phone_control_enhanced.js +184 -0
  96. package/src/tools/searxng.js +61 -0
  97. package/src/tools/speech_to_text.js +135 -0
  98. package/src/tools/text_to_speech.js +105 -0
  99. package/src/tools/thread_ownership.js +88 -0
  100. package/src/tools/video_generation.js +72 -0
  101. package/src/tools/web_readability.js +104 -0
  102. package/src/utils/agents-md.js +85 -0
  103. package/src/utils/api.js +39 -40
  104. package/src/utils/format.js +144 -0
  105. package/src/utils/headless.js +2 -1
  106. package/src/utils/memory.js +200 -0
  107. package/src/utils/parallel-tools.js +106 -0
  108. package/src/utils/sub-agent.js +148 -0
  109. package/src/utils/token-budget.js +304 -0
  110. package/src/utils/tool-runner.js +7 -5
  111. package/src/utils/web-fetch.js +107 -0
@@ -0,0 +1,67 @@
1
+ const chalk = require('chalk');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+
5
+ function openProse(args) {
6
+ const [action, ...params] = args || [];
7
+
8
+ if (!action || action === 'list') return listBundles();
9
+ if (action === 'info') return showInfo();
10
+
11
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
12
+ console.log(chalk.gray(' KullanΔ±m: natureco open-prose [list|info]\n'));
13
+ process.exit(1);
14
+ }
15
+
16
+ function listBundles() {
17
+ const skillsDir = path.join(__dirname, '..', '..', 'skills');
18
+ console.log(chalk.cyan('\n πŸ“¦ OpenProse Skills Bundles\n'));
19
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
20
+
21
+ let bundles = [];
22
+ if (fs.existsSync(skillsDir)) {
23
+ try {
24
+ bundles = fs.readdirSync(skillsDir).filter(f => f.endsWith('.md'));
25
+ } catch {}
26
+ }
27
+
28
+ bundles = bundles.length > 0 ? bundles : [
29
+ 'writing-style.md',
30
+ 'code-review.md',
31
+ 'documentation.md',
32
+ 'prompt-engineering.md'
33
+ ];
34
+
35
+ for (const bundle of bundles) {
36
+ console.log(` ${chalk.cyan('●')} ${chalk.white(bundle.replace('.md', ''))}`);
37
+ }
38
+
39
+ if (bundles.length === 0) {
40
+ console.log(chalk.gray(' YΓΌklΓΌ bundle bulunamadΔ±.\n'));
41
+ }
42
+
43
+ console.log(chalk.gray('\n OpenProse, NatureCo\'nun prose skills paketidir.\n'));
44
+ console.log(chalk.gray(' Skills yΓΌklemek iΓ§in:'));
45
+ console.log(chalk.cyan(' natureco skills install <name>\n'));
46
+ }
47
+
48
+ function showInfo() {
49
+ console.log(chalk.cyan('\n πŸ“– OpenProse\n'));
50
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
51
+ console.log(chalk.gray(' OpenProse β€” Prose skills bundle for NatureCo CLI.'));
52
+ console.log(chalk.gray(' Provides writing, review, documentation, and prompt'));
53
+ console.log(chalk.gray(' engineering skill definitions.'));
54
+ console.log();
55
+ console.log(chalk.gray(' Version: 1.0.0'));
56
+ console.log(chalk.gray(' ID: open-prose'));
57
+ console.log(chalk.gray(' Type: skills-bundle'));
58
+ console.log();
59
+ console.log(chalk.gray(' Included skills:'));
60
+ console.log(chalk.cyan(' writing-style') + chalk.gray(' Writing style guide'));
61
+ console.log(chalk.cyan(' code-review') + chalk.gray(' Code review guidelines'));
62
+ console.log(chalk.cyan(' documentation') + chalk.gray(' Documentation best practices'));
63
+ console.log(chalk.cyan(' prompt-engineering') + chalk.gray(' Prompt engineering techniques'));
64
+ console.log();
65
+ }
66
+
67
+ module.exports = openProse;
@@ -1,107 +1,108 @@
1
- const chalk = require('chalk');
2
- const { getConfig, saveConfig } = require('../utils/config');
3
-
4
- async function pairing(args) {
5
- const [action, ...params] = (args || []);
6
-
7
- if (!action || action === 'list') return listPairing();
8
- if (action === 'approve') return approvePairing(params[0], params[1]);
9
- if (action === 'reject') return rejectPairing(params[0]);
10
-
11
- console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
12
- console.log(chalk.gray(' KullanΔ±m: natureco pairing [list|approve|reject]\n'));
13
- process.exit(1);
14
- }
15
-
16
- function listPairing() {
17
- const config = getConfig();
18
- const pending = config.pendingPairings || [];
19
-
20
- console.log('');
21
- console.log(chalk.gray(' ' + '─'.repeat(48)));
22
- console.log(chalk.cyan.bold('\n Bekleyen Eşleştirmeler\n'));
23
-
24
- if (pending.length === 0) {
25
- console.log(chalk.gray(' Bekleyen eşleştirme yok.\n'));
26
- console.log(chalk.gray(' Telegram bağlamak için: ') + chalk.cyan('natureco telegram connect'));
27
- console.log(chalk.gray(' WhatsApp bağlamak için: ') + chalk.cyan('natureco whatsapp connect\n'));
28
- return;
29
- }
30
-
31
- pending.forEach((p, i) => {
32
- console.log(chalk.white(` ${i + 1}. ${p.channel} β€” ${p.id}`));
33
- console.log(chalk.gray(` Kod: ${p.code} Β· ${new Date(p.createdAt).toLocaleString('tr-TR')}`));
34
- console.log('');
35
- });
36
-
37
- console.log(chalk.gray(' Onaylamak iΓ§in: ') + chalk.cyan('natureco pairing approve <kanal> <kod>'));
38
- console.log(chalk.gray(' Reddetmek iΓ§in: ') + chalk.cyan('natureco pairing reject <kod>\n'));
39
- }
40
-
41
- function approvePairing(channel, code) {
42
- if (!channel || !code) {
43
- console.log(chalk.red('\n ❌ Kanal ve kod gerekli\n'));
44
- console.log(chalk.gray(' KullanΔ±m: natureco pairing approve <telegram|whatsapp> <KOD>\n'));
45
- process.exit(1);
46
- }
47
-
48
- const config = getConfig();
49
- const pending = config.pendingPairings || [];
50
- const idx = pending.findIndex(p => p.code === code && p.channel === channel);
51
-
52
- if (idx === -1) {
53
- console.log(chalk.yellow(`\n ⚠ Eşleştirme bulunamadı: ${channel} ${code}\n`));
54
- console.log(chalk.gray(' Bekleyen listesi: ') + chalk.cyan('natureco pairing list\n'));
55
- return;
56
- }
57
-
58
- const pairing = pending[idx];
59
- pending.splice(idx, 1);
60
-
61
- // Onaylanan kanalΔ± izin listesine ekle
62
- if (channel === 'telegram') {
63
- const allowed = config.telegramAllowedChats || [];
64
- if (!allowed.includes(pairing.id)) {
65
- allowed.push(pairing.id);
66
- config.telegramAllowedChats = allowed;
67
- }
68
- } else if (channel === 'whatsapp') {
69
- const allowed = config.whatsappAllowedNumbers || [];
70
- const num = pairing.id.replace(/\D/g, '');
71
- if (!allowed.includes(num)) {
72
- allowed.push(num);
73
- config.whatsappAllowedNumbers = allowed;
74
- }
75
- }
76
-
77
- config.pendingPairings = pending;
78
- saveConfig(config);
79
-
80
- console.log(chalk.green(`\n βœ“ Eşleştirme onaylandΔ±: ${channel} β€” ${pairing.id}\n`));
81
- console.log(chalk.gray(' Gateway\'i yeniden başlatın: ') + chalk.cyan('natureco gateway stop && natureco gateway start\n'));
82
- }
83
-
84
- function rejectPairing(code) {
85
- if (!code) {
86
- console.log(chalk.red('\n ❌ Kod gerekli\n'));
87
- console.log(chalk.gray(' KullanΔ±m: natureco pairing reject <KOD>\n'));
88
- process.exit(1);
89
- }
90
-
91
- const config = getConfig();
92
- const pending = config.pendingPairings || [];
93
- const idx = pending.findIndex(p => p.code === code);
94
-
95
- if (idx === -1) {
96
- console.log(chalk.yellow(`\n ⚠ Eşleştirme bulunamadı: ${code}\n`));
97
- return;
98
- }
99
-
100
- pending.splice(idx, 1);
101
- config.pendingPairings = pending;
102
- saveConfig(config);
103
-
104
- console.log(chalk.gray(`\n β—‹ Eşleştirme reddedildi: ${code}\n`));
105
- }
106
-
107
- module.exports = pairing;
1
+ const chalk = require('chalk');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+
6
+ const PAIRINGS_FILE = path.join(os.homedir(), '.natureco', 'pairings.json');
7
+
8
+ function loadPairings() {
9
+ if (!fs.existsSync(PAIRINGS_FILE)) return [];
10
+ try { return JSON.parse(fs.readFileSync(PAIRINGS_FILE, 'utf8')); }
11
+ catch { return []; }
12
+ }
13
+
14
+ function savePairings(pairings) {
15
+ const dir = path.dirname(PAIRINGS_FILE);
16
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
17
+ fs.writeFileSync(PAIRINGS_FILE, JSON.stringify(pairings, null, 2), 'utf8');
18
+ }
19
+
20
+ function genId() {
21
+ return Date.now().toString(36) + Math.random().toString(36).slice(2, 8).toUpperCase();
22
+ }
23
+
24
+ function pairing(args) {
25
+ const [action, ...params] = args || [];
26
+
27
+ if (!action || action === 'list') return cmdList();
28
+ if (action === 'approve') return cmdApprove(params[0]);
29
+ if (action === 'reject') return cmdReject(params[0]);
30
+ if (action === 'generate') return cmdGenerate();
31
+
32
+ console.log(chalk.red(`\n Unknown pairing action: ${action}\n`));
33
+ console.log(chalk.gray(' Usage: natureco pairing <action> [params]'));
34
+ console.log(chalk.gray(' Actions: list, approve <id>, reject <id>, generate\n'));
35
+ process.exit(1);
36
+ }
37
+
38
+ function cmdList() {
39
+ const pairings = loadPairings();
40
+ const pending = pairings.filter(p => p.status === 'pending');
41
+
42
+ console.log(chalk.cyan(`\n Pending Pairings (${pending.length})\n`));
43
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
44
+
45
+ if (pending.length === 0) {
46
+ console.log(chalk.gray(' No pending pairings.\n'));
47
+ return;
48
+ }
49
+
50
+ for (const p of pending) {
51
+ console.log(` ${chalk.white(p.id)}`);
52
+ console.log(chalk.gray(` Code: ${p.code}`));
53
+ console.log(chalk.gray(` Node: ${p.nodeName || 'β€”'}`));
54
+ console.log(chalk.gray(` Since: ${p.createdAt ? new Date(p.createdAt).toLocaleString() : 'β€”'}`));
55
+ }
56
+ console.log('');
57
+ }
58
+
59
+ function cmdApprove(id) {
60
+ if (!id) { console.log(chalk.red('\n Usage: natureco pairing approve <id>\n')); process.exit(1); }
61
+
62
+ const pairings = loadPairings();
63
+ const p = pairings.find(x => x.id === id && x.status === 'pending');
64
+
65
+ if (!p) { console.log(chalk.yellow(`\n No pending pairing with id "${id}".\n`)); return; }
66
+
67
+ p.status = 'approved';
68
+ p.approvedAt = new Date().toISOString();
69
+ savePairings(pairings);
70
+ console.log(chalk.green(`\n Pairing "${id}" approved.\n`));
71
+ }
72
+
73
+ function cmdReject(id) {
74
+ if (!id) { console.log(chalk.red('\n Usage: natureco pairing reject <id>\n')); process.exit(1); }
75
+
76
+ const pairings = loadPairings();
77
+ const idx = pairings.findIndex(x => x.id === id && x.status === 'pending');
78
+
79
+ if (idx === -1) { console.log(chalk.yellow(`\n No pending pairing with id "${id}".\n`)); return; }
80
+
81
+ pairings.splice(idx, 1);
82
+ savePairings(pairings);
83
+ console.log(chalk.gray(`\n Pairing "${id}" rejected.\n`));
84
+ }
85
+
86
+ function cmdGenerate() {
87
+ const code = genId();
88
+ const pairings = loadPairings();
89
+
90
+ const entry = {
91
+ id: `pair_${Date.now().toString(36)}`,
92
+ code,
93
+ status: 'pending',
94
+ createdAt: new Date().toISOString(),
95
+ };
96
+
97
+ pairings.push(entry);
98
+ savePairings(pairings);
99
+
100
+ console.log(chalk.cyan('\n Pairing Code Generated\n'));
101
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
102
+ console.log(` ${chalk.white('Code:')} ${chalk.green(code)}`);
103
+ console.log(` ${chalk.white('ID:')} ${chalk.gray(entry.id)}`);
104
+ console.log('');
105
+ console.log(chalk.gray(' Share this code with the node to pair.\n'));
106
+ }
107
+
108
+ module.exports = pairing;
@@ -0,0 +1,206 @@
1
+ const chalk = require('chalk');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+ const os = require('os');
5
+
6
+ const PATHS_FILE = path.join(os.homedir(), '.natureco', 'paths.json');
7
+
8
+ function loadPaths() {
9
+ try {
10
+ if (fs.existsSync(PATHS_FILE)) return JSON.parse(fs.readFileSync(PATHS_FILE, 'utf8'));
11
+ } catch {}
12
+ return {};
13
+ }
14
+
15
+ function savePaths(data) {
16
+ const dir = path.dirname(PATHS_FILE);
17
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
18
+ fs.writeFileSync(PATHS_FILE, JSON.stringify(data, null, 2));
19
+ }
20
+
21
+ function pathCmd(args) {
22
+ const [action, ...params] = args || [];
23
+
24
+ if (!action) return listPaths();
25
+ if (action === 'resolve') return resolvePath(params.join('/'));
26
+ if (action === 'find') return findPath(params[0]);
27
+ if (action === 'set') return setPath(params[0], params.slice(1).join(' '));
28
+ if (action === 'validate') return validatePath(params[0]);
29
+ if (action === 'emit') return emitPath(params[0]);
30
+
31
+ console.log(chalk.red(`\n ❌ Unknown path action: ${action}\n`));
32
+ console.log(chalk.gray(' Usage: natureco path <resolve|find|set|validate|emit> [args]\n'));
33
+ process.exit(1);
34
+ }
35
+
36
+ function listPaths() {
37
+ const paths = loadPaths();
38
+ const entries = Object.entries(paths);
39
+
40
+ console.log(chalk.cyan('\n πŸ“ Registered Paths\n'));
41
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
42
+
43
+ if (entries.length === 0) {
44
+ console.log(chalk.gray(' No paths registered.\n'));
45
+ console.log(chalk.gray(' Register a path:'));
46
+ console.log(chalk.cyan(' natureco path set <name> <path>\n'));
47
+ return;
48
+ }
49
+
50
+ for (const [name, p] of entries) {
51
+ const exists = fs.existsSync(p);
52
+ const icon = exists ? chalk.green('●') : chalk.red('β—‹');
53
+ console.log(` ${icon} ${chalk.white(name)}`);
54
+ console.log(` ${chalk.gray('Path:')} ${chalk.cyan(p)}`);
55
+ console.log(` ${chalk.gray('Exists:')} ${exists ? chalk.green('Yes') : chalk.red('No')}`);
56
+ }
57
+ console.log();
58
+ }
59
+
60
+ function resolvePath(uri) {
61
+ if (!uri) {
62
+ console.log(chalk.red('\n ❌ URI gerekli\n'));
63
+ console.log(chalk.gray(' Usage: natureco path resolve nc://path\n'));
64
+ process.exit(1);
65
+ }
66
+
67
+ const fullUri = uri.startsWith('nc://') ? uri : `nc://${uri}`;
68
+ const parts = fullUri.replace('nc://', '').split('/').filter(Boolean);
69
+ const name = parts[0];
70
+ const sub = parts.slice(1).join('/');
71
+
72
+ const registry = loadPaths();
73
+ const registered = registry[name];
74
+
75
+ if (registered) {
76
+ const resolved = sub ? path.join(registered, sub) : registered;
77
+ const exists = fs.existsSync(resolved);
78
+
79
+ console.log(chalk.cyan('\n πŸ“ Path Resolution\n'));
80
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
81
+ console.log(` ${chalk.white('URI:')} ${chalk.cyan(fullUri)}`);
82
+ console.log(` ${chalk.white('Name:')} ${chalk.white(name)}`);
83
+ console.log(` ${chalk.white('Path:')} ${chalk.white(resolved)}`);
84
+ console.log(` ${chalk.white('From registry:')} ${chalk.gray(registered)}`);
85
+ console.log(` ${chalk.white('Exists:')} ${exists ? chalk.green('Yes') : chalk.red('No')}`);
86
+ console.log();
87
+ return;
88
+ }
89
+
90
+ const resolved = path.resolve(uri);
91
+ const exists = fs.existsSync(resolved);
92
+
93
+ console.log(chalk.cyan('\n πŸ“ Path Resolution\n'));
94
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
95
+ console.log(` ${chalk.white('URI:')} ${chalk.cyan(fullUri)}`);
96
+ console.log(` ${chalk.white('Path:')} ${chalk.white(resolved)}`);
97
+ console.log(` ${chalk.white('From registry:')} ${chalk.gray('No')}`);
98
+ console.log(` ${chalk.white('Exists:')} ${exists ? chalk.green('Yes') : chalk.red('No')}`);
99
+ console.log();
100
+ }
101
+
102
+ function findPath(name) {
103
+ if (!name) {
104
+ console.log(chalk.red('\n ❌ Name gerekli\n'));
105
+ process.exit(1);
106
+ }
107
+
108
+ const paths = loadPaths();
109
+ const entry = paths[name];
110
+
111
+ if (!entry) {
112
+ console.log(chalk.yellow(`\n πŸ” Path not found: ${name}\n`));
113
+ console.log(chalk.gray(' Register it:'));
114
+ console.log(chalk.cyan(` natureco path set ${name} <path>\n`));
115
+ return;
116
+ }
117
+
118
+ const exists = fs.existsSync(entry);
119
+
120
+ console.log(chalk.cyan('\n πŸ” Path Lookup\n'));
121
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
122
+ console.log(` ${chalk.white('Name:')} ${chalk.cyan(name)}`);
123
+ console.log(` ${chalk.white('Path:')} ${chalk.white(entry)}`);
124
+ console.log(` ${chalk.white('Exists:')} ${exists ? chalk.green('Yes') : chalk.red('No')}`);
125
+ console.log();
126
+ }
127
+
128
+ function setPath(name, targetPath) {
129
+ if (!name) {
130
+ console.log(chalk.red('\n ❌ Name gerekli\n'));
131
+ process.exit(1);
132
+ }
133
+ if (!targetPath) {
134
+ console.log(chalk.red('\n ❌ Path gerekli\n'));
135
+ process.exit(1);
136
+ }
137
+
138
+ const resolved = path.resolve(targetPath);
139
+ const paths = loadPaths();
140
+ paths[name] = resolved;
141
+ savePaths(paths);
142
+
143
+ console.log(chalk.green(`\n βœ… Path registered: ${name}\n`));
144
+ console.log(chalk.gray(` Name: ${chalk.white(name)}`));
145
+ console.log(chalk.gray(` Path: ${chalk.cyan(resolved)}\n`));
146
+ }
147
+
148
+ function validatePath(name) {
149
+ if (!name) {
150
+ console.log(chalk.red('\n ❌ Name gerekli\n'));
151
+ process.exit(1);
152
+ }
153
+
154
+ const paths = loadPaths();
155
+ const entry = paths[name];
156
+
157
+ if (!entry) {
158
+ console.log(chalk.yellow(`\n ⚠️ Not registered: ${name}\n`));
159
+ process.exit(1);
160
+ }
161
+
162
+ const exists = fs.existsSync(entry);
163
+
164
+ console.log(chalk.cyan('\n βœ… Path Validation\n'));
165
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
166
+ console.log(` ${chalk.white('Name:')} ${chalk.cyan(name)}`);
167
+ console.log(` ${chalk.white('Path:')} ${chalk.white(entry)}`);
168
+ console.log(` ${chalk.white('Exists:')} ${exists ? chalk.green('Yes') : chalk.red('No')}`);
169
+
170
+ if (exists) {
171
+ try {
172
+ const stat = fs.statSync(entry);
173
+ console.log(` ${chalk.white('Type:')} ${stat.isDirectory() ? chalk.blue('Directory') : chalk.gray('File')}`);
174
+ console.log(` ${chalk.white('Size:')} ${chalk.gray(stat.isDirectory() ? '-' : `${(stat.size / 1024).toFixed(1)} KB`)}`);
175
+ } catch {}
176
+ }
177
+
178
+ console.log();
179
+ }
180
+
181
+ function emitPath(name) {
182
+ if (!name) {
183
+ console.log(chalk.red('\n ❌ Name gerekli\n'));
184
+ process.exit(1);
185
+ }
186
+
187
+ const paths = loadPaths();
188
+ const entry = paths[name];
189
+
190
+ if (!entry) {
191
+ console.log(chalk.yellow(`\n ⚠️ Not registered: ${name}\n`));
192
+ process.exit(1);
193
+ }
194
+
195
+ const uri = `nc://${name}`;
196
+
197
+ console.log(chalk.cyan('\n πŸ”— Clickable URI\n'));
198
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
199
+ console.log(` ${chalk.white('Name:')} ${chalk.cyan(name)}`);
200
+ console.log(` ${chalk.white('URI:')} ${chalk.bold.green(uri)}`);
201
+ console.log(` ${chalk.white('Path:')} ${chalk.gray(entry)}`);
202
+ console.log();
203
+ console.log(chalk.gray(' Copy the URI above to use in nc://-aware tools.\n'));
204
+ }
205
+
206
+ module.exports = pathCmd;
@@ -21,9 +21,10 @@ async function plugins(args) {
21
21
  if (action === 'search') return searchHandler(params.join(' '), opts);
22
22
  if (action === 'doctor') return doctorHandler();
23
23
  if (action === 'registry') return registryHandler(opts);
24
+ if (action === 'marketplace') return marketplaceHandler(opts);
24
25
 
25
26
  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
+ console.log(chalk.gray(' KullanΔ±m: natureco plugins [list|install|uninstall|enable|disable|info|update|search|doctor|registry|marketplace]\n'));
27
28
  process.exit(1);
28
29
  } catch (err) {
29
30
  handleError(err);
@@ -412,4 +413,37 @@ function registryHandler(opts) {
412
413
  console.log('');
413
414
  }
414
415
 
416
+ async function marketplaceHandler(opts) {
417
+ console.log(chalk.cyan.bold('\n Plugin Marketplace\n'));
418
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
419
+ console.log(chalk.gray('\n Fetching available plugins...\n'));
420
+
421
+ try {
422
+ const res = await fetch('https://natureco.me/api/plugins?limit=' + (opts.limit || 20), {
423
+ signal: AbortSignal.timeout(5000),
424
+ });
425
+ if (res.ok) {
426
+ const data = await res.json();
427
+ const plugins = data.plugins || data.results || [];
428
+ if (plugins.length === 0) {
429
+ console.log(chalk.yellow(' No plugins available in marketplace.\n'));
430
+ return;
431
+ }
432
+ console.log(chalk.white(' Available Plugins (' + plugins.length + ')\n'));
433
+ for (const p of plugins.slice(0, opts.limit || 20)) {
434
+ console.log(chalk.cyan(' ' + (p.name || p.id)));
435
+ if (p.description) console.log(chalk.gray(' ' + p.description.slice(0, 80)));
436
+ console.log(chalk.gray(' Install: natureco plugins install ' + (p.id || p.name)));
437
+ console.log('');
438
+ }
439
+ } else {
440
+ console.log(chalk.yellow(' Marketplace unavailable (HTTP ' + res.status + ')\n'));
441
+ console.log(chalk.gray(' Try: natureco plugins search <query>\n'));
442
+ }
443
+ } catch (err) {
444
+ console.log(chalk.yellow(' Marketplace unavailable: ' + err.message + '\n'));
445
+ console.log(chalk.gray(' Try: natureco plugins search <query>\n'));
446
+ }
447
+ }
448
+
415
449
  module.exports = plugins;