i18ntk 1.2.2 → 1.3.1

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 (117) hide show
  1. package/CHANGELOG.md +75 -2
  2. package/LICENSE +3 -1
  3. package/README.md +48 -47
  4. package/docs/README.md +42 -19
  5. package/docs/SCRIPT_DIRECTORY_GUIDE.md +278 -0
  6. package/docs/release-notes/v1.3.0.md +162 -0
  7. package/docs/release-notes/v1.3.1.md +136 -0
  8. package/main/i18ntk-analyze.js +14 -6
  9. package/main/i18ntk-autorun.js +37 -36
  10. package/main/i18ntk-complete.js +9 -5
  11. package/main/i18ntk-init.js +16 -12
  12. package/main/i18ntk-manage.js +6 -4
  13. package/main/i18ntk-sizing.js +12 -12
  14. package/main/i18ntk-summary.js +6 -2
  15. package/main/i18ntk-usage.js +5 -5
  16. package/main/i18ntk-validate.js +9 -5
  17. package/package.json +20 -19
  18. package/scripts/copy-translations.js +90 -0
  19. package/settings/i18ntk-config.json +10 -0
  20. package/settings/settings-cli.js +201 -77
  21. package/settings/settings-manager.js +19 -0
  22. package/ui-locales/de/autorun.json +69 -64
  23. package/ui-locales/de/common.json +14 -1
  24. package/ui-locales/de/errors.json +11 -1
  25. package/ui-locales/de/menu.json +10 -1
  26. package/ui-locales/de/operations.json +11 -0
  27. package/ui-locales/de/security.json +2 -1
  28. package/ui-locales/de/settings.json +67 -9
  29. package/ui-locales/de/sizing.json +14 -1
  30. package/ui-locales/de/status.json +18 -1
  31. package/ui-locales/de/test-complete-system.json +13 -1
  32. package/ui-locales/en/autorun.json +68 -65
  33. package/ui-locales/en/common.json +15 -1
  34. package/ui-locales/en/init.json +20 -5
  35. package/ui-locales/en/menu.json +1 -0
  36. package/ui-locales/en/operations.json +11 -1
  37. package/ui-locales/en/settings.json +158 -35
  38. package/ui-locales/en/validate.json +1 -0
  39. package/ui-locales/es/autorun.json +68 -65
  40. package/ui-locales/es/common.json +14 -1
  41. package/ui-locales/es/errors.json +11 -1
  42. package/ui-locales/es/menu.json +10 -1
  43. package/ui-locales/es/operations.json +11 -0
  44. package/ui-locales/es/security.json +2 -1
  45. package/ui-locales/es/settings.json +60 -9
  46. package/ui-locales/es/sizing.json +14 -1
  47. package/ui-locales/es/status.json +18 -1
  48. package/ui-locales/es/test-complete-system.json +13 -1
  49. package/ui-locales/fr/autorun.json +69 -64
  50. package/ui-locales/fr/common.json +14 -1
  51. package/ui-locales/fr/errors.json +11 -1
  52. package/ui-locales/fr/menu.json +10 -1
  53. package/ui-locales/fr/operations.json +11 -0
  54. package/ui-locales/fr/security.json +2 -1
  55. package/ui-locales/fr/settings.json +60 -9
  56. package/ui-locales/fr/sizing.json +14 -1
  57. package/ui-locales/fr/status.json +18 -1
  58. package/ui-locales/fr/test-complete-system.json +13 -1
  59. package/ui-locales/ja/autorun.json +69 -64
  60. package/ui-locales/ja/common.json +14 -1
  61. package/ui-locales/ja/errors.json +11 -1
  62. package/ui-locales/ja/menu.json +10 -1
  63. package/ui-locales/ja/operations.json +11 -0
  64. package/ui-locales/ja/security.json +2 -1
  65. package/ui-locales/ja/settings.json +60 -9
  66. package/ui-locales/ja/sizing.json +14 -1
  67. package/ui-locales/ja/status.json +18 -1
  68. package/ui-locales/ja/test-complete-system.json +13 -1
  69. package/ui-locales/pt/analyze.json +2 -1
  70. package/ui-locales/pt/autorun.json +69 -64
  71. package/ui-locales/pt/common.json +14 -1
  72. package/ui-locales/pt/errors.json +11 -1
  73. package/ui-locales/pt/init.json +5 -1
  74. package/ui-locales/pt/menu.json +10 -1
  75. package/ui-locales/pt/operations.json +11 -0
  76. package/ui-locales/pt/security.json +2 -1
  77. package/ui-locales/pt/settings.json +60 -9
  78. package/ui-locales/pt/sizing.json +14 -1
  79. package/ui-locales/pt/status.json +18 -1
  80. package/ui-locales/pt/test-complete-system.json +13 -1
  81. package/ui-locales/ru/autorun.json +69 -64
  82. package/ui-locales/ru/common.json +14 -1
  83. package/ui-locales/ru/errors.json +11 -1
  84. package/ui-locales/ru/menu.json +10 -1
  85. package/ui-locales/ru/operations.json +11 -0
  86. package/ui-locales/ru/security.json +2 -1
  87. package/ui-locales/ru/settings.json +60 -9
  88. package/ui-locales/ru/sizing.json +14 -1
  89. package/ui-locales/ru/status.json +18 -1
  90. package/ui-locales/ru/test-complete-system.json +13 -1
  91. package/ui-locales/zh/autorun.json +69 -64
  92. package/ui-locales/zh/common.json +14 -1
  93. package/ui-locales/zh/errors.json +11 -1
  94. package/ui-locales/zh/menu.json +10 -1
  95. package/ui-locales/zh/operations.json +11 -0
  96. package/ui-locales/zh/security.json +2 -1
  97. package/ui-locales/zh/settings.json +67 -9
  98. package/ui-locales/zh/sizing.json +13 -1
  99. package/ui-locales/zh/status.json +25 -8
  100. package/ui-locales/zh/test-complete-system.json +13 -1
  101. package/utils/test-complete-system.js +178 -162
  102. package/settings/backups/i18ntk-config-backup-2025-08-01T23-38-43-753Z.json +0 -117
  103. package/ui-locales/de-old.json +0 -705
  104. package/ui-locales/de.json +0 -15
  105. package/ui-locales/en-old.json +0 -709
  106. package/ui-locales/en.json +0 -15
  107. package/ui-locales/es-old.json +0 -654
  108. package/ui-locales/es.json +0 -15
  109. package/ui-locales/fr-old.json +0 -606
  110. package/ui-locales/fr.json +0 -15
  111. package/ui-locales/ja-old.json +0 -660
  112. package/ui-locales/ja.json +0 -15
  113. package/ui-locales/pt.json +0 -15
  114. package/ui-locales/ru-old.json +0 -655
  115. package/ui-locales/ru.json +0 -15
  116. package/ui-locales/zh-old.json +0 -647
  117. package/ui-locales/zh.json +0 -15
