natureco-cli 2.23.31 → 4.4.0

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 (174) hide show
  1. package/AUDIT.md +178 -0
  2. package/CHANGELOG.md +422 -0
  3. package/DEPLOY_v2.0.0.md +400 -0
  4. package/README.md +159 -1
  5. package/bin/natureco.js +182 -12
  6. package/package.json +43 -11
  7. package/skills/code-review/SKILL.md +0 -0
  8. package/skills/summarize/SKILL.md +0 -0
  9. package/skills/translate/SKILL.md +0 -0
  10. package/src/commands/acp.js +0 -0
  11. package/src/commands/admin-rpc.js +0 -0
  12. package/src/commands/agent.js +0 -0
  13. package/src/commands/agents.js +0 -0
  14. package/src/commands/approvals.js +0 -0
  15. package/src/commands/ask.js +1 -1
  16. package/src/commands/audit.js +209 -0
  17. package/src/commands/backup.js +0 -0
  18. package/src/commands/bonjour.js +0 -0
  19. package/src/commands/bots.js +0 -0
  20. package/src/commands/browser.js +0 -0
  21. package/src/commands/capability.js +0 -0
  22. package/src/commands/channels.js +0 -0
  23. package/src/commands/chat.js +0 -0
  24. package/src/commands/clawbot.js +0 -0
  25. package/src/commands/clickclack.js +0 -0
  26. package/src/commands/code.js +0 -0
  27. package/src/commands/commands.js +0 -0
  28. package/src/commands/commitments.js +0 -0
  29. package/src/commands/completion.js +0 -0
  30. package/src/commands/config.js +11 -2
  31. package/src/commands/configure.js +0 -0
  32. package/src/commands/cost.js +210 -0
  33. package/src/commands/crestodian.js +0 -0
  34. package/src/commands/cron.js +0 -0
  35. package/src/commands/daemon.js +0 -0
  36. package/src/commands/dashboard.js +126 -45
  37. package/src/commands/device-pair.js +0 -0
  38. package/src/commands/devices.js +0 -0
  39. package/src/commands/directory.js +0 -0
  40. package/src/commands/discord.js +0 -0
  41. package/src/commands/dns.js +0 -0
  42. package/src/commands/docs.js +0 -0
  43. package/src/commands/doctor.js +134 -15
  44. package/src/commands/exec-policy.js +0 -0
  45. package/src/commands/gateway-server.js +0 -0
  46. package/src/commands/gateway.js +0 -0
  47. package/src/commands/git.js +0 -0
  48. package/src/commands/health.js +0 -0
  49. package/src/commands/help.js +0 -0
  50. package/src/commands/hooks.js +0 -0
  51. package/src/commands/imessage.js +0 -0
  52. package/src/commands/infer.js +0 -0
  53. package/src/commands/init.js +0 -0
  54. package/src/commands/irc.js +0 -0
  55. package/src/commands/login.js +0 -0
  56. package/src/commands/logout.js +0 -0
  57. package/src/commands/logs.js +0 -0
  58. package/src/commands/mattermost.js +0 -0
  59. package/src/commands/mcp.js +0 -0
  60. package/src/commands/medium.js +206 -0
  61. package/src/commands/memory-cmd.js +0 -0
  62. package/src/commands/memory.js +0 -0
  63. package/src/commands/message.js +0 -0
  64. package/src/commands/migrate.js +0 -0
  65. package/src/commands/models.js +0 -0
  66. package/src/commands/naturehub.js +156 -0
  67. package/src/commands/node.js +0 -0
  68. package/src/commands/nodes.js +1 -1
  69. package/src/commands/oc-path.js +0 -0
  70. package/src/commands/onboard.js +0 -0
  71. package/src/commands/open-prose.js +0 -0
  72. package/src/commands/pairing.js +0 -0
  73. package/src/commands/path.js +0 -0
  74. package/src/commands/plugins.js +0 -0
  75. package/src/commands/policy.js +0 -0
  76. package/src/commands/proxy.js +0 -0
  77. package/src/commands/qr.js +0 -0
  78. package/src/commands/reset.js +0 -0
  79. package/src/commands/run.js +0 -0
  80. package/src/commands/sandbox.js +0 -0
  81. package/src/commands/secrets.js +0 -0
  82. package/src/commands/security.js +0 -0
  83. package/src/commands/seo.js +268 -0
  84. package/src/commands/sessions.js +0 -0
  85. package/src/commands/setup.js +131 -4
  86. package/src/commands/signal.js +0 -0
  87. package/src/commands/skills.js +82 -1
  88. package/src/commands/slack.js +0 -0
  89. package/src/commands/sms.js +0 -0
  90. package/src/commands/status.js +0 -0
  91. package/src/commands/system.js +0 -0
  92. package/src/commands/tasks.js +0 -0
  93. package/src/commands/team.js +171 -0
  94. package/src/commands/telegram.js +0 -0
  95. package/src/commands/terminal.js +0 -0
  96. package/src/commands/thread-ownership.js +0 -0
  97. package/src/commands/transcripts.js +0 -0
  98. package/src/commands/tui.js +0 -0
  99. package/src/commands/ultrareview.js +0 -0
  100. package/src/commands/uninstall.js +0 -0
  101. package/src/commands/update.js +0 -0
  102. package/src/commands/voice.js +0 -0
  103. package/src/commands/vydra.js +0 -0
  104. package/src/commands/web-fetch.js +34 -0
  105. package/src/commands/webhooks.js +0 -0
  106. package/src/commands/whatsapp.js +0 -0
  107. package/src/commands/wiki.js +0 -0
  108. package/src/commands/workboard.js +0 -0
  109. package/src/commands/xp.js +194 -0
  110. package/src/tools/audio_understanding.js +0 -0
  111. package/src/tools/bash.js +0 -0
  112. package/src/tools/browser.js +0 -0
  113. package/src/tools/canvas.js +0 -0
  114. package/src/tools/document_extract.js +0 -0
  115. package/src/tools/duckduckgo.js +0 -0
  116. package/src/tools/exa_search.js +0 -0
  117. package/src/tools/filesystem.js +0 -0
  118. package/src/tools/firecrawl.js +0 -0
  119. package/src/tools/git.js +0 -0
  120. package/src/tools/http.js +0 -0
  121. package/src/tools/image_generation.js +0 -0
  122. package/src/tools/list_dir.js +0 -0
  123. package/src/tools/llm_task.js +43 -11
  124. package/src/tools/media_understanding.js +0 -0
  125. package/src/tools/music_generation.js +0 -0
  126. package/src/tools/parallel_search.js +0 -0
  127. package/src/tools/phone_control.js +0 -0
  128. package/src/tools/phone_control_enhanced.js +0 -0
  129. package/src/tools/read_file.js +0 -0
  130. package/src/tools/searxng.js +0 -0
  131. package/src/tools/speech_to_text.js +0 -0
  132. package/src/tools/text_to_speech.js +0 -0
  133. package/src/tools/thread_ownership.js +0 -0
  134. package/src/tools/video_generation.js +0 -0
  135. package/src/tools/web_readability.js +0 -0
  136. package/src/tools/web_search.js +0 -0
  137. package/src/tools/write_file.js +0 -0
  138. package/src/utils/agents-md.js +0 -0
  139. package/src/utils/agents.js +0 -0
  140. package/src/utils/api.js +6 -2
  141. package/src/utils/approvals.js +0 -0
  142. package/src/utils/audit.js +199 -0
  143. package/src/utils/background.js +0 -0
  144. package/src/utils/baileys.js +0 -0
  145. package/src/utils/branding.js +136 -0
  146. package/src/utils/commands.js +0 -0
  147. package/src/utils/config.js +0 -0
  148. package/src/utils/cost-tracker.js +360 -0
  149. package/src/utils/cron.js +0 -0
  150. package/src/utils/dashboard-server.js +284 -0
  151. package/src/utils/errors.js +0 -0
  152. package/src/utils/format.js +7 -10
  153. package/src/utils/gateway-ws.js +0 -0
  154. package/src/utils/headless.js +0 -0
  155. package/src/utils/history.js +0 -0
  156. package/src/utils/hooks.js +0 -0
  157. package/src/utils/inquirer-wrapper.js +0 -0
  158. package/src/utils/mcp-client.js +0 -0
  159. package/src/utils/mcp.js +0 -0
  160. package/src/utils/memory.js +0 -0
  161. package/src/utils/parallel-tools.js +0 -0
  162. package/src/utils/path-utils.js +0 -0
  163. package/src/utils/pattern-detector.js +314 -0
  164. package/src/utils/plugin-registry.js +0 -0
  165. package/src/utils/secret-scanner.js +204 -0
  166. package/src/utils/secrets.js +0 -0
  167. package/src/utils/sessions.js +0 -0
  168. package/src/utils/skills.js +0 -0
  169. package/src/utils/sub-agent.js +6 -0
  170. package/src/utils/token-budget.js +0 -0
  171. package/src/utils/tool-adapter.js +0 -0
  172. package/src/utils/tool-runner.js +0 -0
  173. package/src/utils/tui.js +750 -0
  174. package/src/utils/web-fetch.js +0 -0
