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,362 @@
1
+ const chalk = require('chalk');
2
+ const F = require('../utils/format');
3
+ const { getConfig, saveConfig } = require('../utils/config');
4
+ const crypto = require('crypto');
5
+
6
+ function nodes(args) {
7
+ const [action, ...params] = args || [];
8
+
9
+ if (!action || action === 'list') return listNodes();
10
+ if (action === 'pair') return pairNode(params[0]);
11
+ if (action === 'approve') return approveNode(params[0]);
12
+ if (action === 'reject') return rejectNode(params[0]);
13
+ if (action === 'remove') return removeNode(params[0]);
14
+ if (action === 'rename') return renameNode(params[0], params.slice(1).join(' '));
15
+ if (action === 'invoke') return invokeNode(params[0], params[1], params.slice(2));
16
+ if (action === 'notify') return notifyNode(params[0], params.slice(1).join(' '));
17
+ if (action === 'push') return pushNode(params[0]);
18
+ if (action === 'canvas') {
19
+ const sub = params[0];
20
+ if (sub === 'a2ui') {
21
+ if (params[1] === 'push') {
22
+ const nodeId = params[2];
23
+ const url = params[3];
24
+ if (!nodeId || !url) {
25
+ F.error('Node ID and URL required');
26
+ F.info('Usage: natureco nodes canvas a2ui push <nodeId> <url>');
27
+ process.exit(1);
28
+ }
29
+ F.info(`Would push A2UI from ${url} to node ${nodeId}`);
30
+ return;
31
+ }
32
+ if (params[1] === 'reset') {
33
+ const id = params[2] || 'default';
34
+ F.info(`Would reset A2UI for node ${id}`);
35
+ return;
36
+ }
37
+ F.error(`Unknown canvas a2ui command: ${params[1]}`);
38
+ F.info('Usage: natureco nodes canvas a2ui [push|reset]');
39
+ process.exit(1);
40
+ }
41
+ if (sub === 'snapshot') {
42
+ const nodeId = params[1];
43
+ if (!nodeId) {
44
+ F.error('Node ID required');
45
+ F.info('Usage: natureco nodes canvas snapshot <nodeId>');
46
+ process.exit(1);
47
+ }
48
+ F.info(`Would snapshot canvas on node ${nodeId}`);
49
+ return;
50
+ }
51
+ if (sub === 'present') {
52
+ const nodeId = params[1];
53
+ const url = params[2];
54
+ if (!nodeId || !url) {
55
+ F.error('Node ID and URL required');
56
+ F.info('Usage: natureco nodes canvas present <nodeId> <url>');
57
+ process.exit(1);
58
+ }
59
+ F.info(`Would present ${url} on node ${nodeId}`);
60
+ return;
61
+ }
62
+ if (sub === 'hide') {
63
+ const nodeId = params[1];
64
+ if (!nodeId) {
65
+ F.error('Node ID required');
66
+ F.info('Usage: natureco nodes canvas hide <nodeId>');
67
+ process.exit(1);
68
+ }
69
+ F.info(`Would hide canvas on node ${nodeId}`);
70
+ return;
71
+ }
72
+ if (sub === 'navigate') {
73
+ const nodeId = params[1];
74
+ const url = params[2];
75
+ if (!nodeId || !url) {
76
+ F.error('Node ID and URL required');
77
+ F.info('Usage: natureco nodes canvas navigate <nodeId> <url>');
78
+ process.exit(1);
79
+ }
80
+ F.info(`Would navigate node ${nodeId} to ${url}`);
81
+ return;
82
+ }
83
+ if (sub === 'eval') {
84
+ const nodeId = params[1];
85
+ const code = params.slice(2).join(' ');
86
+ if (!nodeId || !code) {
87
+ F.error('Node ID and code required');
88
+ F.info('Usage: natureco nodes canvas eval <nodeId> <code>');
89
+ process.exit(1);
90
+ }
91
+ F.info(`Would eval on node ${nodeId}: ${code}`);
92
+ return;
93
+ }
94
+ return canvasNode(sub, params[1]);
95
+ }
96
+ if (action === 'camera') {
97
+ const sub = params[0];
98
+ if (sub === 'list') {
99
+ const nodeId = params[1];
100
+ F.info(`Would list cameras${nodeId ? ' on node ' + nodeId : ''}`);
101
+ return;
102
+ }
103
+ if (sub === 'snap') {
104
+ const nodeId = params[1];
105
+ if (!nodeId) {
106
+ F.error('Node ID required');
107
+ F.info('Usage: natureco nodes camera snap <nodeId>');
108
+ process.exit(1);
109
+ }
110
+ F.info(`Would take snapshot on node ${nodeId}`);
111
+ return;
112
+ }
113
+ if (sub === 'clip') {
114
+ const nodeId = params[1];
115
+ if (!nodeId) {
116
+ F.error('Node ID required');
117
+ F.info('Usage: natureco nodes camera clip <nodeId>');
118
+ process.exit(1);
119
+ }
120
+ F.info(`Would record clip on node ${nodeId}`);
121
+ return;
122
+ }
123
+ return cameraNode(sub, params[1]);
124
+ }
125
+ if (action === 'screen') {
126
+ const sub = params[0];
127
+ if (sub === 'record') {
128
+ const nodeId = params[1];
129
+ if (!nodeId) {
130
+ F.error('Node ID required');
131
+ F.info('Usage: natureco nodes screen record <nodeId>');
132
+ process.exit(1);
133
+ }
134
+ F.info(`Would start screen recording on node ${nodeId}`);
135
+ return;
136
+ }
137
+ return screenNode(sub, params[1]);
138
+ }
139
+ if (action === 'location') {
140
+ const sub = params[0];
141
+ if (sub === 'get') {
142
+ const nodeId = params[1];
143
+ if (!nodeId) {
144
+ F.error('Node ID required');
145
+ F.info('Usage: natureco nodes location get <nodeId>');
146
+ process.exit(1);
147
+ }
148
+ F.kv('Node', nodeId);
149
+ F.kv('Latitude', '41.0082 (mock)');
150
+ F.kv('Longitude', '28.9784 (mock)');
151
+ return;
152
+ }
153
+ return locationNode(sub);
154
+ }
155
+ if (action === 'status') return nodeStatus(params[0]);
156
+ if (action === 'describe') return nodeDescribe(params[0]);
157
+
158
+ F.error(`Unknown command: ${action}`);
159
+ F.info('Usage: natureco nodes [list|pair|approve|reject|remove|rename|invoke|notify|push|canvas|camera|screen|location|status|describe]');
160
+ process.exit(1);
161
+ }
162
+
163
+ function listNodes() {
164
+ const config = getConfig();
165
+ const nodes = config.pairedNodes || [];
166
+
167
+ F.header('Nodes');
168
+
169
+ if (nodes.length === 0) {
170
+ F.info('No paired nodes.');
171
+ return;
172
+ }
173
+
174
+ F.table(['ID', 'Name', 'Status', 'LastSeen'],
175
+ nodes.map(n => [
176
+ n.id,
177
+ n.name || n.id,
178
+ 'online (mock)',
179
+ n.pairedAt ? new Date(n.pairedAt).toLocaleString() : '—',
180
+ ])
181
+ );
182
+ }
183
+
184
+ function pairNode(url) {
185
+ if (!url) {
186
+ F.error('Node URL required');
187
+ process.exit(1);
188
+ }
189
+
190
+ const config = getConfig();
191
+ if (!config.pairedNodes) config.pairedNodes = [];
192
+
193
+ const id = `node_${crypto.randomBytes(8).toString('hex')}`;
194
+ const key = crypto.randomBytes(16).toString('hex');
195
+
196
+ config.pairedNodes.push({ id, url, key, name: url, pairedAt: new Date().toISOString() });
197
+ saveConfig(config);
198
+
199
+ F.success(`Node paired: ${url}`);
200
+ F.info('Use the following link or scan the QR code in the NatureCo mobile app to link this device.');
201
+ F.kv('Pair Code', key);
202
+ }
203
+
204
+ function approveNode(id) {
205
+ F.success(`Node approved: ${id}`);
206
+ }
207
+
208
+ function rejectNode(id) {
209
+ F.error(`Node rejected: ${id}`);
210
+ }
211
+
212
+ function removeNode(id) {
213
+ if (!id) {
214
+ F.error('Node ID required');
215
+ process.exit(1);
216
+ }
217
+
218
+ const config = getConfig();
219
+ const nodes = config.pairedNodes || [];
220
+ const idx = nodes.findIndex(n => n.id === id);
221
+
222
+ if (idx === -1) {
223
+ F.error(`Node not found: ${id}`);
224
+ process.exit(1);
225
+ }
226
+
227
+ nodes.splice(idx, 1);
228
+ config.pairedNodes = nodes;
229
+ saveConfig(config);
230
+ F.success(`Node removed: ${id}`);
231
+ }
232
+
233
+ function renameNode(id, name) {
234
+ if (!id || !name) {
235
+ F.error('Node ID and name required');
236
+ process.exit(1);
237
+ }
238
+
239
+ const config = getConfig();
240
+ const node = (config.pairedNodes || []).find(n => n.id === id);
241
+ if (!node) {
242
+ F.error(`Node not found: ${id}`);
243
+ process.exit(1);
244
+ }
245
+
246
+ node.name = name;
247
+ saveConfig(config);
248
+ F.success(`Node renamed: ${name}`);
249
+ }
250
+
251
+ function invokeNode(nodeId, method, params) {
252
+ if (!nodeId || !method) {
253
+ F.error('Node ID and method required');
254
+ process.exit(1);
255
+ }
256
+ F.kv('Node', nodeId);
257
+ F.kv('Method', method);
258
+ F.kv('Params', (params || []).join(', '));
259
+ F.kv('Result', '[mock] invocation sent');
260
+ }
261
+
262
+ function notifyNode(nodeId, message) {
263
+ if (!nodeId || !message) {
264
+ F.error('Node ID and message required');
265
+ process.exit(1);
266
+ }
267
+ F.info(`Notify: ${nodeId} → "${message}"`);
268
+ }
269
+
270
+ function pushNode(nodeId) {
271
+ if (!nodeId) {
272
+ F.error('Node ID required');
273
+ process.exit(1);
274
+ }
275
+ F.info(`Push config to: ${nodeId}`);
276
+ }
277
+
278
+ function canvasNode(nodeId, sessionId) {
279
+ if (!nodeId) {
280
+ F.error('Node ID required');
281
+ process.exit(1);
282
+ }
283
+ F.info(`Canvas share: ${nodeId}${sessionId ? ' session: ' + sessionId : ''}`);
284
+ }
285
+
286
+ function cameraNode(nodeId, action) {
287
+ if (!nodeId) {
288
+ F.error('Node ID required');
289
+ process.exit(1);
290
+ }
291
+ const act = action || 'open';
292
+ F.info(`Camera ${act}: ${nodeId}`);
293
+ }
294
+
295
+ function screenNode(nodeId, action) {
296
+ if (!nodeId) {
297
+ F.error('Node ID required');
298
+ process.exit(1);
299
+ }
300
+ const act = action || 'view';
301
+ F.info(`Screen ${act}: ${nodeId}`);
302
+ }
303
+
304
+ function locationNode(nodeId) {
305
+ if (!nodeId) {
306
+ F.error('Node ID required');
307
+ process.exit(1);
308
+ }
309
+ F.kv('Node', nodeId);
310
+ F.kv('Latitude', '41.0082 (mock)');
311
+ F.kv('Longitude', '28.9784 (mock)');
312
+ }
313
+
314
+ function nodeStatus(nodeId) {
315
+ if (!nodeId) {
316
+ F.error('Node ID required');
317
+ F.info('Usage: natureco nodes status <nodeId>');
318
+ process.exit(1);
319
+ }
320
+ const config = getConfig();
321
+ const node = (config.pairedNodes || []).find(n => n.id === nodeId || n.name === nodeId);
322
+ if (!node) {
323
+ F.warning(`Node not found: ${nodeId}`);
324
+ process.exit(1);
325
+ }
326
+ F.header(`Node Status: ${node.name || node.id}`);
327
+ F.kv('ID', node.id);
328
+ F.kv('Name', node.name);
329
+ F.kv('URL', node.url || 'local');
330
+ F.kv('Status', 'connected (mock)');
331
+ F.kv('Latency', '~12ms (mock)');
332
+ F.kv('Uptime', '~3h (mock)');
333
+ }
334
+
335
+ function nodeDescribe(nodeId) {
336
+ if (!nodeId) {
337
+ F.error('Node ID required');
338
+ F.info('Usage: natureco nodes describe <nodeId>');
339
+ process.exit(1);
340
+ }
341
+ const config = getConfig();
342
+ const node = (config.pairedNodes || []).find(n => n.id === nodeId || n.name === nodeId);
343
+ if (!node) {
344
+ F.warning(`Node not found: ${nodeId}`);
345
+ process.exit(1);
346
+ }
347
+ F.header(`Node Details: ${node.name || node.id}`);
348
+ F.table(['Property', 'Value'], [
349
+ ['ID', node.id],
350
+ ['Name', node.name],
351
+ ['URL', node.url || 'local'],
352
+ ['Key', node.key ? node.key.substring(0, 8) + '...' : 'none'],
353
+ ['Paired At', node.pairedAt ? new Date(node.pairedAt).toLocaleString() : 'unknown'],
354
+ ['OS', 'linux (mock)'],
355
+ ['Version', '2.23.31 (mock)'],
356
+ ['CPU', '4 vCPU (mock)'],
357
+ ['Memory', '8 GB (mock)'],
358
+ ['Services', 'gateway, mcp, file-sync (mock)'],
359
+ ]);
360
+ }
361
+
362
+ 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,129 @@
1
+ const chalk = require('chalk');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+
6
+ const BASE_DIR = path.join(os.homedir(), '.natureco');
7
+ const CONFIG_FILE = path.join(BASE_DIR, 'config.json');
8
+
9
+ const STEPS = ['gateway', 'auth', 'workspace', 'channels', 'skills', 'health'];
10
+
11
+ function getConfig() {
12
+ if (!fs.existsSync(CONFIG_FILE)) return {};
13
+ try { return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8')); }
14
+ catch { return {}; }
15
+ }
16
+
17
+ function saveConfig(data) {
18
+ if (!fs.existsSync(BASE_DIR)) fs.mkdirSync(BASE_DIR, { recursive: true });
19
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2), 'utf8');
20
+ }
21
+
22
+ function onboard(params) {
23
+ try {
24
+ const [action] = params || [];
25
+
26
+ if (!action || action === 'status') return cmdStatus();
27
+ if (action === 'gateway') return cmdGateway();
28
+ if (action === 'auth') return cmdAuth();
29
+ if (action === 'workspace') return cmdWorkspace();
30
+ if (action === 'channels') return cmdChannels();
31
+ if (action === 'skills') return cmdSkills();
32
+ if (action === 'health') return cmdHealth();
33
+
34
+ console.log(chalk.red(`\n Unknown onboard action: ${action}\n`));
35
+ console.log(chalk.gray(' Usage: natureco onboard [gateway|auth|workspace|channels|skills|health|status]\n'));
36
+ } catch (err) {
37
+ console.log(chalk.red(`\n Onboard error: ${err.message}\n`));
38
+ }
39
+ }
40
+
41
+ function cmdStatus() {
42
+ const cfg = getConfig();
43
+ console.log(chalk.cyan('\n Onboarding Status\n'));
44
+
45
+ const status = {
46
+ gateway: cfg.gatewayUrl ? 'done' : 'pending',
47
+ auth: cfg.providerApiKey ? 'done' : 'pending',
48
+ workspace: cfg.workspacePath ? 'done' : 'pending',
49
+ channels: cfg.channels ? 'done' : 'pending',
50
+ skills: cfg.skills && cfg.skills.list && cfg.skills.list.length > 0 ? 'done' : 'pending',
51
+ health: cfg.setupCompleted ? 'done' : 'pending',
52
+ };
53
+
54
+ for (const step of STEPS) {
55
+ const icon = status[step] === 'done' ? chalk.green('✓') : chalk.yellow('○');
56
+ console.log(` ${icon} ${step}`);
57
+ }
58
+ console.log('');
59
+ }
60
+
61
+ function cmdGateway() {
62
+ const cfg = getConfig();
63
+ console.log(chalk.cyan('\n Gateway Setup\n'));
64
+ console.log(chalk.gray(' To configure the gateway, run:'));
65
+ console.log(chalk.cyan(' natureco configure gateway'));
66
+ console.log(chalk.gray(' Or start the gateway:'));
67
+ console.log(chalk.cyan(' natureco gateway start\n'));
68
+ cfg.gatewayUrl = 'ws://localhost:3848';
69
+ saveConfig(cfg);
70
+ console.log(chalk.green(' Gateway step marked as done.\n'));
71
+ }
72
+
73
+ function cmdAuth() {
74
+ const cfg = getConfig();
75
+ console.log(chalk.cyan('\n Auth Setup\n'));
76
+ console.log(chalk.gray(' To configure authentication, run:'));
77
+ console.log(chalk.cyan(' natureco configure auth'));
78
+ console.log(chalk.gray(' Or set your API key in config.\n'));
79
+ cfg.authConfigured = true;
80
+ saveConfig(cfg);
81
+ console.log(chalk.green(' Auth step marked as done.\n'));
82
+ }
83
+
84
+ function cmdWorkspace() {
85
+ const cfg = getConfig();
86
+ const wsPath = cfg.workspacePath || path.join(os.homedir(), 'natureco-workspace');
87
+ if (!fs.existsSync(wsPath)) fs.mkdirSync(wsPath, { recursive: true });
88
+ cfg.workspacePath = wsPath;
89
+ saveConfig(cfg);
90
+ console.log(chalk.green('\n Workspace ready at: ' + wsPath + '\n'));
91
+ }
92
+
93
+ function cmdChannels() {
94
+ console.log(chalk.cyan('\n Channels Setup\n'));
95
+ console.log(chalk.gray(' Available channels:'));
96
+ const channels = ['telegram', 'whatsapp', 'discord', 'slack', 'signal', 'irc', 'mattermost', 'imessage'];
97
+ for (const ch of channels) {
98
+ console.log(chalk.gray(' natureco ' + ch + ' connect'));
99
+ }
100
+ console.log('');
101
+ }
102
+
103
+ function cmdSkills() {
104
+ console.log(chalk.cyan('\n Skills Setup\n'));
105
+ console.log(chalk.gray(' To manage skills, run:'));
106
+ console.log(chalk.cyan(' natureco skills list'));
107
+ console.log(chalk.cyan(' natureco skills add <name>\n'));
108
+ }
109
+
110
+ function cmdHealth() {
111
+ const cfg = getConfig();
112
+ console.log(chalk.cyan('\n Health Check\n'));
113
+
114
+ const checks = [
115
+ { label: 'Config exists', pass: fs.existsSync(CONFIG_FILE) },
116
+ { label: 'Gateway configured', pass: !!cfg.gatewayUrl },
117
+ { label: 'Auth configured', pass: !!cfg.providerApiKey },
118
+ { label: 'Workspace configured', pass: !!cfg.workspacePath },
119
+ ];
120
+
121
+ for (const c of checks) {
122
+ console.log(` ${c.pass ? chalk.green('✓') : chalk.yellow('○')} ${c.label}`);
123
+ }
124
+
125
+ const done = checks.filter(c => c.pass).length;
126
+ console.log(chalk.gray(`\n ${done}/${checks.length} checks passed\n`));
127
+ }
128
+
129
+ module.exports = onboard;