@@ -68,7 +68,7 @@ class SettingsCLI {
68
68
  this.schema = settingsManager.getSettingsSchema();
69
69
  return true;
70
70
  } catch (error) {
71
- this.error(`Failed to initialize settings: ${error.message}`);
71
+ this.error(this.t('settings.initFailed', { error: error.message }));
72
72
  return false;
73
73
  }
74
74
  }
@@ -113,7 +113,7 @@ class SettingsCLI {
113
113
  console.log(colors.reset);
114
114
 
115
115
  if (this.modified) {
116
- console.log(`${colors.yellow}⚠️ You have unsaved changes${colors.reset}\n`);
116
+ console.log(`${colors.yellow}${this.t('settings.mainMenu.unsavedChangesWarning')}${colors.reset}\n`);
117
117
  }
118
118
  }
119
119
 
@@ -124,12 +124,14 @@ class SettingsCLI {
124
124
  const options = [
125
125
  { key: '1', label: this.t('settings.mainMenu.uiSettings'), description: this.t('settings.mainMenu.uiSettingsDesc') },
126
126
  { key: '2', label: this.t('settings.mainMenu.directorySettings'), description: this.t('settings.mainMenu.directorySettingsDesc') },
127
- { key: '3', label: this.t('settings.mainMenu.processingSettings'), description: this.t('settings.mainMenu.processingSettingsDesc') },
128
- { key: '4', label: this.t('settings.mainMenu.advancedSettings'), description: this.t('settings.mainMenu.advancedSettingsDesc') },
129
- { key: '5', label: this.t('settings.mainMenu.viewAllSettings'), description: this.t('settings.mainMenu.viewAllSettingsDesc') },
130
- { key: '6', label: this.t('settings.mainMenu.importExport'), description: this.t('settings.mainMenu.importExportDesc') },
131
- { key: '7', label: this.t('settings.mainMenu.resetToDefaults'), description: this.t('settings.mainMenu.resetToDefaultsDesc') },
132
- { key: '8', label: this.t('settings.mainMenu.reportBug'), description: this.t('settings.mainMenu.reportBugDesc') },
127
+ { key: '3', label: this.t('settings.mainMenu.scriptDirectorySettings'), description: this.t('settings.mainMenu.scriptDirectorySettingsDesc') },
128
+ { key: '4', label: this.t('settings.mainMenu.processingSettings'), description: this.t('settings.mainMenu.processingSettingsDesc') },
129
+ { key: '5', label: this.t('settings.mainMenu.advancedSettings'), description: this.t('settings.mainMenu.advancedSettingsDesc') },
130
+ { key: '6', label: this.t('settings.mainMenu.viewAllSettings'), description: this.t('settings.mainMenu.viewAllSettingsDesc') },
131
+ { key: '7', label: this.t('settings.mainMenu.importExport'), description: this.t('settings.mainMenu.importExportDesc') },
132
+ { key: '8', label: this.t('settings.mainMenu.resetToDefaults'), description: this.t('settings.mainMenu.resetToDefaultsDesc') },
133
+ { key: '9', label: this.t('settings.mainMenu.reportBug'), description: this.t('settings.mainMenu.reportBugDesc') },
134
+ { key: '0', label: this.t('settings.mainMenu.updatePackage'), description: this.t('settings.mainMenu.updatePackageDesc') },
133
135
  { key: 's', label: this.t('settings.mainMenu.saveChanges'), description: this.t('settings.mainMenu.saveChangesDesc') },
134
136
  { key: 'h', label: this.t('settings.mainMenu.help'), description: this.t('settings.mainMenu.helpDesc') },
135
137
  { key: 'q', label: this.t('settings.mainMenu.quit'), description: this.t('settings.mainMenu.quitDesc') }
@@ -160,23 +162,29 @@ class SettingsCLI {
160
162
  await this.showDirectorySettings();
161
163
  break;
162
164
  case '3':
163
- await this.showProcessingSettings();
165
+ await this.showScriptDirectorySettings();
164
166
  break;
165
167
  case '4':
166
- await this.showAdvancedSettings();
168
+ await this.showProcessingSettings();
167
169
  break;
168
170
  case '5':
169
- await this.showAllSettings();
171
+ await this.showAdvancedSettings();
170
172
  break;
171
173
  case '6':
172
- await this.showImportExport();
174
+ await this.showAllSettings();
173
175
  break;
174
176
  case '7':
175
- await this.resetToDefaults();
177
+ await this.showImportExport();
176
178
  break;
177
179
  case '8':
180
+ await this.resetToDefaults();
181
+ break;
182
+ case '9':
178
183
  await this.reportBug();
179
184
  break;
185
+ case '0':
186
+ await this.updatePackage();
187
+ break;
180
188
  case 's':
181
189
  await this.saveSettings();
182
190
  break;
@@ -231,6 +239,30 @@ class SettingsCLI {
231
239
  await this.showSettingsCategory(dirSettings);
232
240
  }
233
241
 
242
+ /**
243
+ * Show script-specific directory settings menu
244
+ */
245
+ async showScriptDirectorySettings() {
246
+ this.clearScreen();
247
+ this.showHeader();
248
+ console.log(`${colors.bright}${this.t('settings.categories.scriptDirectorySettings')}${colors.reset}\n`);
249
+ console.log(`📁 ${colors.cyan}${this.t('settings.currentDirectory')}: ${process.cwd()}${colors.reset}`);
250
+ console.log(`💡 ${colors.dim}${this.t('settings.relativePathHint')}${colors.reset}\n`);
251
+
252
+ const scriptDirSettings = {
253
+ 'scriptDirectories.analyze': this.t('settings.fields.scriptDirectories.analyzeLabel'),
254
+ 'scriptDirectories.complete': this.t('settings.fields.scriptDirectories.completeLabel'),
255
+ 'scriptDirectories.init': this.t('settings.fields.scriptDirectories.initLabel'),
256
+ 'scriptDirectories.manage': this.t('settings.fields.scriptDirectories.manageLabel'),
257
+ 'scriptDirectories.sizing': this.t('settings.fields.scriptDirectories.sizingLabel'),
258
+ 'scriptDirectories.summary': this.t('settings.fields.scriptDirectories.summaryLabel'),
259
+ 'scriptDirectories.usage': this.t('settings.fields.scriptDirectories.usageLabel'),
260
+ 'scriptDirectories.validate': this.t('settings.fields.scriptDirectories.validateLabel')
261
+ };
262
+
263
+ await this.showSettingsCategory(scriptDirSettings);
264
+ }
265
+
234
266
  /**
235
267
  * Show processing settings menu
236
268
  */
@@ -280,6 +312,12 @@ class SettingsCLI {
280
312
  });
281
313
 
282
314
  console.log(`\n ${colors.yellow}b${colors.reset}) ${this.t('settings.back')}`);
315
+
316
+ // Add reset option for script directories
317
+ const isScriptDirectory = Object.keys(categorySettings).some(key => key.startsWith('scriptDirectories.'));
318
+ if (isScriptDirectory) {
319
+ console.log(` ${colors.red}r${colors.reset}) ${this.t('settings.resetScriptDirectories')}`);
320
+ }
283
321
  console.log();
284
322
 
285
323
  const choice = await this.prompt(this.t('settings.selectSettingPrompt'));
@@ -288,6 +326,12 @@ class SettingsCLI {
288
326
  return;
289
327
  }
290
328
 
329
+ if (choice.toLowerCase() === 'r' && isScriptDirectory) {
330
+ await this.resetScriptDirectories();
331
+ await this.showSettingsCategory(categorySettings);
332
+ return;
333
+ }
334
+
291
335
  const index = parseInt(choice) - 1;
292
336
  if (index >= 0 && index < keys.length) {
293
337
  const key = keys[index];
@@ -402,7 +446,7 @@ class SettingsCLI {
402
446
 
403
447
  // Check if admin authentication is required
404
448
  if (this.requiresAdminAuth(key) && !this.adminAuthenticated) {
405
- console.log(`\n🔒 Admin authentication required for: ${label}`);
449
+ console.log(`\n${this.t('settings.admin.authRequired', { label: label })}`);
406
450
  const authenticated = await this.adminPin.verifyPin();
407
451
  if (!authenticated) {
408
452
  console.log(this.t('settings.admin.accessDenied'));
@@ -446,8 +490,19 @@ class SettingsCLI {
446
490
  return;
447
491
  }
448
492
 
449
- if (newValue.trim() === '') {
450
- return;
493
+ // Handle "default" keyword for script directory settings
494
+ if (newValue.trim().toLowerCase() === 'default') {
495
+ if (key.startsWith('scriptDirectories.')) {
496
+ this.setNestedValue(this.settings, key, null);
497
+ this.modified = true;
498
+ this.success(`${label} reset to system default.`);
499
+ await this.pause();
500
+ return;
501
+ } else {
502
+ this.error('"default" keyword is only supported for script directory settings.');
503
+ await this.pause();
504
+ return;
505
+ }
451
506
  }
452
507
 
453
508
  // Validate input
@@ -461,7 +516,7 @@ class SettingsCLI {
461
516
  // Convert the value
462
517
  const convertedValue = this.convertValue(newValue.trim(), schema);
463
518
  if (convertedValue === null) {
464
- this.error('Invalid value format.');
519
+ this.error(this.t('settings.invalidValueFormat'));
465
520
  await this.pause();
466
521
  return;
467
522
  }
@@ -499,7 +554,7 @@ class SettingsCLI {
499
554
  async handlePinSetup() {
500
555
  this.clearScreen();
501
556
  this.showHeader();
502
- console.log(`${colors.bright}Admin PIN Setup${colors.reset}\n`);
557
+ console.log(`${colors.bright}${this.t('settings.admin.pinSetupTitle')}${colors.reset}\n`);
503
558
 
504
559
  if (this.adminPin.isPinSet()) {
505
560
  console.log(this.t('settings.admin.pinConfigured'));
@@ -509,7 +564,7 @@ class SettingsCLI {
509
564
  console.log(' ' + this.t('settings.admin.cancel'));
510
565
  console.log();
511
566
 
512
- const choice = await this.prompt('Select option: ');
567
+ const choice = await this.prompt(this.t('settings.admin.selectOption'));
513
568
 
514
569
  switch (choice) {
515
570
  case '1':
@@ -542,7 +597,7 @@ class SettingsCLI {
542
597
  console.log(this.t('settings.admin.operationCancelled'));
543
598
  break;
544
599
  default:
545
- this.error('Invalid option.');
600
+ this.error(this.t('common.invalidOption'));
546
601
  }
547
602
  } else {
548
603
  console.log(this.t('settings.admin.noPinConfigured'));
@@ -553,7 +608,7 @@ class SettingsCLI {
553
608
  console.log(' ' + this.t('settings.admin.benefitReset'));
554
609
  console.log();
555
610
 
556
- const response = await this.prompt('Would you like to set up an admin PIN? (y/N): ');
611
+ const response = await this.prompt(this.t('settings.admin.setupPinPrompt'));
557
612
 
558
613
  if (response.toLowerCase() === 'y' || response.toLowerCase() === 'yes') {
559
614
  const success = await this.adminPin.setupPin();
@@ -640,7 +695,7 @@ class SettingsCLI {
640
695
  * Export settings to a file
641
696
  */
642
697
  async exportSettings() {
643
- const filename = await this.prompt('Enter filename (or press Enter for default): ');
698
+ const filename = await this.prompt(this.t('settings.importExport.exportFilenamePrompt'));
644
699
  const exportFile = filename.trim() || `i18n-settings-${new Date().toISOString().split('T')[0]}.json`;
645
700
 
646
701
  try {
@@ -657,7 +712,7 @@ class SettingsCLI {
657
712
  * Import settings from a file
658
713
  */
659
714
  async importSettings() {
660
- const filename = await this.prompt('Enter filename to import: ');
715
+ const filename = await this.prompt(this.t('settings.importExport.importFilenamePrompt'));
661
716
 
662
717
  if (!filename.trim()) {
663
718
  return;
@@ -679,7 +734,7 @@ class SettingsCLI {
679
734
  return;
680
735
  }
681
736
 
682
- const confirm = await this.prompt('This will replace all current settings. Continue? (y/N): ');
737
+ const confirm = await this.prompt(this.t('settings.importExport.importConfirm'));
683
738
  if (confirm.toLowerCase() === 'y') {
684
739
  this.settings = importedSettings;
685
740
  this.modified = true;
@@ -712,12 +767,11 @@ class SettingsCLI {
712
767
  async resetToDefaults() {
713
768
  this.clearScreen();
714
769
  this.showHeader();
715
- console.log(`${colors.bright}Reset to Defaults${colors.reset}\n`);
770
+ console.log(`${colors.bright}${this.t('settings.resetToDefaultsTitle')}${colors.reset}\n`);
771
+ console.log(`${colors.yellow}${this.t('settings.resetWarning1')}${colors.reset}`);
772
+ console.log(`${colors.yellow}${this.t('settings.resetWarning2')}${colors.reset}\n`);
716
773
 
717
- console.log(`${colors.yellow}⚠️ This will reset ALL settings to their default values.${colors.reset}`);
718
- console.log(`${colors.yellow}⚠️ Any unsaved changes will be lost.${colors.reset}\n`);
719
-
720
- const confirm = await this.prompt('Are you sure you want to continue? (y/N): ');
774
+ const confirm = await this.prompt(this.t('settings.resetConfirm'));
721
775
 
722
776
  if (confirm.toLowerCase() === 'y') {
723
777
  try {
@@ -733,6 +787,46 @@ class SettingsCLI {
733
787
  await this.pause();
734
788
  }
735
789
 
790
+ /**
791
+ * Reset script directories to defaults
792
+ */
793
+ async resetScriptDirectories() {
794
+ this.clearScreen();
795
+ this.showHeader();
796
+ console.log(`${colors.bright}${this.t('settings.resetScriptDirectoriesTitle')}${colors.reset}\n`);
797
+ console.log(`${colors.yellow}${this.t('settings.resetScriptDirectoriesWarning1')}${colors.reset}`);
798
+ console.log(`${colors.yellow}${this.t('settings.resetScriptDirectoriesWarning2')}${colors.reset}\n`);
799
+
800
+ const confirm = await this.prompt(this.t('settings.resetScriptDirectoriesConfirm'));
801
+
802
+ if (confirm.toLowerCase() === 'y') {
803
+ try {
804
+ // Reset all script directory settings to null (use system defaults)
805
+ const scriptDirKeys = [
806
+ 'scriptDirectories.analyze',
807
+ 'scriptDirectories.complete',
808
+ 'scriptDirectories.init',
809
+ 'scriptDirectories.manage',
810
+ 'scriptDirectories.sizing',
811
+ 'scriptDirectories.summary',
812
+ 'scriptDirectories.usage',
813
+ 'scriptDirectories.validate'
814
+ ];
815
+
816
+ scriptDirKeys.forEach(key => {
817
+ this.setNestedValue(this.settings, key, null);
818
+ });
819
+
820
+ this.modified = true;
821
+ this.success('Script directories reset to system defaults successfully.');
822
+ } catch (error) {
823
+ this.error(`Failed to reset script directories: ${error.message}`);
824
+ }
825
+ }
826
+
827
+ await this.pause();
828
+ }
829
+
736
830
  /**
737
831
  * Save current settings
738
832
  */
@@ -758,31 +852,30 @@ class SettingsCLI {
758
852
  async showHelp() {
759
853
  this.clearScreen();
760
854
  this.showHeader();
761
- console.log(`${colors.bright}Help Information${colors.reset}\n`);
762
-
763
- console.log(`${colors.cyan}Navigation:${colors.reset}`);
764
- console.log(` • Use number keys to select menu options`);
765
- console.log(` • Use 'b' to go back to previous menu`);
766
- console.log(` • Use 'q' to quit (with save prompt if needed)`);
767
- console.log(` • Use 's' to save changes at any time\n`);
768
-
769
- console.log(`${colors.cyan}Settings Categories:${colors.reset}`);
770
- console.log(` • UI Settings: Interface language, theme, and display options`);
771
- console.log(` • Directory Settings: Paths for locales, reports, and backups`);
772
- console.log(` • Processing Settings: Performance and batch processing options`);
773
- console.log(` • Advanced Settings: Validation, logging, and expert features\n`);
774
-
775
- console.log(`${colors.cyan}Environment Variables:${colors.reset}`);
776
- console.log(` • I18N_CONFIG_FILE: Custom config file path`);
777
- console.log(` • I18N_LOCALE_DIR: Override locales directory`);
778
- console.log(` • I18N_REPORTS_DIR: Override reports directory\n`);
779
-
780
- console.log(`${colors.cyan}Command Line Usage:${colors.reset}`);
781
- console.log(` • i18ntk manage --command=settings`);
782
- console.log(` • node settings-cli.js (direct access)`);
783
- console.log(` • All scripts support --config flag for custom config files\n`);
784
-
785
- console.log(`Press Enter to continue...`);
855
+ console.log(`${colors.bright}${this.t('settings.help.title')}${colors.reset}\n`);
856
+ console.log(`${colors.cyan}${this.t('settings.help.navigationTitle')}${colors.reset}`);
857
+ console.log(`${this.t('settings.help.navigation1')}`);
858
+ console.log(`${this.t('settings.help.navigation2')}`);
859
+ console.log(`${this.t('settings.help.navigation3')}`);
860
+ console.log(`${this.t('settings.help.navigation4')}\n`);
861
+
862
+ console.log(`${colors.cyan}${this.t('settings.help.categoriesTitle')}${colors.reset}`);
863
+ console.log(`${this.t('settings.help.categoryUI')}`);
864
+ console.log(`${this.t('settings.help.categoryDirectory')}`);
865
+ console.log(`${this.t('settings.help.categoryProcessing')}`);
866
+ console.log(`${this.t('settings.help.categoryAdvanced')}\n`);
867
+
868
+ console.log(`${colors.cyan}${this.t('settings.help.envVarsTitle')}${colors.reset}`);
869
+ console.log(`${this.t('settings.help.envVar1')}`);
870
+ console.log(`${this.t('settings.help.envVar2')}`);
871
+ console.log(`${this.t('settings.help.envVar3')}\n`);
872
+
873
+ console.log(`${colors.cyan}${this.t('settings.help.cliUsageTitle')}${colors.reset}`);
874
+ console.log(`${this.t('settings.help.cliUsage1')}`);
875
+ console.log(`${this.t('settings.help.cliUsage2')}`);
876
+ console.log(`${this.t('settings.help.cliUsage3')}\n`);
877
+
878
+ console.log(`${this.t('settings.pressEnter')}\n`);
786
879
  await this.prompt('');
787
880
  }
788
881
 
@@ -792,19 +885,12 @@ class SettingsCLI {
792
885
  async reportBug() {
793
886
  this.clearScreen();
794
887
  this.showHeader();
795
- console.log(`${colors.bright}Report a Bug${colors.reset}\n`);
796
-
797
- console.log(`${colors.cyan}GitHub Issues Page:${colors.reset}`);
798
- console.log(`https://github.com/vladnoskv/i18n-management-toolkit-main/issues\n`);
799
-
800
- console.log(`${colors.yellow}Before reporting a bug, please:${colors.reset}`);
801
- console.log(` • Check if the issue already exists`);
802
- console.log(` • Include steps to reproduce the problem`);
803
- console.log(` • Provide error messages and logs`);
804
- console.log(` • Mention your operating system and Node.js version\n`);
805
-
806
- console.log(`${colors.cyan}Opening GitHub issues page...${colors.reset}`);
807
-
888
+ console.log(`${colors.bright}${this.t('settings.reportBug.title')}${colors.reset}\n`);
889
+ console.log(this.t('settings.reportBug.description'));
890
+ console.log(`
891
+ ${colors.dim}${this.t('settings.reportBug.link')}: https://github.com/vladnoskv/i18n-management-toolkit-main/issues${colors.reset}
892
+ `);
893
+
808
894
  try {
809
895
  const { exec } = require('child_process');
810
896
  const url = 'https://github.com/vladnoskv/i18n-management-toolkit-main/issues';
@@ -825,34 +911,72 @@ class SettingsCLI {
825
911
 
826
912
  exec(command, (error) => {
827
913
  if (error) {
828
- console.log(`${colors.yellow}Could not automatically open browser.${colors.reset}`);
829
- console.log(`Please manually visit: ${url}`);
914
+ console.log(`${colors.yellow}${this.t('settings.reportBug.browserOpenFailed')}${colors.reset}`);
915
+ console.log(`${this.t('settings.reportBug.manualVisit', { url: url })}`);
830
916
  } else {
831
- console.log(`${colors.green}✅ Browser opened successfully!${colors.reset}`);
917
+ console.log(`${colors.green}${this.t('settings.reportBug.browserOpened')}${colors.reset}`);
832
918
  }
833
919
  });
834
920
  } catch (error) {
835
- console.log(`${colors.yellow}Could not automatically open browser.${colors.reset}`);
836
- console.log(`Please manually visit: https://github.com/vladnoskv/i18n-management-toolkit-main/issues`);
921
+ console.log(`${colors.yellow}${this.t('settings.reportBug.browserOpenFailed')}${colors.reset}`);
922
+ console.log(`${this.t('settings.reportBug.manualVisit', { url: 'https://github.com/vladnoskv/i18n-management-toolkit-main/issues' })}`);
837
923
  }
838
924
 
839
925
  await this.pause();
840
926
  }
841
927
 
928
+ /**
929
+ * Update the i18n-toolkit package via npm
930
+ */
931
+ async updatePackage() {
932
+ this.clearScreen();
933
+ this.showHeader();
934
+ console.log(`${colors.bright}${this.t('settings.updatePackage.title')}${colors.reset}\n`);
935
+ console.log(this.t('settings.updatePackage.description'));
936
+ console.log(`
937
+ ${colors.dim}${this.t('settings.updatePackage.command')}: npm update i18ntk -g${colors.reset}
938
+ `);
939
+
940
+ const confirm = await this.prompt(this.t('settings.updatePackage.prompt'));
941
+
942
+ if (confirm.toLowerCase() === 'y') {
943
+ try {
944
+ const { exec } = require('child_process');
945
+ console.log(this.t('settings.updatePackage.updating'));
946
+ exec('npm update i18ntk -g', (error, stdout, stderr) => {
947
+ if (error) {
948
+ this.error(`${this.t('settings.updatePackage.error')}: ${error.message}`);
949
+ console.error(stderr);
950
+ } else {
951
+ this.success(this.t('settings.updatePackage.success'));
952
+ console.log(stdout);
953
+ }
954
+ this.pause();
955
+ });
956
+ } catch (error) {
957
+ this.error(`${this.t('settings.updatePackage.error')}: ${error.message}`);
958
+ this.pause();
959
+ }
960
+ } else {
961
+ this.warning(this.t('settings.updatePackage.cancelled'));
962
+ await this.pause();
963
+ }
964
+ }
965
+
842
966
  /**
843
967
  * Quit the application
844
968
  */
845
969
  async quit() {
846
970
  if (this.modified) {
847
- console.log(`\n${colors.yellow}⚠️ You have unsaved changes.${colors.reset}`);
848
- const save = await this.prompt('Save before quitting? (Y/n): ');
849
-
971
+ console.log(`\n${colors.yellow}${this.t('settings.mainMenu.unsavedChangesWarning')}${colors.reset}`);
972
+ const save = await this.prompt(this.t('settings.mainMenu.saveChangesBeforeQuit'));
973
+
850
974
  if (save.toLowerCase() !== 'n') {
851
975
  await this.saveSettings();
852
976
  }
853
977
  }
854
-
855
- console.log(`\n${colors.green}Thank you for using the i18n settings manager!${colors.reset}`);
978
+
979
+ console.log(`\n${colors.green}${this.t('settings.goodbyeMessage')}${colors.reset}`);
856
980
  this.rl.close();
857
981
  process.exit(0);
858
982
  }
@@ -22,6 +22,18 @@ class SettingsManager {
22
22
  defaultLanguages: ['de', 'es', 'fr', 'ru'], // Default target languages | Example: ['de', 'es', 'fr', 'ru', 'ja', 'zh']
23
23
  outputDir: './i18ntk-reports', // Default: './i18ntk-reports' | Example: './reports/i18n'
24
24
 
25
+ // Per-Script Directory Configuration (optional overrides)
26
+ scriptDirectories: {
27
+ analyze: null, // Custom sourceDir for i18ntk-analyze.js
28
+ init: null, // Custom sourceDir for i18ntk-init.js
29
+ validate: null, // Custom sourceDir for i18ntk-validate.js
30
+ complete: null, // Custom sourceDir for i18ntk-complete.js
31
+ manage: null, // Custom sourceDir for i18ntk-manage.js
32
+ summary: null, // Custom sourceDir for i18ntk-summary.js
33
+ usage: null, // Custom sourceDir for i18ntk-usage.js
34
+ sizing: null // Custom sourceDir for i18ntk-sizing.js
35
+ },
36
+
25
37
  // Report Settings
26
38
  reportLanguage: 'auto', // Default: 'auto' (matches UI language) | Options: 'auto', 'en', 'de', 'es', 'fr', 'ru', 'ja', 'zh'
27
39
 
@@ -158,6 +170,13 @@ class SettingsManager {
158
170
  merged.advanced = { ...this.defaultConfig.advanced, ...loadedSettings.advanced };
159
171
  }
160
172
 
173
+ if (loadedSettings.scriptDirectories) {
174
+ merged.scriptDirectories = {
175
+ ...this.defaultConfig.scriptDirectories,
176
+ ...loadedSettings.scriptDirectories
177
+ };
178
+ }
179
+
161
180
  return merged;
162
181
  }
163
182
 
@@ -1,66 +1,71 @@
1
1
  {
2
- "missingRequiredFile": "Missing required file: {file}",
3
- "runInitializationFirst": "Please run initialization first.",
4
- "initializationCheckPassed": "Initialization check passed.",
5
- "runningStep": "Running step: {stepName}",
6
- "commandLabel": "Command: {command}",
7
- "stepRunning": "Step '{stepName}' running...",
8
- "stepCompletedWithTime": "Step '{stepName}' completed in {duration}ms.",
9
- "stepCompleted": "Step '{stepName}' completed.",
10
- "stepFailed": "Step '{stepName}' failed.",
11
- "errorLabel": "Error: {error}",
12
- "stepFailedWithError": "Step '{stepName}' failed with error: {error}",
13
- "requiredStepFailed": "Required step failed. Stopping workflow.",
14
- "optionalStepFailed": "Optional step failed. Continuing workflow.",
15
- "startingAutoRunWorkflow": "Starting Auto-Run Workflow...",
16
- "workflowIncludesSteps": "Workflow includes {count} steps:",
17
- "stepRequired": "(Required)",
18
- "stepOptional": "(Optional)",
19
- "startingExecution": "Starting execution...",
20
- "workflowStopped": "Workflow stopped.",
21
- "workflowCompleted": "Workflow completed.",
22
- "pressEnterToContinue": "Press Enter to continue...",
23
- "runningSelectedSteps": "Running selected steps...",
24
- "invalidStepNumber": "Invalid step number: {stepNum}",
25
- "executionReport": "Execution Report:",
26
- "successfulSteps": "Successful steps: {count}",
27
- "failedSteps": "Failed steps: {count}",
28
- "requiredFailedSteps": "Required steps failed: {count}",
29
- "stepDetails": "Step Details:",
30
- "errorDetails": "Error: {error}",
31
- "reportSavedTo": "Report saved to: {path}",
32
- "overallStatusSuccess": "SUCCESS",
33
- "overallStatusFailed": "FAILED",
34
- "overallStatus": "Overall Status: {status}",
35
- "customSettingsConfiguration": "Custom Settings Configuration",
36
- "pressEnterForDefaults": "Press Enter to use default settings for any prompt.",
37
- "sourceDirPrompt": "Enter source directory (default: {default}): ",
38
- "sourceLangPrompt": "Enter source language (default: {default}): ",
39
- "targetLangsPrompt": "Enter target languages (comma-separated, default: {default}): ",
40
- "translationMarkerPrompt": "Enter translation marker (default: {default}): ",
41
- "outputDirPrompt": "Enter output directory for reports (default: {default}): ",
42
- "settingsUpdatedSuccessfully": "Settings updated successfully!",
43
- "errorConfiguringSettings": "Error configuring settings: {error}",
44
- "autoRunScriptTitle": "Auto-Run Script",
45
- "usageTitle": "Usage:",
46
- "runAllSteps": "node i18ntk-autorun.js --all - Run all steps defined in i18ntk-config.json",
47
- "configureSettingsFirst": "node i18ntk-autorun.js --config - Configure settings for the workflow",
48
- "runSpecificSteps": "node i18ntk-autorun.js --steps <step_numbers> - Run specific steps (e.g., --steps 1,3,5)",
49
- "showHelp": "node i18ntk-autorun.js --help - Show this help message",
50
- "availableSteps": "Available Steps:",
51
- "examplesTitle": "Examples:",
52
- "configExample": "node i18ntk-autorun.js --config",
53
- "stepsExample1": "node i18ntk-autorun.js --steps 1,2,3",
54
- "stepsExample2": "node i18ntk-autorun.js --all",
55
- "configurationComplete": "Configuration complete.",
56
- "runAutoRunCommand": "Now you can run the auto-run command.",
57
- "configurationFailed": "Configuration failed: {error}",
58
- "noValidStepNumbers": "No valid step numbers provided.",
59
- "autoRunFailed": "Auto-run failed: {error}",
60
- "stepAnalyzeTranslations": "Übersetzungen analysieren",
61
- "stepValidateTranslations": "Übersetzungen validieren",
62
- "stepCheckUsage": "Verwendung prüfen",
63
- "stepCompleteTranslations": "Übersetzungen vervollständigen",
64
- "stepAnalyzeSizing": "Größe analysieren",
65
- "stepGenerateSummary": "Zusammenfassung erstellen"
2
+ "autorun": {
3
+ "missingRequiredFile": "[DE] Missing required file: {file}",
4
+ "runInitializationFirst": "[DE] Please run initialization first.",
5
+ "initializationCheckPassed": "[DE] Initialization check passed.",
6
+ "runningStep": "[DE] Running step: {stepName}",
7
+ "commandLabel": "[DE] Command: {command}",
8
+ "stepRunning": "[DE] Step '{stepName}' running...",
9
+ "stepCompletedWithTime": "[DE] Step '{stepName}' completed in {duration}ms.",
10
+ "stepCompleted": "[DE] Step '{stepName}' completed.",
11
+ "stepFailed": "[DE] Step '{stepName}' failed.",
12
+ "errorLabel": "[DE] Error: {error}",
13
+ "stepFailedWithError": "[DE] Step '{stepName}' failed with error: {error}",
14
+ "requiredStepFailed": "[DE] Required step failed. Stopping workflow.",
15
+ "optionalStepFailed": "[DE] Optional step failed. Continuing workflow.",
16
+ "startingAutoRunWorkflow": "[DE] Starting Auto-Run Workflow...",
17
+ "workflowIncludesSteps": "[DE] Workflow includes {count} steps:",
18
+ "stepRequired": "[DE] (Required)",
19
+ "stepOptional": "[DE] (Optional)",
20
+ "startingExecution": "[DE] Starting execution...",
21
+ "workflowStopped": "[DE] Workflow stopped.",
22
+ "workflowCompleted": "[DE] Workflow completed.",
23
+ "pressEnterToContinue": "[DE] Press Enter to continue...",
24
+ "runningSelectedSteps": "[DE] Running selected steps...",
25
+ "invalidStepNumber": "[DE] Invalid step number: {stepNum}",
26
+ "executionReport": "[DE] Execution Report:",
27
+ "successfulSteps": "[DE] Successful steps: {count}",
28
+ "failedSteps": "[DE] Failed steps: {count}",
29
+ "requiredFailedSteps": "[DE] Required steps failed: {count}",
30
+ "stepDetails": "[DE] Step Details:",
31
+ "errorDetails": "[DE] Error: {error}",
32
+ "reportSavedTo": "[DE] Report saved to: {path}",
33
+ "overallStatusSuccess": "[DE] SUCCESS",
34
+ "overallStatusFailed": "[DE] FAILED",
35
+ "overallStatus": "[DE] Overall Status: {status}",
36
+ "customSettingsConfiguration": "[DE] Custom Settings Configuration",
37
+ "pressEnterForDefaults": "[DE] Press Enter to use default settings for any prompt.",
38
+ "sourceDirPrompt": "[DE] Enter source directory (default: {default}): ",
39
+ "sourceLangPrompt": "[DE] Enter source language (default: {default}): ",
40
+ "targetLangsPrompt": "[DE] Enter target languages (comma-separated, default: {default}): ",
41
+ "translationMarkerPrompt": "[DE] Enter translation marker (default: {default}): ",
42
+ "outputDirPrompt": "[DE] Enter output directory for reports (default: {default}): ",
43
+ "settingsUpdatedSuccessfully": "[DE] Settings updated successfully!",
44
+ "errorConfiguringSettings": "[DE] Error configuring settings: {error}",
45
+ "autoRunScriptTitle": "[DE] Auto-Run Script",
46
+ "usageTitle": "[DE] Usage:",
47
+ "runAllSteps": "[DE] node i18ntk-autorun.js --all - Run all steps defined in i18ntk-config.json",
48
+ "configureSettingsFirst": "[DE] node i18ntk-autorun.js --config - Configure settings for the workflow",
49
+ "runSpecificSteps": "[DE] node i18ntk-autorun.js --steps <step_numbers> - Run specific steps (e.g., --steps 1,3,5)",
50
+ "showHelp": "[DE] node i18ntk-autorun.js --help - Show this help message",
51
+ "availableSteps": "[DE] Available Steps:",
52
+ "examplesTitle": "[DE] Examples:",
53
+ "configExample": "[DE] node i18ntk-autorun.js --config",
54
+ "stepsExample1": "[DE] node i18ntk-autorun.js --steps 1,2,3",
55
+ "stepsExample2": "[DE] node i18ntk-autorun.js --all",
56
+ "configurationComplete": "[DE] Configuration complete.",
57
+ "runAutoRunCommand": "[DE] Now you can run the auto-run command.",
58
+ "configurationFailed": "[DE] Configuration failed: {error}",
59
+ "noValidStepNumbers": "[DE] No valid step numbers provided.",
60
+ "autoRunFailed": "[DE] Auto-run failed: {error}",
61
+ "stepAnalyzeTranslations": "[DE] Analyze Translations",
62
+ "stepValidateTranslations": "[DE] Validate Translations",
63
+ "stepCheckUsage": "[DE] Check Usage",
64
+ "stepCompleteTranslations": "[DE] Complete Translations",
65
+ "stepAnalyzeSizing": "[DE] Analyze Sizing",
66
+ "stepGenerateSummary": "[DE] Generate Summary",
67
+ "translationLoadWarning": "[DE] Warning: Could not load {lang} translations",
68
+ "configReadError": "[DE] Error reading {file}",
69
+ "separator": "[DE] =================================================="
70
+ }
66
71
  }