package/bin/natureco.js CHANGED
@@ -34,6 +34,13 @@ const vydra = require('../src/commands/vydra');
34
34
  const agent = require('../src/commands/agent');
35
35
  const approvals = require('../src/commands/approvals');
36
36
  const backup = require('../src/commands/backup');
37
+ const audit = require('../src/commands/audit');
38
+ const cost = require('../src/commands/cost');
39
+ const naturehub = require('../src/commands/naturehub');
40
+ const medium = require('../src/commands/medium');
41
+ const seo = require('../src/commands/seo');
42
+ const xp = require('../src/commands/xp');
43
+ const team = require('../src/commands/team');
37
44
  const capability = require('../src/commands/capability');
38
45
  const commitments = require('../src/commands/commitments');
39
46
  const completion = require('../src/commands/completion');
@@ -182,11 +189,11 @@ program
182
189
  .action(login);
183
190
 
184
191
  program
185
- .command('setup')
186
- .description('Run initial setup wizard')
187
- .action(async () => {
192
+ .command('setup [action]')
193
+ .description('Run initial setup wizard (wizard|config|workspace|dirs|status)')
194
+ .action(async (action) => {
188
195
  const setup = require('../src/commands/setup');
189
- await setup();
196
+ await setup(action ? [action] : []);
190
197
  });
191
198
 
192
199
  program
@@ -567,6 +574,55 @@ program
567
574
  modelsCmd(allArgs);
568
575
  });
