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.
- package/README.md +94 -11
- package/bin/natureco.js +495 -94
- package/package.json +1 -1
- package/src/commands/acp.js +39 -0
- package/src/commands/admin-rpc.js +302 -0
- package/src/commands/agent.js +280 -0
- package/src/commands/agents.js +114 -30
- package/src/commands/approvals.js +214 -0
- package/src/commands/backup.js +124 -0
- package/src/commands/bonjour.js +167 -0
- package/src/commands/browser.js +815 -0
- package/src/commands/capability.js +237 -0
- package/src/commands/channels.js +422 -267
- package/src/commands/chat.js +5 -8
- package/src/commands/clawbot.js +19 -0
- package/src/commands/clickclack.js +130 -0
- package/src/commands/code.js +3 -2
- package/src/commands/commitments.js +148 -0
- package/src/commands/completion.js +84 -0
- package/src/commands/config.js +219 -30
- package/src/commands/configure.js +110 -0
- package/src/commands/crestodian.js +92 -0
- package/src/commands/cron.js +239 -19
- package/src/commands/daemon.js +90 -0
- package/src/commands/dashboard.js +47 -374
- package/src/commands/device-pair.js +248 -0
- package/src/commands/devices.js +137 -0
- package/src/commands/directory.js +179 -0
- package/src/commands/dns.js +196 -0
- package/src/commands/docs.js +136 -0
- package/src/commands/doctor.js +143 -492
- package/src/commands/exec-policy.js +80 -0
- package/src/commands/gateway-server.js +1155 -24
- package/src/commands/gateway.js +492 -249
- package/src/commands/health.js +148 -0
- package/src/commands/help.js +24 -25
- package/src/commands/hooks.js +141 -87
- package/src/commands/imessage.js +128 -14
- package/src/commands/infer.js +1474 -0
- package/src/commands/irc.js +64 -15
- package/src/commands/logs.js +122 -99
- package/src/commands/mattermost.js +114 -12
- package/src/commands/mcp.js +121 -309
- package/src/commands/memory-cmd.js +134 -1
- package/src/commands/memory.js +128 -0
- package/src/commands/message.js +720 -134
- package/src/commands/migrate.js +213 -2
- package/src/commands/models.js +39 -1
- package/src/commands/node.js +98 -0
- package/src/commands/nodes.js +362 -0
- package/src/commands/oc-path.js +200 -0
- package/src/commands/onboard.js +129 -0
- package/src/commands/open-prose.js +67 -0
- package/src/commands/pairing.js +108 -107
- package/src/commands/path.js +206 -0
- package/src/commands/plugins.js +35 -1
- package/src/commands/policy.js +176 -0
- package/src/commands/proxy.js +306 -0
- package/src/commands/qr.js +70 -0
- package/src/commands/reset.js +101 -94
- package/src/commands/sandbox.js +125 -0
- package/src/commands/secrets.js +201 -0
- package/src/commands/sessions.js +110 -51
- package/src/commands/setup.js +102 -543
- package/src/commands/signal.js +447 -18
- package/src/commands/skills.js +67 -1
- package/src/commands/sms.js +123 -19
- package/src/commands/status.js +101 -127
- package/src/commands/system.js +53 -0
- package/src/commands/tasks.js +208 -100
- package/src/commands/terminal.js +139 -0
- package/src/commands/thread-ownership.js +157 -0
- package/src/commands/transcripts.js +95 -0
- package/src/commands/tui.js +41 -0
- package/src/commands/uninstall.js +73 -92
- package/src/commands/update.js +146 -91
- package/src/commands/voice.js +82 -0
- package/src/commands/vydra.js +98 -0
- package/src/commands/webhooks.js +58 -66
- package/src/commands/wiki.js +783 -0
- package/src/commands/workboard.js +207 -0
- package/src/tools/audio_understanding.js +154 -0
- package/src/tools/browser.js +112 -0
- package/src/tools/canvas.js +104 -0
- package/src/tools/document_extract.js +84 -0
- package/src/tools/duckduckgo.js +54 -0
- package/src/tools/exa_search.js +66 -0
- package/src/tools/firecrawl.js +104 -0
- package/src/tools/image_generation.js +99 -0
- package/src/tools/llm_task.js +118 -0
- package/src/tools/media_understanding.js +128 -0
- package/src/tools/music_generation.js +113 -0
- package/src/tools/parallel_search.js +77 -0
- package/src/tools/phone_control.js +80 -0
- package/src/tools/phone_control_enhanced.js +184 -0
- package/src/tools/searxng.js +61 -0
- package/src/tools/speech_to_text.js +135 -0
- package/src/tools/text_to_speech.js +105 -0
- package/src/tools/thread_ownership.js +88 -0
- package/src/tools/video_generation.js +72 -0
- package/src/tools/web_readability.js +104 -0
- package/src/utils/agents-md.js +85 -0
- package/src/utils/api.js +39 -40
- package/src/utils/format.js +144 -0
- package/src/utils/headless.js +2 -1
- package/src/utils/memory.js +200 -0
- package/src/utils/parallel-tools.js +106 -0
- package/src/utils/sub-agent.js +148 -0
- package/src/utils/token-budget.js +304 -0
- package/src/utils/tool-runner.js +7 -5
- package/src/utils/web-fetch.js +107 -0
package/src/commands/migrate.js
CHANGED
|
@@ -35,9 +35,17 @@ function addUniqueFact(facts, newFact) {
|
|
|
35
35
|
async function migrate(options) {
|
|
36
36
|
const from = options.from || 'openclaw';
|
|
37
37
|
|
|
38
|
+
if (from === 'claude-code' || from === 'claude') {
|
|
39
|
+
return migrateClaudeCode();
|
|
40
|
+
}
|
|
41
|
+
if (from === 'hermes') {
|
|
42
|
+
return migrateHermes();
|
|
43
|
+
}
|
|
38
44
|
if (from !== 'openclaw') {
|
|
39
|
-
console.log(chalk.red('\n❌
|
|
40
|
-
console.log(chalk.gray('Kullanım: natureco migrate --from openclaw
|
|
45
|
+
console.log(chalk.red('\n❌ Desteklenen kaynaklar: openclaw, claude-code, hermes\n'));
|
|
46
|
+
console.log(chalk.gray('Kullanım: natureco migrate --from openclaw'));
|
|
47
|
+
console.log(chalk.gray(' natureco migrate --from claude-code'));
|
|
48
|
+
console.log(chalk.gray(' natureco migrate --from hermes\n'));
|
|
41
49
|
return;
|
|
42
50
|
}
|
|
43
51
|
|
|
@@ -623,4 +631,207 @@ function copyDirRecursive(src, dest) {
|
|
|
623
631
|
}
|
|
624
632
|
}
|
|
625
633
|
|
|
634
|
+
// ── Claude Code Migration ──────────────────────────────────────────────────────
|
|
635
|
+
async function migrateClaudeCode() {
|
|
636
|
+
console.log(chalk.yellow('\n⏳ Claude Code → NatureCo migration başlıyor...\n'));
|
|
637
|
+
|
|
638
|
+
const claudeDir = path.join(os.homedir(), '.claude');
|
|
639
|
+
const claudeSettings = path.join(claudeDir, 'settings.json');
|
|
640
|
+
const claudeProjects = path.join(os.homedir(), '.claude', 'projects');
|
|
641
|
+
|
|
642
|
+
if (!fs.existsSync(claudeSettings)) {
|
|
643
|
+
console.log(chalk.yellow('⚠ Claude Code settings bulunamadı: ~/.claude/settings.json\n'));
|
|
644
|
+
} else {
|
|
645
|
+
try {
|
|
646
|
+
const settings = JSON.parse(fs.readFileSync(claudeSettings, 'utf-8'));
|
|
647
|
+
console.log(chalk.gray(' Claude Code ayarları bulundu.\n'));
|
|
648
|
+
|
|
649
|
+
// Migrate allowed tools
|
|
650
|
+
if (settings.allowList?.length > 0) {
|
|
651
|
+
const config = getConfig();
|
|
652
|
+
if (!config.policies) config.policies = {};
|
|
653
|
+
config.policies.claudeAllowedTools = settings.allowList;
|
|
654
|
+
setConfigValue('policies', config.policies);
|
|
655
|
+
console.log(chalk.green(` ✅ ${settings.allowList.length} izinli araç migrate edildi`));
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Migrate permissions
|
|
659
|
+
if (settings.permissions) {
|
|
660
|
+
const config = getConfig();
|
|
661
|
+
config.claudePermissions = settings.permissions;
|
|
662
|
+
setConfigValue('claudePermissions', settings.permissions);
|
|
663
|
+
console.log(chalk.green(' ✅ Claude izinleri migrate edildi'));
|
|
664
|
+
}
|
|
665
|
+
} catch (err) {
|
|
666
|
+
console.log(chalk.red(` ❌ Claude settings okuma hatası: ${err.message}`));
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// Migrate Claude projects
|
|
671
|
+
if (fs.existsSync(claudeProjects)) {
|
|
672
|
+
try {
|
|
673
|
+
const projects = fs.readdirSync(claudeProjects).filter(f => {
|
|
674
|
+
const p = path.join(claudeProjects, f);
|
|
675
|
+
return fs.statSync(p).isDirectory() && !f.startsWith('.');
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
if (projects.length > 0) {
|
|
679
|
+
console.log(chalk.gray(`\n Claude projeleri bulundu: ${projects.length}\n`));
|
|
680
|
+
const projectsDir = path.join(os.homedir(), '.natureco', 'claude-projects');
|
|
681
|
+
fs.mkdirSync(projectsDir, { recursive: true });
|
|
682
|
+
|
|
683
|
+
for (const project of projects) {
|
|
684
|
+
const src = path.join(claudeProjects, project);
|
|
685
|
+
const dst = path.join(projectsDir, project);
|
|
686
|
+
if (!fs.existsSync(dst)) {
|
|
687
|
+
fs.cpSync(src, dst, { recursive: true });
|
|
688
|
+
console.log(chalk.green(` ✅ Proje kopyalandı: ${project}`));
|
|
689
|
+
} else {
|
|
690
|
+
console.log(chalk.yellow(` ⚠ Proje zaten var, atlandı: ${project}`));
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
} catch (err) {
|
|
695
|
+
console.log(chalk.yellow(` ⚠ Proje migrasyonu atlandı: ${err.message}`));
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// Migrate MEMORY.md if exists
|
|
700
|
+
const memoryFile = path.join(claudeDir, '..', 'workspace', 'MEMORY.md');
|
|
701
|
+
if (fs.existsSync(memoryFile)) {
|
|
702
|
+
try {
|
|
703
|
+
const content = fs.readFileSync(memoryFile, 'utf-8');
|
|
704
|
+
const memory = {
|
|
705
|
+
name: '',
|
|
706
|
+
nickname: '',
|
|
707
|
+
botName: '',
|
|
708
|
+
facts: [{ value: 'Migrated from Claude Code', score: 5, updatedAt: new Date().toISOString() }],
|
|
709
|
+
preferences: []
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
const lines = content.split('\n');
|
|
713
|
+
for (const line of lines) {
|
|
714
|
+
if (line.toLowerCase().includes('name:')) {
|
|
715
|
+
memory.name = line.split(':')[1]?.trim() || '';
|
|
716
|
+
}
|
|
717
|
+
if (line.toLowerCase().includes('preference:') || line.toLowerCase().includes('favorite:')) {
|
|
718
|
+
memory.preferences.push({ value: line.split(':')[1]?.trim() || '', score: 5, updatedAt: new Date().toISOString() });
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
const memoryDir = path.join(os.homedir(), '.natureco', 'memory');
|
|
723
|
+
fs.mkdirSync(memoryDir, { recursive: true });
|
|
724
|
+
fs.writeFileSync(path.join(memoryDir, 'universal-provider.json'), JSON.stringify(memory, null, 2));
|
|
725
|
+
console.log(chalk.green(' ✅ Claude MEMORY.md migrate edildi'));
|
|
726
|
+
} catch (err) {
|
|
727
|
+
console.log(chalk.yellow(` ⚠ Memory migrasyonu atlandı: ${err.message}`));
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
console.log(chalk.green('\n✅ Claude Code migration tamamlandı!\n'));
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// ── Hermes Migration ──────────────────────────────────────────────────────────
|
|
735
|
+
async function migrateHermes() {
|
|
736
|
+
console.log(chalk.yellow('\n⏳ Hermes → NatureCo migration başlıyor...\n'));
|
|
737
|
+
|
|
738
|
+
const hermesDir = path.join(os.homedir(), '.hermes');
|
|
739
|
+
const hermesConfig = path.join(hermesDir, 'config.json');
|
|
740
|
+
const hermesSessions = path.join(hermesDir, 'sessions');
|
|
741
|
+
|
|
742
|
+
if (!fs.existsSync(hermesDir)) {
|
|
743
|
+
console.log(chalk.yellow('⚠ Hermes dizini bulunamadı: ~/.hermes\n'));
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
let migrated = { config: false, sessions: 0, memory: false };
|
|
748
|
+
|
|
749
|
+
// Migrate config
|
|
750
|
+
if (fs.existsSync(hermesConfig)) {
|
|
751
|
+
try {
|
|
752
|
+
const config = JSON.parse(fs.readFileSync(hermesConfig, 'utf-8'));
|
|
753
|
+
|
|
754
|
+
const ncConfig = getConfig();
|
|
755
|
+
if (config.provider) ncConfig.providerUrl = config.provider;
|
|
756
|
+
if (config.model) ncConfig.providerModel = config.model;
|
|
757
|
+
if (config.apiKey) ncConfig.providerApiKey = config.apiKey;
|
|
758
|
+
if (config.systemPrompt) ncConfig.systemPrompt = config.systemPrompt;
|
|
759
|
+
if (config.temperature !== undefined) ncConfig.temperature = config.temperature;
|
|
760
|
+
|
|
761
|
+
setConfigValue('providerUrl', ncConfig.providerUrl);
|
|
762
|
+
setConfigValue('providerModel', ncConfig.providerModel);
|
|
763
|
+
if (config.apiKey) setConfigValue('providerApiKey', ncConfig.providerApiKey);
|
|
764
|
+
if (config.systemPrompt) setConfigValue('systemPrompt', ncConfig.systemPrompt);
|
|
765
|
+
if (config.temperature !== undefined) setConfigValue('temperature', ncConfig.temperature);
|
|
766
|
+
|
|
767
|
+
migrated.config = true;
|
|
768
|
+
console.log(chalk.green(' ✅ Hermes config migrate edildi'));
|
|
769
|
+
} catch (err) {
|
|
770
|
+
console.log(chalk.red(` ❌ Config okuma hatası: ${err.message}`));
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// Migrate sessions
|
|
775
|
+
if (fs.existsSync(hermesSessions)) {
|
|
776
|
+
try {
|
|
777
|
+
const sessions = fs.readdirSync(hermesSessions).filter(f => f.endsWith('.json'));
|
|
778
|
+
const ncSessionsDir = path.join(os.homedir(), '.natureco', 'sessions');
|
|
779
|
+
fs.mkdirSync(ncSessionsDir, { recursive: true });
|
|
780
|
+
|
|
781
|
+
for (const session of sessions) {
|
|
782
|
+
const src = path.join(hermesSessions, session);
|
|
783
|
+
const dst = path.join(ncSessionsDir, `hermes-${session}`);
|
|
784
|
+
if (!fs.existsSync(dst)) {
|
|
785
|
+
fs.copyFileSync(src, dst);
|
|
786
|
+
migrated.sessions++;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
if (migrated.sessions > 0) {
|
|
791
|
+
console.log(chalk.green(` ✅ ${migrated.sessions} Hermes oturumu migrate edildi`));
|
|
792
|
+
}
|
|
793
|
+
} catch (err) {
|
|
794
|
+
console.log(chalk.yellow(` ⚠ Session migrasyonu atlandı: ${err.message}`));
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// Migrate memory
|
|
799
|
+
const hermesMemory = path.join(hermesDir, 'memory.json');
|
|
800
|
+
if (fs.existsSync(hermesMemory)) {
|
|
801
|
+
try {
|
|
802
|
+
const memData = JSON.parse(fs.readFileSync(hermesMemory, 'utf-8'));
|
|
803
|
+
const ncMemoryDir = path.join(os.homedir(), '.natureco', 'memory');
|
|
804
|
+
fs.mkdirSync(ncMemoryDir, { recursive: true });
|
|
805
|
+
|
|
806
|
+
const ncMem = {
|
|
807
|
+
name: memData.userName || '',
|
|
808
|
+
nickname: '',
|
|
809
|
+
botName: 'Hermes',
|
|
810
|
+
facts: [],
|
|
811
|
+
preferences: []
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
if (memData.userInfo) {
|
|
815
|
+
ncMem.facts.push({ value: memData.userInfo, score: 6, updatedAt: new Date().toISOString() });
|
|
816
|
+
}
|
|
817
|
+
if (memData.context) {
|
|
818
|
+
ncMem.facts.push({ value: memData.context, score: 5, updatedAt: new Date().toISOString() });
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
fs.writeFileSync(path.join(ncMemoryDir, 'hermes-migrated.json'), JSON.stringify(ncMem, null, 2));
|
|
822
|
+
migrated.memory = true;
|
|
823
|
+
console.log(chalk.green(' ✅ Hermes hafızası migrate edildi'));
|
|
824
|
+
} catch (err) {
|
|
825
|
+
console.log(chalk.yellow(` ⚠ Memory migrasyonu atlandı: ${err.message}`));
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
if (!migrated.config && migrated.sessions === 0 && !migrated.memory) {
|
|
830
|
+
console.log(chalk.yellow(' ⚠ Hiçbir veri migrate edilemedi.\n'));
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
console.log(chalk.green('\n✅ Hermes migration tamamlandı!\n'));
|
|
835
|
+
}
|
|
836
|
+
|
|
626
837
|
module.exports = migrate;
|
package/src/commands/models.js
CHANGED
|
@@ -116,9 +116,11 @@ async function models(args) {
|
|
|
116
116
|
}
|
|
117
117
|
if (action === 'aliases') return manageAliases(params);
|
|
118
118
|
if (action === 'fallbacks') return manageFallbacks(params);
|
|
119
|
+
if (action === 'set-image') return setImageModel(params[0]);
|
|
120
|
+
if (action === 'image-fallbacks') return manageImageFallbacks(params);
|
|
119
121
|
|
|
120
122
|
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
121
|
-
console.log(chalk.gray(' Kullanım: natureco models [list|set|scan|aliases|fallbacks]\n'));
|
|
123
|
+
console.log(chalk.gray(' Kullanım: natureco models [list|set|scan|aliases|fallbacks|set-image|image-fallbacks]\n'));
|
|
122
124
|
process.exit(1);
|
|
123
125
|
}
|
|
124
126
|
|
|
@@ -469,6 +471,42 @@ function manageFallbacks(params) {
|
|
|
469
471
|
console.log(chalk.gray('\n Kullanım: natureco models fallbacks [list|set <model-id>|clear]\n'));
|
|
470
472
|
}
|
|
471
473
|
|
|
474
|
+
function setImageModel(modelId) {
|
|
475
|
+
if (!modelId) {
|
|
476
|
+
console.log(chalk.cyan('\n Current image model: ') + chalk.white(getConfig().imageModel || 'not set'));
|
|
477
|
+
console.log(chalk.gray('\n Usage: natureco models set-image <model-id>\n'));
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
const config = getConfig();
|
|
481
|
+
config.imageModel = modelId;
|
|
482
|
+
saveConfig(config);
|
|
483
|
+
console.log(chalk.green(`\n ✓ Image model set: ${modelId}\n`));
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function manageImageFallbacks(params) {
|
|
487
|
+
const config = getConfig();
|
|
488
|
+
if (params.length === 0 || params[0] === 'list') {
|
|
489
|
+
console.log(chalk.cyan.bold('\n Image Model Fallbacks\n'));
|
|
490
|
+
console.log(chalk.gray(' Primary : ') + chalk.white(config.imageModel || 'not set'));
|
|
491
|
+
console.log(chalk.gray(' Fallback : ') + chalk.white(config.imageFallbackModel || 'not set'));
|
|
492
|
+
console.log(chalk.gray('\n Set: natureco models image-fallbacks set <model-id>'));
|
|
493
|
+
console.log(chalk.gray(' Clear: natureco models image-fallbacks clear\n'));
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
if (params[0] === 'set' && params[1]) {
|
|
497
|
+
config.imageFallbackModel = params[1];
|
|
498
|
+
saveConfig(config);
|
|
499
|
+
console.log(chalk.green(`\n ✓ Image fallback set: ${params[1]}\n`));
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
if (params[0] === 'clear') {
|
|
503
|
+
delete config.imageFallbackModel;
|
|
504
|
+
saveConfig(config);
|
|
505
|
+
console.log(chalk.green('\n ✓ Image fallback cleared\n'));
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
472
510
|
function resolveModel(input) {
|
|
473
511
|
const config = getConfig();
|
|
474
512
|
const aliases = config.modelAliases || {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
const NODES_FILE = path.join(os.homedir(), '.natureco', 'nodes.json');
|
|
7
|
+
|
|
8
|
+
function loadNodes() {
|
|
9
|
+
if (!fs.existsSync(NODES_FILE)) return {};
|
|
10
|
+
try { return JSON.parse(fs.readFileSync(NODES_FILE, 'utf8')); }
|
|
11
|
+
catch { return {}; }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function saveNodes(nodes) {
|
|
15
|
+
const dir = path.dirname(NODES_FILE);
|
|
16
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
17
|
+
fs.writeFileSync(NODES_FILE, JSON.stringify(nodes, null, 2), 'utf8');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function node(args) {
|
|
21
|
+
const [action, ...params] = args || [];
|
|
22
|
+
|
|
23
|
+
if (!action || action === 'status') return cmdStatus(params[0]);
|
|
24
|
+
if (action === 'run') return cmdRun(params[0], params.slice(1));
|
|
25
|
+
if (action === 'install') return cmdInstall();
|
|
26
|
+
if (action === 'uninstall') return cmdUninstall(params[0]);
|
|
27
|
+
if (action === 'stop') return cmdStop(params[0]);
|
|
28
|
+
if (action === 'restart') return cmdRestart(params[0]);
|
|
29
|
+
|
|
30
|
+
console.log(chalk.red(`\n Unknown node action: ${action}\n`));
|
|
31
|
+
console.log(chalk.gray(' Usage: natureco node <action> [params]'));
|
|
32
|
+
console.log(chalk.gray(' Actions: run <id>, status <id>, install, uninstall, stop <id>, restart <id>\n'));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function cmdRun(id) {
|
|
37
|
+
if (!id) { console.log(chalk.red('\n Usage: natureco node run <id>\n')); process.exit(1); }
|
|
38
|
+
const nodes = loadNodes();
|
|
39
|
+
const n = nodes[id];
|
|
40
|
+
if (!n) { console.log(chalk.yellow(`\n Node "${id}" not found.\n`)); return; }
|
|
41
|
+
console.log(chalk.cyan(`\n Running command on node "${id}"...\n`));
|
|
42
|
+
console.log(chalk.gray(' (Stub — command execution not implemented)\n'));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function cmdStatus(id) {
|
|
46
|
+
if (!id) { console.log(chalk.red('\n Usage: natureco node status <id>\n')); process.exit(1); }
|
|
47
|
+
const nodes = loadNodes();
|
|
48
|
+
const n = nodes[id];
|
|
49
|
+
|
|
50
|
+
console.log(chalk.cyan(`\n Node: ${id || '(all)'}\n`));
|
|
51
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
52
|
+
|
|
53
|
+
if (!n) {
|
|
54
|
+
console.log(chalk.yellow(` Node "${id}" not found.\n`));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log(` ${chalk.white('ID:')} ${chalk.cyan(n.id || id)}`);
|
|
59
|
+
console.log(` ${chalk.white('Host:')} ${chalk.white(n.host || n.hostname || '—')}`);
|
|
60
|
+
console.log(` ${chalk.white('Port:')} ${chalk.white(n.port || '—')}`);
|
|
61
|
+
console.log(` ${chalk.white('Status:')} ${n.online ? chalk.green('online') : chalk.gray('offline')}`);
|
|
62
|
+
console.log(` ${chalk.white('Version:')} ${chalk.gray(n.version || '—')}`);
|
|
63
|
+
console.log('');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function cmdInstall() {
|
|
67
|
+
console.log(chalk.cyan('\n Installing node software...\n'));
|
|
68
|
+
console.log(chalk.gray(' (Stub — installation not implemented)\n'));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function cmdUninstall(id) {
|
|
72
|
+
if (!id) { console.log(chalk.red('\n Usage: natureco node uninstall <id>\n')); process.exit(1); }
|
|
73
|
+
const nodes = loadNodes();
|
|
74
|
+
if (!nodes[id]) { console.log(chalk.yellow(`\n Node "${id}" not found.\n`)); return; }
|
|
75
|
+
delete nodes[id];
|
|
76
|
+
saveNodes(nodes);
|
|
77
|
+
console.log(chalk.gray(`\n Node "${id}" uninstalled.\n`));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function cmdStop(id) {
|
|
81
|
+
if (!id) { console.log(chalk.red('\n Usage: natureco node stop <id>\n')); process.exit(1); }
|
|
82
|
+
const nodes = loadNodes();
|
|
83
|
+
if (!nodes[id]) { console.log(chalk.yellow(`\n Node "${id}" not found.\n`)); return; }
|
|
84
|
+
nodes[id].online = false;
|
|
85
|
+
saveNodes(nodes);
|
|
86
|
+
console.log(chalk.gray(`\n Node "${id}" stopped.\n`));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function cmdRestart(id) {
|
|
90
|
+
if (!id) { console.log(chalk.red('\n Usage: natureco node restart <id>\n')); process.exit(1); }
|
|
91
|
+
const nodes = loadNodes();
|
|
92
|
+
if (!nodes[id]) { console.log(chalk.yellow(`\n Node "${id}" not found.\n`)); return; }
|
|
93
|
+
nodes[id].online = true;
|
|
94
|
+
saveNodes(nodes);
|
|
95
|
+
console.log(chalk.gray(`\n Node "${id}" restarted.\n`));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = node;
|