natureco-cli 2.23.28 → 2.23.30

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 (96) hide show
  1. package/README.md +94 -11
  2. package/bin/natureco.js +470 -10
  3. package/package.json +10 -6
  4. package/src/commands/admin-rpc.js +219 -0
  5. package/src/commands/agent.js +89 -0
  6. package/src/commands/approvals.js +53 -0
  7. package/src/commands/backup.js +124 -0
  8. package/src/commands/bonjour.js +167 -0
  9. package/src/commands/capability.js +64 -0
  10. package/src/commands/channels.js +94 -4
  11. package/src/commands/chat.js +11 -25
  12. package/src/commands/clickclack.js +130 -0
  13. package/src/commands/commitments.js +32 -0
  14. package/src/commands/completion.js +76 -0
  15. package/src/commands/config.js +111 -68
  16. package/src/commands/configure.js +93 -0
  17. package/src/commands/crestodian.js +92 -0
  18. package/src/commands/daemon.js +60 -0
  19. package/src/commands/device-pair.js +248 -0
  20. package/src/commands/devices.js +110 -0
  21. package/src/commands/directory.js +47 -0
  22. package/src/commands/dns.js +58 -0
  23. package/src/commands/docs.js +43 -0
  24. package/src/commands/doctor.js +121 -16
  25. package/src/commands/exec-policy.js +71 -0
  26. package/src/commands/gateway-server.js +1175 -30
  27. package/src/commands/gateway.js +11 -20
  28. package/src/commands/health.js +18 -0
  29. package/src/commands/help.js +6 -0
  30. package/src/commands/imessage.js +169 -0
  31. package/src/commands/infer.js +73 -0
  32. package/src/commands/irc.js +119 -0
  33. package/src/commands/mattermost.js +164 -0
  34. package/src/commands/memory-cmd.js +134 -1
  35. package/src/commands/message.js +30 -4
  36. package/src/commands/migrate.js +213 -2
  37. package/src/commands/models.js +584 -216
  38. package/src/commands/node.js +98 -0
  39. package/src/commands/nodes.js +106 -0
  40. package/src/commands/oc-path.js +200 -0
  41. package/src/commands/onboard.js +70 -0
  42. package/src/commands/open-prose.js +67 -0
  43. package/src/commands/plugins.js +415 -172
  44. package/src/commands/policy.js +176 -0
  45. package/src/commands/proxy.js +155 -0
  46. package/src/commands/qr.js +28 -0
  47. package/src/commands/sandbox.js +125 -0
  48. package/src/commands/secrets.js +118 -0
  49. package/src/commands/security.js +149 -1
  50. package/src/commands/setup.js +114 -10
  51. package/src/commands/signal.js +495 -0
  52. package/src/commands/skills.js +20 -29
  53. package/src/commands/sms.js +168 -0
  54. package/src/commands/system.js +53 -0
  55. package/src/commands/tasks.js +328 -79
  56. package/src/commands/terminal.js +21 -0
  57. package/src/commands/thread-ownership.js +157 -0
  58. package/src/commands/transcripts.js +72 -0
  59. package/src/commands/voice.js +82 -0
  60. package/src/commands/vydra.js +98 -0
  61. package/src/commands/webhooks.js +79 -0
  62. package/src/commands/whatsapp.js +7 -21
  63. package/src/commands/workboard.js +207 -0
  64. package/src/tools/audio_understanding.js +154 -0
  65. package/src/tools/bash.js +63 -29
  66. package/src/tools/browser.js +112 -0
  67. package/src/tools/canvas.js +104 -0
  68. package/src/tools/document_extract.js +84 -0
  69. package/src/tools/duckduckgo.js +54 -0
  70. package/src/tools/exa_search.js +66 -0
  71. package/src/tools/firecrawl.js +104 -0
  72. package/src/tools/image_generation.js +99 -0
  73. package/src/tools/llm_task.js +118 -0
  74. package/src/tools/media_understanding.js +128 -0
  75. package/src/tools/music_generation.js +113 -0
  76. package/src/tools/parallel_search.js +77 -0
  77. package/src/tools/phone_control.js +80 -0
  78. package/src/tools/phone_control_enhanced.js +184 -0
  79. package/src/tools/searxng.js +61 -0
  80. package/src/tools/speech_to_text.js +135 -0
  81. package/src/tools/text_to_speech.js +105 -0
  82. package/src/tools/thread_ownership.js +88 -0
  83. package/src/tools/video_generation.js +72 -0
  84. package/src/tools/web_readability.js +104 -0
  85. package/src/utils/api.js +3 -20
  86. package/src/utils/approvals.js +297 -0
  87. package/src/utils/background.js +223 -66
  88. package/src/utils/baileys.js +21 -0
  89. package/src/utils/config.js +141 -10
  90. package/src/utils/errors.js +148 -0
  91. package/src/utils/inquirer-wrapper.js +1 -2
  92. package/src/utils/memory.js +200 -0
  93. package/src/utils/path-utils.js +13 -13
  94. package/src/utils/plugin-registry.js +238 -0
  95. package/src/utils/secrets.js +177 -0
  96. package/src/utils/skills.js +10 -23