569
576
 
577
+ program
578
+ .command('audit [action] [params...]')
579
+ .description('Audit log görüntüleyici (today|stats|show|search|files|cleanup|tail)')
580
+ .action((action, params) => {
581
+ audit(action ? [action, ...(params || [])] : ['today']);
582
+ });
583
+
584
+ program
585
+ .command('cost [action] [params...]')
586
+ .description('Maliyet takibi (today|week|month|all|budget|set|model|prices)')
587
+ .action((action, params) => {
588
+ cost(action ? [action, ...(params || [])] : ['today']);
589
+ });
590
+
591
+ program
592
+ .command('naturehub [action] [params...]')
593
+ .description('Nature Hub\'a içerik yayınla (post|list|trending|config)')
594
+ .action((action, params) => {
595
+ naturehub(action ? [action, ...(params || [])] : []);
596
+ });
597
+
598
+ program
599
+ .command('medium [action] [params...]')
600
+ .description('Medium makale yayınla (draft|publish|list)')
601
+ .action((action, params) => {
602
+ medium(action ? [action, ...(params || [])] : []);
603
+ });
604
+
605
+ program
606
+ .command('seo [action] [params...]')
607
+ .description('SEO analizi (audit|meta|speed)')
608
+ .action((action, params) => {
609
+ seo(action ? [action, ...(params || [])] : []);
610
+ });
611
+
612
+ program
613
+ .command('xp [action]')
614
+ .description('NatureCo XP/Level sistemi')
615
+ .action((action) => {
616
+ xp(action ? [action] : []);
617
+ });
618
+
619
+ program
620
+ .command('team [action] [params...]')
621
+ .description('Multi-agent orkestrasyon (list|status|spawn|parallel)')
622
+ .action((action, params) => {
623
+ team(action ? [action, ...(params || [])] : []);
624
+ });
625
+
570
626
  program
571
627
  .command('memory [action] [params...]')
572
628
  .description('Manage memory (status|list|search|show|clear|index|export|import|semantic|wiki)')
@@ -877,24 +933,138 @@ program
877
933
  // === OpenClaw uyumlu alias komutlar ===
878
934
 
879
935
  program
880
- .command('acp [file]')
936
+ .command('acp [file]')
881
937
  .description('Alias for code command')
882
938
  .action((file) => {
883
939
  const codeCmd = require('../src/commands/code');
884
940
  codeCmd(file, { dir: process.cwd() });
885
941
  });
886
942
 
943
+ program
944
+ .command('web-fetch [url]')
945
+ .description('Fetch a URL and convert to markdown')
946
+ .action(async (url) => {
947
+ const webFetch = require('../src/commands/web-fetch');
948
+ await webFetch(url);
949
+ });
950
+
887
951
  program
888
952
  .command('help')
889
953
  .description('Show help information')
890
954
  .action(help);
891
955
 
892
- // Komut verilmezse gateway göster
893
- if (!process.argv.slice(2).length) {
894
- gateway().catch(err => {
895
- console.error(chalk.red(`\n❌ Hata: ${err.message}\n`));
896
- process.exit(1);
897
- });
898
- } else {
956
+ // Yardım çıktısı için colors
957
+ program.configureHelp({
958
+ sortSubcommands: true,
959
+ showGlobalOptions: true,
960
+ });
961
+
962
+ // Global options
963
+ program
964
+ .option('--no-splash', 'Splash animasyonunu atla')
965
+ .option('--plain', 'Düz metin (renk ve animasyon yok)')
966
+ .option('--profile <name>', 'Farklı profil kullan (multi-account)')
967
+ .allowUnknownOption(); // kendi custom option'larımız için
968
+
969
+ // ════════════════════════════════════════════════════════════
970
+ // First-run akışı: setup yoksa otomatik wizard'a yönlendir
971
+ // ════════════════════════════════════════════════════════════
972
+ const path = require('path');
973
+ const fs = require('fs');
974
+ const os = require('os');
975
+ const brand = require('../src/utils/branding');
976
+ const tui = require('../src/utils/tui');
977
+ tui.init();
978
+ const { firstRunScreen } = brand;
979
+
980
+ const argv = process.argv.slice(2);
981
+
982
+ // Global option'ları filtrele — bunlar command değil
983
+ const GLOBAL_FLAGS = ['--no-splash', '--plain', '--profile'];
984
+ const realArgs = argv.filter(a => !GLOBAL_FLAGS.includes(a) && !a.startsWith('--profile='));
985
+ const hasCommand = realArgs.length > 0;
986
+ const CONFIG_DIR = path.join(os.homedir(), '.natureco');
987
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
988
+
989
+ // Yardım/versiyon için asla first-run'a sokma
990
+ const skipFirstRun = argv.includes('--help') || argv.includes('-h')
991
+ || argv.includes('--version') || argv.includes('-V')
992
+ || argv[0] === 'help' || argv[0] === 'setup' || argv[0] === 'update'
993
+ || argv[0] === 'doctor' || argv[0] === 'uninstall';
994
+
995
+ // --no-splash flag'i ile splash atlanabilsin
996
+ const noSplash = argv.includes('--no-splash') || process.env.NATURECO_NO_SPLASH;
997
+
998
+ function needsFirstRun() {
999
+ try {
1000
+ if (!fs.existsSync(CONFIG_FILE)) return true;
1001
+ const cfg = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
1002
+ return !cfg.setupCompleted;
1003
+ } catch {
1004
+ return true;
1005
+ }
1006
+ }
1007
+
1008
+ async function handleNoArgs() {
1009
+ if (!hasCommand) {
1010
+ // Splash animasyonu (sadece TTY'de ve --no-splash yoksa)
1011
+ if (!noSplash && tui.CAPS.isTTY && !process.env.CI) {
1012
+ await tui.splash({
1013
+ title: 'NatureCo CLI',
1014
+ version: packageJson.version,
1015
+ subtitle: 'OpenClaw\'dan daha güvenli, daha hızlı, daha ucuz',
1016
+ duration: 1200,
1017
+ });
1018
+ }
1019
+
1020
+ if (!skipFirstRun && needsFirstRun()) {
1021
+ if (tui.CAPS.isTTY && !noSplash) {
1022
+ console.log('\n' + tui.C.amber(' ⌥ İlk kurulum hoş geldin! Hızlıca ayarlayalım.\n'));
1023
+ } else {
1024
+ console.log(firstRunScreen());
1025
+ }
1026
+ const setup = require('../src/commands/setup');
1027
+ await setup(['wizard']);
1028
+ console.log('\n');
1029
+ const userName = require('os').userInfo().username;
1030
+ console.log(tui.welcomeCard({
1031
+ version: packageJson.version,
1032
+ user: { name: userName },
1033
+ status: tui.C.green('✓ Aktif'),
1034
+ tips: brand.pickDailyTip(),
1035
+ }));
1036
+ return;
1037
+ }
1038
+ // Normal kullanım — welcome card
1039
+ const userName = require('os').userInfo().username;
1040
+ let loginStatus = 'ok';
1041
+ try {
1042
+ if (fs.existsSync(CONFIG_FILE)) {
1043
+ const cfg = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
1044
+ if (!cfg.providerApiKey && !cfg.apiKey) loginStatus = 'needed';
1045
+ } else {
1046
+ loginStatus = 'needed';
1047
+ }
1048
+ } catch { loginStatus = 'unknown'; }
1049
+ console.log('\n' + tui.welcomeCard({
1050
+ version: packageJson.version,
1051
+ user: { name: userName },
1052
+ status: loginStatus === 'ok' ? tui.C.green('✓ Aktif') : tui.C.amber('⚠ API key gerekli'),
1053
+ tips: brand.pickDailyTip(),
1054
+ }));
1055
+ return;
1056
+ }
1057
+ // Global option'ları filtrele (--no-splash, --plain, --profile) ve parse et
1058
+ const opts = program.opts();
1059
+ if (opts.profile) {
1060
+ process.env.NATURECO_PROFILE = opts.profile;
1061
+ // TODO: profile dizinini değiştir
1062
+ }
1063
+ if (opts.plain) {
1064
+ process.env.FORCE_COLOR = '0';
1065
+ process.env.NATURECO_NO_SPLASH = '1';
1066
+ }
899
1067
  program.parse(process.argv);
900
1068
  }
1069
+
1070
+ handleNoArgs();
package/package.json CHANGED
@@ -1,30 +1,65 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "2.23.31",
4
- "description": "NatureCo AI Bot Terminal Interface",
3
+ "version": "4.4.0",
4
+ "description": "OpenClaw'dan daha güvenli, daha hızlı, daha ucuz AI agent CLI. Multi-agent, self-evolving skills, audit log, maliyet optimizasyonu ve NatureCo platform-native.",
5
5
  "bin": {
6
6
  "natureco": "bin/natureco.js"
7
7
  },
8
8
  "files": [
9
9
  "bin/",
10
10
  "src/",
11
- "skills/"
11
+ "skills/",
12
+ "README.md",
13
+ "CHANGELOG.md",
14
+ "AUDIT.md",
15
+ "DEPLOY_v2.0.0.md"
12
16
  ],
13
17
  "scripts": {
14
18
  "test": "node bin/natureco.js help",
15
- "test:unit": "vitest run",
16
- "test:watch": "vitest watch",
17
- "test:coverage": "vitest run --coverage"
19
+ "test:unit": "node --check bin/natureco.js && node -e \"console.log('All files OK')\"",
20
+ "test:watch": "node --watch bin/natureco.js",
21
+ "test:coverage": "node --check bin/natureco.js",
22
+ "postinstall": "node bin/natureco.js doctor || true",
23
+ "prepublishOnly": "node --check bin/natureco.js"
18
24
  },
19
25
  "keywords": [
20
26
  "natureco",
21
27
  "ai",
28
+ "ai-agent",
22
29
  "bot",
23
30
  "cli",
24
- "terminal"
31
+ "terminal",
32
+ "openclaw-alternative",
33
+ "claude-code-alternative",
34
+ "multi-agent",
35
+ "self-evolving-skills",
36
+ "audit-log",
37
+ "cost-optimization",
38
+ "seo",
39
+ "türkçe",
40
+ "turkish",
41
+ "whatsapp-bot",
42
+ "telegram-bot",
43
+ "discord-bot",
44
+ "natureco-me"
25
45
  ],
26
- "author": "NatureCo",
46
+ "author": {
47
+ "name": "Gencay Olgun",
48
+ "email": "hello@natureco.me",
49
+ "url": "https://natureco.me"
50
+ },
51
+ "homepage": "https://natureco.me/cli",
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "git+https://github.com/natureco/natureco-cli.git"
55
+ },
56
+ "bugs": {
57
+ "url": "https://github.com/natureco/natureco-cli/issues"
58
+ },
27
59
  "license": "MIT",