@@ -0,0 +1,98 @@
1
+ const chalk = require('chalk');
2
+ const os = require('os');
3
+ const http = require('http');
4
+
5
+ let nodeServer = null;
6
+
7
+ function nodeCmd(args) {
8
+ const [action, ...params] = args || [];
9
+
10
+ if (!action || action === 'status') return statusNode();
11
+ if (action === 'start') return startNode(params[0]);
12
+ if (action === 'stop') return stopNode();
13
+ if (action === 'info') return infoNode();
14
+
15
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
16
+ console.log(chalk.gray(' Kullanım: natureco node [status|start|stop|info]\n'));
17
+ process.exit(1);
18
+ }
19
+
20
+ function statusNode() {
21
+ console.log(chalk.cyan('\n 🖥️ Node Host\n'));
22
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
23
+ console.log(` ${chalk.white('Status:')} ${nodeServer ? chalk.green('Running on port ' + nodeServer.port) : chalk.gray('idle')}`);
24
+ console.log(` ${chalk.white('Host:')} ${os.hostname()}`);
25
+ console.log(` ${chalk.white('Platform:')} ${process.platform}`);
26
+ console.log(` ${chalk.white('Memory:')} ${Math.round(os.freemem() / 1024 / 1024)}MB free`);
27
+ console.log(` ${chalk.white('CPU:')} ${os.cpus()[0]?.model || 'unknown'}`);
28
+ console.log(chalk.gray('\n Start: ') + chalk.cyan('natureco node start [port]'));
29
+ console.log(chalk.gray(' Info: ') + chalk.cyan('natureco node info'));
30
+ console.log();
31
+ }
32
+
33
+ function startNode(portStr) {
34
+ if (nodeServer) {
35
+ console.log(chalk.yellow('\n ⚠️ Node host already running\n'));
36
+ return;
37
+ }
38
+
39
+ const port = parseInt(portStr, 10) || 0;
40
+ const server = http.createServer((req, res) => {
41
+ if (req.url === '/health' || req.url === '/') {
42
+ res.writeHead(200, { 'Content-Type': 'application/json' });
43
+ res.end(JSON.stringify({
44
+ status: 'ok',
45
+ hostname: os.hostname(),
46
+ platform: process.platform,
47
+ node: process.version,
48
+ uptime: Math.floor(process.uptime()),
49
+ memory: { free: os.freemem(), total: os.totalmem() },
50
+ cpus: os.cpus().length,
51
+ loadavg: os.loadavg()
52
+ }));
53
+ } else {
54
+ res.writeHead(404);
55
+ res.end('Not Found');
56
+ }
57
+ });
58
+
59
+ server.listen(port, () => {
60
+ nodeServer = server;
61
+ nodeServer.port = server.address().port;
62
+ console.log(chalk.green(`\n ✅ Node host running on http://localhost:${nodeServer.port}\n`));
63
+ console.log(chalk.gray(` Health endpoint: http://localhost:${nodeServer.port}/health\n`));
64
+ console.log(chalk.gray(' Press Ctrl+C to stop.\n'));
65
+ });
66
+ }
67
+
68
+ function stopNode() {
69
+ if (!nodeServer) {
70
+ console.log(chalk.yellow('\n ⚠️ Node host not running\n'));
71
+ return;
72
+ }
73
+ nodeServer.close(() => {
74
+ console.log(chalk.gray('\n 🛑 Node host stopped\n'));
75
+ nodeServer = null;
76
+ });
77
+ }
78
+
79
+ function infoNode() {
80
+ console.log(chalk.cyan('\n 🖥️ Node Info\n'));
81
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
82
+ console.log(` ${chalk.white('Node:')} ${process.version}`);
83
+ console.log(` ${chalk.white('Platform:')} ${process.platform} ${os.release()}`);
84
+ console.log(` ${chalk.white('Arch:')} ${process.arch}`);
85
+ console.log(` ${chalk.white('Hostname:')} ${os.hostname()}`);
86
+ console.log(` ${chalk.white('CPUs:')} ${os.cpus().length}`);
87
+ for (let i = 0; i < Math.min(os.cpus().length, 4); i++) {
88
+ console.log(` ${chalk.gray(`${i}: ${os.cpus()[i].model}`)}`);
89
+ }
90
+ if (os.cpus().length > 4) console.log(` ${chalk.gray(`… and ${os.cpus().length - 4} more`)}`);
91
+ console.log(` ${chalk.white('Memory:')} ${Math.round(os.totalmem() / 1024 / 1024 / 1024)}GB total, ${Math.round(os.freemem() / 1024 / 1024)}MB free`);
92
+ console.log(` ${chalk.white('Load:')} ${os.loadavg().map(l => l.toFixed(2)).join(', ')}`);
93
+ console.log(` ${chalk.white('Uptime:')} ${Math.floor(os.uptime() / 3600)}h ${Math.floor((os.uptime() % 3600) / 60)}m`);
94
+ console.log(` ${chalk.white('Interfaces:')} ${Object.keys(os.networkInterfaces()).filter(k => k !== 'lo').join(', ') || 'none'}`);
95
+ console.log();
96
+ }
97
+
98
+ module.exports = nodeCmd;
@@ -0,0 +1,106 @@
1
+ const chalk = require('chalk');
2
+ const { getConfig, saveConfig } = require('../utils/config');
3
+ const crypto = require('crypto');
4
+
5
+ function nodes(args) {
6
+ const [action, ...params] = args || [];
7
+
8
+ if (!action || action === 'list') return listNodes();
9
+ if (action === 'pair') return pairNode(params[0]);
10
+ if (action === 'approve') return approveNode(params[0]);
11
+ if (action === 'reject') return rejectNode(params[0]);
12
+ if (action === 'remove') return removeNode(params[0]);
13
+ if (action === 'rename') return renameNode(params[0], params.slice(1).join(' '));
14
+
15
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
16
+ console.log(chalk.gray(' Kullanım: natureco nodes [list|pair|approve|reject|remove|rename]\n'));
17
+ process.exit(1);
18
+ }
19
+
20
+ function listNodes() {
21
+ const config = getConfig();
22
+ const nodes = config.pairedNodes || [];
23
+
24
+ console.log(chalk.cyan('\n 🖥️ Paired Nodes\n'));
25
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
26
+
27
+ if (nodes.length === 0) {
28
+ console.log(chalk.gray(' No paired nodes.\n'));
29
+ return;
30
+ }
31
+
32
+ for (const n of nodes) {
33
+ console.log(` ${chalk.green('●')} ${chalk.white(n.name || n.id)}`);
34
+ console.log(` ${chalk.gray('ID:')} ${n.id}`);
35
+ console.log(` ${chalk.gray('URL:')} ${n.url || 'local'}`);
36
+ console.log(` ${chalk.gray('Key:')} ${n.key ? n.key.substring(0, 8) + '…' : 'none'}`);
37
+ }
38
+ console.log();
39
+ }
40
+
41
+ function pairNode(url) {
42
+ if (!url) {
43
+ console.log(chalk.red('\n ❌ Node URL gerekli\n'));
44
+ process.exit(1);
45
+ }
46
+
47
+ const config = getConfig();
48
+ if (!config.pairedNodes) config.pairedNodes = [];
49
+
50
+ const id = `node_${crypto.randomBytes(8).toString('hex')}`;
51
+ const key = crypto.randomBytes(16).toString('hex');
52
+
53
+ config.pairedNodes.push({ id, url, key, name: url, pairedAt: new Date().toISOString() });
54
+ saveConfig(config);
55
+
56
+ console.log(chalk.green(`\n ✅ Node paired: ${url}\n`));
57
+ }
58
+
59
+ function approveNode(id) {
60
+ console.log(chalk.green(`\n ✅ Node approved: ${id}\n`));
61
+ }
62
+
63
+ function rejectNode(id) {
64
+ console.log(chalk.gray(`\n ❌ Node rejected: ${id}\n`));
65
+ }
66
+
67
+ function removeNode(id) {
68
+ if (!id) {
69
+ console.log(chalk.red('\n ❌ Node ID gerekli\n'));
70
+ process.exit(1);
71
+ }
72
+
73
+ const config = getConfig();
74
+ const nodes = config.pairedNodes || [];
75
+ const idx = nodes.findIndex(n => n.id === id);
76
+
77
+ if (idx === -1) {
78
+ console.log(chalk.red(`\n ❌ Node bulunamadı: ${id}\n`));
79
+ process.exit(1);
80
+ }
81
+
82
+ nodes.splice(idx, 1);
83
+ config.pairedNodes = nodes;
84
+ saveConfig(config);
85
+ console.log(chalk.gray(`\n 🗑️ Node removed: ${id}\n`));
86
+ }
87
+
88
+ function renameNode(id, name) {
89
+ if (!id || !name) {
90
+ console.log(chalk.red('\n ❌ Node ID ve name gerekli\n'));
91
+ process.exit(1);
92
+ }
93
+
94
+ const config = getConfig();
95
+ const node = (config.pairedNodes || []).find(n => n.id === id);
96
+ if (!node) {
97
+ console.log(chalk.red(`\n ❌ Node bulunamadı: ${id}\n`));
98
+ process.exit(1);
99
+ }
100
+
101
+ node.name = name;
102
+ saveConfig(config);
103
+ console.log(chalk.green(`\n ✅ Node renamed: ${name}\n`));
104
+ }
105
+
106
+ module.exports = nodes;
@@ -0,0 +1,200 @@
1
+ const chalk = require('chalk');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+ const os = require('os');
5
+
6
+ function normalizeNcPath(uri) {
7
+ if (!uri) return null;
8
+
9
+ const str = uri.trim();
10
+
11
+ if (str.startsWith('nc://')) return str.slice(5);
12
+ if (str.startsWith('natureco://')) return str.slice(10);
13
+
14
+ return str;
15
+ }
16
+
17
+ function resolveNcPath(ncPath) {
18
+ if (!ncPath) return null;
19
+
20
+ const parts = ncPath.split('/').filter(Boolean);
21
+ const scope = parts[0];
22
+ const rest = parts.slice(1);
23
+
24
+ if (scope === 'workspace' || scope === 'w') {
25
+ return { type: 'workspace', path: rest.join('/') || '.', description: 'Workspace path' };
26
+ }
27
+
28
+ if (scope === 'home' || scope === 'h') {
29
+ return { type: 'home', path: path.join(os.homedir(), ...rest), description: 'Home directory' };
30
+ }
31
+
32
+ if (scope === 'config' || scope === 'c') {
33
+ const configDir = path.join(os.homedir(), '.natureco');
34
+ return { type: 'config', path: rest.length ? path.join(configDir, ...rest) : configDir, description: 'Config directory' };
35
+ }
36
+
37
+ if (scope === 'tmp' || scope === 't') {
38
+ return { type: 'tmp', path: path.join(os.tmpdir(), ...rest), description: 'Temp directory' };
39
+ }
40
+
41
+ if (scope === 'tools' || scope === 'tool') {
42
+ const toolsDir = path.join(__dirname, '..', 'tools');
43
+ return { type: 'tools', path: path.join(toolsDir, ...rest), description: 'Tools directory' };
44
+ }
45
+
46
+ if (scope === 'commands' || scope === 'cmd') {
47
+ const cmdsDir = path.join(__dirname, '..', 'commands');
48
+ return { type: 'commands', path: path.join(cmdsDir, ...rest), description: 'Commands directory' };
49
+ }
50
+
51
+ if (scope === 'project' || scope === 'p') {
52
+ return { type: 'project', path: rest.join('/') || '.', description: 'Project path (CWD)' };
53
+ }
54
+
55
+ if (scope === 'skills' || scope === 's') {
56
+ const skillsDir = path.join(__dirname, '..', '..', 'skills');
57
+ return { type: 'skills', path: path.join(skillsDir, ...rest), description: 'Skills directory' };
58
+ }
59
+
60
+ if (scope === 'data' || scope === 'd') {
61
+ const dataDir = path.join(os.homedir(), '.natureco', 'data');
62
+ return { type: 'data', path: rest.length ? path.join(dataDir, ...rest) : dataDir, description: 'Data directory' };
63
+ }
64
+
65
+ return { type: 'unknown', path: ncPath, description: 'Unresolved path' };
66
+ }
67
+
68
+ function ocPath(args) {
69
+ const [action, ...params] = args || [];
70
+
71
+ if (!action || action === 'resolve') return resolvePath(params.join('/'));
72
+ if (action === 'list') return listScopes();
73
+ if (action === 'cat') return catFile(params.join('/'));
74
+ if (action === 'ls') return lsPath(params.join('/'));
75
+
76
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
77
+ console.log(chalk.gray(' Kullanım: natureco oc-path [resolve|list|cat|ls] <path>\n'));
78
+ process.exit(1);
79
+ }
80
+
81
+ function resolvePath(uri) {
82
+ const ncPath = normalizeNcPath(uri);
83
+ if (!ncPath) {
84
+ console.log(chalk.red('\n ❌ Path gerekli\n'));
85
+ console.log(chalk.cyan(' natureco oc-path resolve nc://config\n'));
86
+ process.exit(1);
87
+ }
88
+
89
+ const resolved = resolveNcPath(ncPath);
90
+ if (!resolved) {
91
+ console.log(chalk.red(`\n ❌ Çözümlenemedi: ${ncPath}\n`));
92
+ process.exit(1);
93
+ }
94
+
95
+ const exists = fs.existsSync(resolved.path);
96
+
97
+ console.log(chalk.cyan('\n 📍 nc:// Path Resolution\n'));
98
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
99
+ console.log(` ${chalk.white('Scope:')} ${chalk.cyan(resolved.type)}`);
100
+ console.log(` ${chalk.white('Path:')} ${chalk.white(resolved.path)}`);
101
+ console.log(` ${chalk.white('Description:')} ${chalk.gray(resolved.description)}`);
102
+ console.log(` ${chalk.white('Exists:')} ${exists ? chalk.green('Yes') : chalk.red('No')}`);
103
+ console.log();
104
+ }
105
+
106
+ function listScopes() {
107
+ console.log(chalk.cyan('\n 📍 nc:// Path Scopes\n'));
108
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
109
+
110
+ const scopes = [
111
+ { alias: 'w', scope: 'workspace', desc: 'CWD altındaki dosyalar' },
112
+ { alias: 'p', scope: 'project', desc: 'Proje kökü (CWD)' },
113
+ { alias: 'h', scope: 'home', desc: 'Kullanıcı ana dizini (~)' },
114
+ { alias: 'c', scope: 'config', desc: '~/.natureco yapılandırma' },
115
+ { alias: 'd', scope: 'data', desc: '~/.natureco/data veri dizini' },
116
+ { alias: 't', scope: 'tmp', desc: 'Geçici dizin' },
117
+ { alias: 's', scope: 'skills', desc: 'Skill dizini' },
118
+ { alias: 'tool', scope: 'tools', desc: 'Araçlar dizini' },
119
+ { alias: 'cmd', scope: 'commands', desc: 'Komutlar dizini' }
120
+ ];
121
+
122
+ for (const s of scopes) {
123
+ console.log(` ${chalk.cyan(`nc://${s.scope}`)} ${chalk.gray(`(${s.alias})`)} ${chalk.white('-')} ${chalk.gray(s.desc)}`);
124
+ }
125
+
126
+ console.log(chalk.gray('\n Examples:'));
127
+ console.log(chalk.cyan(' natureco oc-path resolve nc://config'));
128
+ console.log(chalk.cyan(' natureco oc-path ls nc://tools'));
129
+ console.log(chalk.cyan(' natureco oc-path cat nc://c/settings.json'));
130
+ console.log();
131
+ }
132
+
133
+ function catFile(uri) {
134
+ const ncPath = normalizeNcPath(uri);
135
+ if (!ncPath) {
136
+ console.log(chalk.red('\n ❌ Path gerekli\n'));
137
+ process.exit(1);
138
+ }
139
+
140
+ const resolved = resolveNcPath(ncPath);
141
+ if (!resolved) {
142
+ console.log(chalk.red(`\n ❌ Çözümlenemedi: ${ncPath}\n`));
143
+ process.exit(1);
144
+ }
145
+
146
+ if (!fs.existsSync(resolved.path)) {
147
+ console.log(chalk.red(`\n ❌ Dosya bulunamadı: ${resolved.path}\n`));
148
+ process.exit(1);
149
+ }
150
+
151
+ const stat = fs.statSync(resolved.path);
152
+ if (stat.isDirectory()) {
153
+ console.log(chalk.yellow(`\n ⚠️ Bu bir dizin, dosya değil: ${resolved.path}\n`));
154
+ process.exit(1);
155
+ }
156
+
157
+ const content = fs.readFileSync(resolved.path, 'utf8');
158
+ console.log(chalk.gray(`\n 📄 ${resolved.path}\n`));
159
+ console.log(content);
160
+ if (!content.endsWith('\n')) console.log();
161
+ }
162
+
163
+ function lsPath(uri) {
164
+ const ncPath = normalizeNcPath(uri || 'nc://w');
165
+ if (!ncPath) {
166
+ console.log(chalk.red('\n ❌ Path gerekli\n'));
167
+ process.exit(1);
168
+ }
169
+
170
+ const resolved = resolveNcPath(ncPath);
171
+ if (!resolved) {
172
+ console.log(chalk.red(`\n ❌ Çözümlenemedi: ${ncPath}\n`));
173
+ process.exit(1);
174
+ }
175
+
176
+ if (!fs.existsSync(resolved.path)) {
177
+ console.log(chalk.red(`\n ❌ Dizin bulunamadı: ${resolved.path}\n`));
178
+ process.exit(1);
179
+ }
180
+
181
+ const stat = fs.statSync(resolved.path);
182
+ if (!stat.isDirectory()) {
183
+ console.log(chalk.yellow(`\n ⚠️ Bu bir dosya: ${resolved.path}\n`));
184
+ process.exit(1);
185
+ }
186
+
187
+ const items = fs.readdirSync(resolved.path);
188
+ console.log(chalk.cyan(`\n 📂 ${resolved.path}\n`));
189
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
190
+
191
+ for (const item of items) {
192
+ const fullPath = path.join(resolved.path, item);
193
+ const isDir = fs.statSync(fullPath).isDirectory();
194
+ console.log(` ${isDir ? chalk.blue('📁') : chalk.gray('📄')} ${isDir ? chalk.cyan(item + '/') : chalk.white(item)}`);
195
+ }
196
+
197
+ console.log();
198
+ }
199
+
200
+ module.exports = ocPath;
@@ -0,0 +1,70 @@
1
+ const chalk = require('chalk');
2
+ const readline = require('readline');
3
+
4
+ function rlQuestion(query) {
5
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
6
+ return new Promise(resolve => {
7
+ rl.question(query, answer => { rl.close(); resolve(answer.trim()); });
8
+ });
9
+ }
10
+
11
+ async function onboard(args) {
12
+ console.log(chalk.cyan('\n 🚀 NatureCo Onboarding\n'));
13
+ console.log(chalk.gray(' Welcome! Let\'s get you set up step by step.\n'));
14
+
15
+ const { getConfig, saveConfig } = require('../utils/config');
16
+ const config = getConfig();
17
+
18
+ const start = await rlQuestion(' Begin onboarding? [Y/n]: ');
19
+ if (start.toLowerCase() === 'n') {
20
+ console.log(chalk.gray('\n Skipped. You can always run: natureco onboard\n'));
21
+ return;
22
+ }
23
+
24
+ // Step 1: Provider
25
+ console.log(chalk.cyan('\n Step 1: AI Provider\n'));
26
+ const provider = await rlQuestion(` Provider (${config.provider || 'openai'}): `);
27
+ const model = await rlQuestion(` Model (${config.model || 'gpt-4o'}): `);
28
+ config.provider = provider || config.provider || 'openai';
29
+ config.model = model || config.model || 'gpt-4o';
30
+ saveConfig(config);
31
+ console.log(chalk.green(` ✅ ${config.provider}/${config.model}`));
32
+
33
+ // Step 2: API Key
34
+ if (!config.openaiApiKey && !config.anthropicApiKey) {
35
+ console.log(chalk.cyan('\n Step 2: API Key\n'));
36
+ const apiKey = await rlQuestion(` Enter your ${config.provider} API key: `);
37
+ if (apiKey) {
38
+ config[`${config.provider}ApiKey`] = apiKey;
39
+ saveConfig(config);
40
+ console.log(chalk.green(' ✅ API Key saved'));
41
+ }
42
+ }
43
+
44
+ // Step 3: Gateway
45
+ console.log(chalk.cyan('\n Step 3: Gateway\n'));
46
+ const gUrl = await rlQuestion(` Gateway URL (${config.gatewayUrl || 'ws://localhost:3848'}): `);
47
+ const gPort = await rlQuestion(` Port (${config.gatewayPort || 3848}): `);
48
+ config.gatewayUrl = gUrl || config.gatewayUrl || 'ws://localhost:3848';
49
+ config.gatewayPort = parseInt(gPort) || config.gatewayPort || 3848;
50
+ saveConfig(config);
51
+ console.log(chalk.green(' ✅ Gateway configured'));
52
+
53
+ // Step 4: Workspace
54
+ console.log(chalk.cyan('\n Step 4: Workspace\n'));
55
+ const wsPath = await rlQuestion(` Workspace path (${process.cwd()}): `);
56
+ if (wsPath) {
57
+ config.workspacePath = wsPath;
58
+ saveConfig(config);
59
+ }
60
+ console.log(chalk.green(' ✅ Workspace set'));
61
+
62
+ console.log(chalk.green('\n 🎉 Onboarding complete!\n'));
63
+ console.log(chalk.gray(' Next steps:'));
64
+ console.log(chalk.cyan(' natureco chat') + chalk.gray(' Start chatting'));
65
+ console.log(chalk.cyan(' natureco channels add') + chalk.gray(' Connect messaging channels'));
66
+ console.log(chalk.cyan(' natureco doctor') + chalk.gray(' Health check'));
67
+ console.log(chalk.cyan(' natureco configure') + chalk.gray(' More settings\n'));
68
+ }
69
+
70
+ module.exports = onboard;
@@ -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;