60
+ "engines": {
61
+ "node": ">=18.0.0"
62
+ },
28
63
  "dependencies": {
29
64
  "@inquirer/prompts": "^8.5.0",
30
65
  "@whiskeysockets/baileys": "^7.0.0-rc10",
@@ -38,9 +73,6 @@
38
73
  "semver": "^7.8.1",
39
74
  "ws": "^8.20.0"
40
75
  },
41
- "engines": {
42
- "node": ">=18.0.0"
43
- },
44
76
  "devDependencies": {
45
77
  "vitest": "^4.1.9"
46
78
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -41,7 +41,7 @@ async function ask(question) {
41
41
  }, 80);
42
42
 
43
43
  try {
44
- const response = await sendMessage(apiKey, defaultBotId, question, null, systemPrompt);
44
+ const response = await sendMessage(apiKey, defaultBotId, question, null, systemPrompt, { stream: false });
45
45
 
46
46
  clearInterval(loadingInterval);
47
47
  process.stdout.write('\r');
@@ -0,0 +1,209 @@
1
+ /**
2
+ * natureco audit — Audit log görüntüleyici ve yönetimi (Phase 2)
3
+ *
4
+ * Kullanım:
5
+ * natureco audit Bugünkü log'ları göster (son 50)
6
+ * natureco audit today Bugünkü tüm loglar
7
+ * natureco audit stats Son 24 saat istatistik
8
+ * natureco audit show <date> Belirli bir günün logları (YYYY-MM-DD)
9
+ * natureco audit cleanup 30 günden eski logları sil
10
+ * natureco audit tail Canlı log akışı
11
+ * natureco audit search <q> Action veya data içinde ara
12
+ */
13
+
14
+ const chalk = require('chalk');
15
+ const tui = require('../utils/tui');
16
+ const F = require('../utils/format');
17
+ const fs = require('fs');
18
+ const path = require('path');
19
+ const audit = require('../utils/audit');
20
+
21
+ const SEVERITY_COLORS = {
22
+ command: chalk.cyan,
23
+ approval: chalk.yellow,
24
+ tool: chalk.magenta,
25
+ auth: chalk.green,
26
+ secret: chalk.red.bold,
27
+ config: chalk.blue,
28
+ cron: chalk.gray,
29
+ skill: chalk.green,
30
+ error: chalk.red,
31
+ info: chalk.white,
32
+ };
33
+
34
+ function colorizeAction(action) {
35
+ if (!action) return chalk.gray('?');
36
+ const prefix = action.split('.')[0];
37
+ const colorFn = SEVERITY_COLORS[prefix] || chalk.white;
38
+ return colorFn(action);
39
+ }
40
+
41
+ function formatEntry(entry) {
42
+ const ts = entry.ts ? entry.ts.slice(11, 19) : '--:--:--';
43
+ const action = colorizeAction(entry.action);
44
+ // data içinden en anlamlı alanı çıkar
45
+ const data = { ...entry };
46
+ delete data.ts; delete data.pid; delete data.ppid; delete data.user;
47
+ delete data.cwd; delete data.argv; delete data.action;
48
+ const dataStr = Object.keys(data).length > 0
49
+ ? ' ' + chalk.gray(JSON.stringify(data).slice(0, 100))
50
+ : '';
51
+ return `${chalk.gray(ts)} ${action}${dataStr}`;
52
+ }
53
+
54
+ function showEntries(entries, limit = 50) {
55
+ if (entries.length === 0) {
56
+ console.log(tui.C.muted('\n Kayıt yok.\n'));
57
+ return;
58
+ }
59
+ const slice = entries.slice(-limit);
60
+ console.log(tui.styled(`\n 📋 ${entries.length} kayıt${limit < entries.length ? ` (son ${limit})` : ''}`, { color: tui.PALETTE.primary, bold: true }));
61
+
62
+ // Yeni TUI tablo
63
+ const rows = slice.map(e => ({
64
+ ts: e.ts ? e.ts.slice(11, 19) : '--:--:--',
65
+ action: e.action,
66
+ data: Object.keys(e).filter(k => !['ts', 'pid', 'ppid', 'user', 'cwd', 'argv', 'action'].includes(k)).length > 0
67
+ ? JSON.stringify(Object.fromEntries(Object.entries(e).filter(([k]) => !['ts', 'pid', 'ppid', 'user', 'cwd', 'argv', 'action'].includes(k)))).slice(0, 80)
68
+ : '',
69
+ }));
70
+
71
+ console.log('\n' + tui.table(rows, [
72
+ { key: 'ts', label: 'Saat', minWidth: 10, render: r => tui.C.muted(r.ts) },
73
+ { key: 'action', label: 'Action', minWidth: 22, render: r => colorizeAction(r.action) },
74
+ { key: 'data', label: 'Veri', minWidth: 30, render: r => tui.C.dim(r.data) },
75
+ ], { borderStyle: 'round', zebra: true }));
76
+ console.log('');
77
+ }
78
+
79
+ function audit_cmd(args) {
80
+ const [action, ...params] = args || [];
81
+
82
+ if (!action || action === 'today') {
83
+ const today = new Date().toISOString().slice(0, 10);
84
+ const entries = audit.readLog(today);
85
+ showEntries(entries);
86
+ return;
87
+ }
88
+
89
+ if (action === 'stats') {
90
+ const stats = audit.stats24h();
91
+ console.log('\n' + tui.styled(' 📊 Son 24 Saat Audit İstatistiği', { color: tui.PALETTE.primary, bold: true }));
92
+ console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
93
+ console.log('\n ' + tui.C.muted('Dönem: ') + tui.C.text(stats.period));
94
+ console.log(' ' + tui.C.muted('Toplam kayıt: ') + tui.styled(String(stats.total), { color: tui.PALETTE.primary, bold: true }));
95
+ console.log('');
96
+
97
+ // TUI tablo ile
98
+ const rows = Object.entries(stats.byAction)
99
+ .sort((a, b) => b[1] - a[1])
100
+ .map(([act, count]) => {
101
+ const max = Math.max(...Object.values(stats.byAction));
102
+ const bar = tui.progressBar(count / max, 1, { width: 20, showPercent: false });
103
+ return { action: act, count: String(count), bar };
104
+ });
105
+
106
+ if (rows.length > 0) {
107
+ console.log(tui.table(rows, [
108
+ { key: 'action', label: 'Action', minWidth: 22, render: r => colorizeAction(r.action) },
109
+ { key: 'count', label: 'Sayı', minWidth: 6, render: r => tui.styled(r.count, { color: tui.PALETTE.secondary, bold: true }) },
110
+ { key: 'bar', label: 'Dağılım', minWidth: 22, render: r => tui.styled(r.bar, { color: tui.PALETTE.primary }) },
111
+ ], { borderStyle: 'round', zebra: true }));
112
+ }
113
+ console.log('');
114
+ return;
115
+ }
116
+
117
+ if (action === 'show') {
118
+ const date = params[0] || new Date().toISOString().slice(0, 10);
119
+ const entries = audit.readLog(date);
120
+ if (entries.length === 0) {
121
+ console.log(chalk.yellow(`\n ⚠️ ${date} için kayıt yok.\n`));
122
+ return;
123
+ }
124
+ showEntries(entries, 9999);
125
+ return;
126
+ }
127
+
128
+ if (action === 'cleanup') {
129
+ const removed = audit.cleanup();
130
+ console.log(chalk.green(`\n ✓ ${removed} eski log dosyası temizlendi (30 gün+).\n`));
131
+ return;
132
+ }
133
+
134
+ if (action === 'tail') {
135
+ console.log(chalk.cyan('\n 📡 Canlı audit log (Ctrl+C ile çık)...\n'));
136
+ let lastSize = 0;
137
+ const todayFile = audit.listLogFiles()[0];
138
+ const interval = setInterval(() => {
139
+ const current = audit.listLogFiles()[0];
140
+ if (current !== todayFile) {
141
+ console.log(chalk.gray(`\n ── yeni gün: ${current} ──`));
142
+ }
143
+ const file = path.join(audit.AUDIT_DIR, audit.listLogFiles()[0]);
144
+ try {
145
+ const stat = fs.statSync(file);
146
+ if (stat.size > lastSize) {
147
+ // Son eklenen satırları oku
148
+ const fd = fs.openSync(file, 'r');
149
+ const buf = Buffer.alloc(stat.size - lastSize);
150
+ fs.readSync(fd, buf, 0, buf.length, lastSize);
151
+ fs.closeSync(fd);
152
+ const lines = buf.toString('utf8').trim().split('\n');
153
+ for (const line of lines) {
154
+ try {
155
+ const entry = JSON.parse(line);
156
+ console.log(' ' + formatEntry(entry));
157
+ } catch {}
158
+ }
159
+ lastSize = stat.size;
160
+ }
161
+ } catch {}
162
+ }, 1000);
163
+ process.on('SIGINT', () => { clearInterval(interval); process.exit(0); });
164
+ return;
165
+ }
166
+
167
+ if (action === 'search') {
168
+ const query = params.join(' ').toLowerCase();
169
+ if (!query) {
170
+ console.log(chalk.red('\n ❌ Arama terimi gerekli: natureco audit search <query>\n'));
171
+ return;
172
+ }
173
+ const today = new Date().toISOString().slice(0, 10);
174
+ const yesterday = new Date(Date.now() - 86400000).toISOString().slice(0, 10);
175
+ const all = [...audit.readLog(today), ...audit.readLog(yesterday)];
176
+ const matches = all.filter(e =>
177
+ (e.action && e.action.toLowerCase().includes(query)) ||
178
+ JSON.stringify(e).toLowerCase().includes(query)
179
+ );
180
+ showEntries(matches, 200);
181
+ return;
182
+ }
183
+
184
+ if (action === 'files') {
185
+ const files = audit.listLogFiles();
186
+ console.log(chalk.bold('\n 📁 Audit log dosyaları:\n'));
187
+ for (const f of files) {
188
+ const stat = fs.statSync(path.join(audit.AUDIT_DIR, f));
189
+ const size = (stat.size / 1024).toFixed(1);
190
+ console.log(` ${chalk.cyan(f.padEnd(40))} ${chalk.gray(size + ' KB')}`);
191
+ }
192
+ console.log('');
193
+ return;
194
+ }
195
+
196
+ // Yardım
197
+ console.log(chalk.yellow('\n Kullanım:'));
198
+ console.log(chalk.gray(' natureco audit Bugünkü logları göster'));
199
+ console.log(chalk.gray(' natureco audit today Bugünkü tüm loglar'));
200
+ console.log(chalk.gray(' natureco audit stats 24 saat istatistik'));
201
+ console.log(chalk.gray(' natureco audit show <date> Belirli gün (YYYY-MM-DD)'));
202
+ console.log(chalk.gray(' natureco audit search <q> Log ara'));
203
+ console.log(chalk.gray(' natureco audit files Dosya listesi'));
204
+ console.log(chalk.gray(' natureco audit cleanup 30 günden eski logları sil'));
205
+ console.log(chalk.gray(' natureco audit tail Canlı akış'));
206
+ console.log('');
207
+ }
208
+
209
+ module.exports = audit_cmd;
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -13,12 +13,21 @@ function config(args) {
13
13
  process.exit(1);
14
14
  }
15
15
 
16
+ const SENSITIVE_KEYS = ['apiKey', 'providerApiKey', 'providerApiKey1', 'providerApiKey2', 'secret', 'token', 'password', 'webhookSecret'];
17
+
18
+ function maskSensitive(key, value) {
19
+ if (typeof value !== 'string' || value.length < 8) return value;
20
+ const lower = key.toLowerCase();
21
+ if (!SENSITIVE_KEYS.some(sk => lower.includes(sk.toLowerCase()))) return value;
22
+ return value.slice(0, 4) + '*'.repeat(Math.min(value.length - 8, 16)) + value.slice(-4);
23
+ }
24
+
16
25
  if (action === 'list') {
17
26
  const cfg = getAllConfig();
18
27
  F.header('Configuration');
19
28
  const rows = Object.entries(cfg).map(([k, v]) => [
20
29
  k,
21
- typeof v === 'string' ? v : JSON.stringify(v),
30
+ maskSensitive(k, typeof v === 'string' ? v : JSON.stringify(v)),
22
31
  ]);
23
32
  F.table(['Key', 'Value'], rows);
24
33
  return;
@@ -38,7 +47,7 @@ function config(args) {
38
47
  if (value === undefined) {
39
48
  F.info(`${key}: (tanımlı değil)`);
40
49
  } else {
41
- F.kv(key, JSON.stringify(value, null, 2));
50
+ F.kv(key, maskSensitive(key, JSON.stringify(value, null, 2)));
42
51
  }
43
52
  return;
44
53
  }
File without changes