browser-extension-manager 1.1.10 → 1.1.11

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 CHANGED
@@ -45,9 +45,15 @@ npm start
45
45
  ## 📦 How to sync with the template
46
46
  1. Simply run `npx bxm setup` in Terminal to get all the latest updates from the **Ultimate Browser Extension template**.
47
47
 
48
+ ## 🌐 Automatic Translation
49
+ When you run `npm run build`, BEM automatically translates your `src/_locales/en/messages.json` to 16 languages using Claude CLI:
50
+ `zh`, `es`, `hi`, `ar`, `pt`, `ru`, `ja`, `de`, `fr`, `ko`, `ur`, `id`, `bn`, `tl`, `vi`, `it`
51
+
52
+ Only missing translations are generated - existing translations are preserved.
53
+
48
54
  ## 🌎 Publishing your extension
49
- 1. Run `npm run dist` in Terminal to build your extension for production in every browser.
50
- 2. Upload the respective `.zip` files to the browser's extension store.
55
+ 1. Run `npm run build` in Terminal to build your extension for production.
56
+ 2. Upload the `.zip` file to the browser's extension store.
51
57
 
52
58
  <!-- ## ⛳️ Flags
53
59
  * `--test=false` - Coming soon
@@ -2,6 +2,7 @@
2
2
  // Basic info
3
3
  manifest_version: 3,
4
4
  name: '__MSG_appName__',
5
+ short_name: '__MSG_appNameShort__',
5
6
  description: '__MSG_appDescription__',
6
7
 
7
8
  // Icon
@@ -3,6 +3,10 @@
3
3
  message: 'Ultimate Browser Extension - Browser Enhancer',
4
4
  description: 'The name of the extension.',
5
5
  },
6
+ appNameShort: {
7
+ message: 'Ultimate Browser Extension',
8
+ description: 'The short name of the extension.',
9
+ },
6
10
  appDescription: {
7
11
  message: 'Ultimate Browser Extension - A powerful tool to enhance your browsing experience.',
8
12
  description: 'The description of the extension.',
@@ -1,6 +1,7 @@
1
1
  {
2
2
  // Basic info
3
3
  name: '__MSG_appName__',
4
+ short_name: '__MSG_appNameShort__',
4
5
  description: '__MSG_appDescription__',
5
6
 
6
7
  // Background script
package/dist/gulp/main.js CHANGED
@@ -40,6 +40,7 @@ exports.build = series(
40
40
  // exports.clean,
41
41
  // exports.themes,
42
42
  exports.defaults,
43
+ exports.translate,
43
44
  exports.distribute,
44
45
  parallel(exports.sass, exports.webpack, exports.icons, exports.html),
45
46
  exports.package,
@@ -0,0 +1,196 @@
1
+ // Libraries
2
+ const Manager = new (require('../../build.js'));
3
+ const logger = Manager.logger('translate');
4
+ const { series } = require('gulp');
5
+ const jetpack = require('fs-jetpack');
6
+ const path = require('path');
7
+ const { execute } = require('node-powertools');
8
+ const JSON5 = require('json5');
9
+
10
+ // Languages to translate
11
+ const LANGUAGES = [
12
+ 'zh',
13
+ 'es',
14
+ 'hi',
15
+ 'ar',
16
+ 'pt',
17
+ 'ru',
18
+ 'ja',
19
+ 'de',
20
+ 'fr',
21
+ 'ko',
22
+ 'ur',
23
+ 'id',
24
+ 'bn',
25
+ 'tl',
26
+ 'vi',
27
+ 'it',
28
+ ];
29
+
30
+ // Paths
31
+ const localesDir = path.join(process.cwd(), 'src', '_locales');
32
+ const enMessagesPath = path.join(localesDir, 'en', 'messages.json');
33
+
34
+ // Main translate task
35
+ async function translate(complete) {
36
+ // Only run in build mode
37
+ if (!Manager.isBuildMode()) {
38
+ logger.log('Skipping translation (not in build mode)');
39
+ return complete();
40
+ }
41
+
42
+ // Log
43
+ logger.log('Starting translation...');
44
+
45
+ // Check if English messages exist
46
+ if (!jetpack.exists(enMessagesPath)) {
47
+ logger.warn(`English messages not found at ${enMessagesPath}`);
48
+ return complete();
49
+ }
50
+
51
+ // Read English messages
52
+ let enMessages;
53
+ try {
54
+ enMessages = JSON5.parse(jetpack.read(enMessagesPath));
55
+ } catch (e) {
56
+ logger.error(`Failed to parse English messages: ${e.message}`);
57
+ return complete();
58
+ }
59
+
60
+ // Get English keys
61
+ const enKeys = Object.keys(enMessages);
62
+ logger.log(`Found ${enKeys.length} keys in English messages`);
63
+
64
+ // Build translation tasks for all languages in parallel
65
+ const translationTasks = LANGUAGES.map(async (lang) => {
66
+ const langDir = path.join(localesDir, lang);
67
+ const langMessagesPath = path.join(langDir, 'messages.json');
68
+
69
+ // Check if translation exists
70
+ const exists = jetpack.exists(langMessagesPath);
71
+ let needsTranslation = !exists;
72
+ let existingMessages = {};
73
+ let missingKeys = [];
74
+
75
+ // If exists, check for missing keys
76
+ if (exists) {
77
+ try {
78
+ existingMessages = JSON5.parse(jetpack.read(langMessagesPath));
79
+ missingKeys = enKeys.filter(key => !existingMessages[key]);
80
+ needsTranslation = missingKeys.length > 0;
81
+
82
+ if (needsTranslation) {
83
+ logger.log(`[${lang}] Found ${missingKeys.length} missing keys`);
84
+ }
85
+ } catch (e) {
86
+ logger.warn(`[${lang}] Failed to parse existing messages, will retranslate: ${e.message}`);
87
+ needsTranslation = true;
88
+ missingKeys = enKeys;
89
+ }
90
+ } else {
91
+ missingKeys = enKeys;
92
+ }
93
+
94
+ // Skip if no translation needed
95
+ if (!needsTranslation) {
96
+ logger.log(`[${lang}] Up to date, skipping`);
97
+ return;
98
+ }
99
+
100
+ // Build messages to translate
101
+ const messagesToTranslate = {};
102
+ missingKeys.forEach(key => {
103
+ messagesToTranslate[key] = enMessages[key];
104
+ });
105
+
106
+ // Translate using Claude CLI
107
+ try {
108
+ logger.log(`[${lang}] Translating ${missingKeys.length} keys...`);
109
+
110
+ const translated = await translateWithClaude(messagesToTranslate, lang);
111
+
112
+ // Merge with existing messages
113
+ const finalMessages = { ...existingMessages, ...translated };
114
+
115
+ // Ensure directory exists
116
+ jetpack.dir(langDir);
117
+
118
+ // Write translated messages
119
+ jetpack.write(langMessagesPath, JSON.stringify(finalMessages, null, 2));
120
+
121
+ logger.log(`[${lang}] Translation complete`);
122
+ } catch (e) {
123
+ logger.error(`[${lang}] Translation failed: ${e.message}`);
124
+ }
125
+ });
126
+
127
+ // Run all translations in parallel
128
+ await Promise.all(translationTasks);
129
+
130
+ // Log
131
+ logger.log('Translation finished!');
132
+
133
+ // Complete
134
+ return complete();
135
+ }
136
+
137
+ // Translate using Claude CLI
138
+ async function translateWithClaude(messages, targetLang) {
139
+ const prompt = `Translate the following Chrome extension messages.json content from English to ${getLanguageName(targetLang)} (${targetLang}).
140
+
141
+ IMPORTANT RULES:
142
+ 1. Only translate the "message" field values
143
+ 2. Keep the "description" field values in English (they are for developers)
144
+ 3. Keep all JSON keys exactly as they are
145
+ 4. Return ONLY valid JSON, no markdown, no explanation
146
+ 5. Preserve any placeholders like $1, $2, etc.
147
+
148
+ Input JSON:
149
+ ${JSON.stringify(messages, null, 2)}
150
+
151
+ Output the translated JSON:`;
152
+
153
+ try {
154
+ // Run Claude CLI
155
+ const result = await execute(`claude -p "${prompt.replace(/"/g, '\\"')}"`, {
156
+ timeout: 120000,
157
+ });
158
+
159
+ // Parse result - extract JSON from response
160
+ const jsonMatch = result.match(/\{[\s\S]*\}/);
161
+ if (!jsonMatch) {
162
+ throw new Error('No JSON found in Claude response');
163
+ }
164
+
165
+ return JSON.parse(jsonMatch[0]);
166
+ } catch (e) {
167
+ throw new Error(`Claude CLI failed: ${e.message}`);
168
+ }
169
+ }
170
+
171
+ // Get full language name
172
+ function getLanguageName(code) {
173
+ const names = {
174
+ zh: 'Chinese (Simplified)',
175
+ es: 'Spanish',
176
+ hi: 'Hindi',
177
+ ar: 'Arabic',
178
+ pt: 'Portuguese',
179
+ ru: 'Russian',
180
+ ja: 'Japanese',
181
+ de: 'German',
182
+ fr: 'French',
183
+ ko: 'Korean',
184
+ ur: 'Urdu',
185
+ id: 'Indonesian',
186
+ bn: 'Bengali',
187
+ tl: 'Tagalog/Filipino',
188
+ vi: 'Vietnamese',
189
+ it: 'Italian',
190
+ };
191
+
192
+ return names[code] || code;
193
+ }
194
+
195
+ // Export task
196
+ module.exports = series(translate);
@@ -726,3 +726,73 @@
726
726
  [debug] [2025-11-24T23:10:17.226Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
727
727
  [debug] [2025-11-24T23:10:17.226Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
728
728
  [debug] [2025-11-24T23:10:17.226Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
729
+ [debug] [2025-11-25T00:07:11.592Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
730
+ [debug] [2025-11-25T00:07:11.592Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
731
+ [debug] [2025-11-25T00:07:11.594Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
732
+ [debug] [2025-11-25T00:07:11.595Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
733
+ [debug] [2025-11-25T00:07:11.595Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
734
+ [debug] [2025-11-25T00:07:11.606Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
735
+ [debug] [2025-11-25T00:07:11.606Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
736
+ [debug] [2025-11-25T00:07:11.594Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
737
+ [debug] [2025-11-25T00:07:11.594Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
738
+ [debug] [2025-11-25T00:07:11.594Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
739
+ [debug] [2025-11-25T00:07:11.606Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
740
+ [debug] [2025-11-25T00:07:11.606Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
741
+ [debug] [2025-11-25T00:07:11.643Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
742
+ [debug] [2025-11-25T00:07:11.644Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
743
+ [debug] [2025-11-25T00:07:11.644Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
744
+ [debug] [2025-11-25T00:07:11.644Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
745
+ [debug] [2025-11-25T00:07:11.644Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
746
+ [debug] [2025-11-25T00:07:11.646Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
747
+ [debug] [2025-11-25T00:07:11.646Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
748
+ [debug] [2025-11-25T00:07:11.646Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
749
+ [debug] [2025-11-25T00:07:11.646Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
750
+ [debug] [2025-11-25T00:07:11.645Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
751
+ [debug] [2025-11-25T00:07:11.645Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
752
+ [debug] [2025-11-25T00:07:11.646Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
753
+ [debug] [2025-11-25T00:07:11.647Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
754
+ [debug] [2025-11-25T00:07:11.647Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
755
+ [debug] [2025-11-25T00:07:11.648Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
756
+ [debug] [2025-11-25T00:07:11.648Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
757
+ [debug] [2025-11-25T10:39:16.707Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
758
+ [debug] [2025-11-25T10:39:16.729Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
759
+ [debug] [2025-11-25T10:39:16.730Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
760
+ [debug] [2025-11-25T10:39:16.730Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
761
+ [debug] [2025-11-25T10:39:17.257Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
762
+ [debug] [2025-11-25T10:39:17.257Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
763
+ [debug] [2025-11-25T10:39:17.796Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
764
+ [debug] [2025-11-25T10:39:17.796Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
765
+ [debug] [2025-11-25T10:39:17.797Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
766
+ [debug] [2025-11-25T10:39:17.798Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
767
+ [debug] [2025-11-25T10:39:17.804Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
768
+ [debug] [2025-11-25T10:39:17.804Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
769
+ [debug] [2025-11-25T10:39:17.805Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
770
+ [debug] [2025-11-25T10:39:17.805Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
771
+ [debug] [2025-11-25T10:40:42.230Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
772
+ [debug] [2025-11-25T10:40:42.233Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
773
+ [debug] [2025-11-25T10:40:42.233Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
774
+ [debug] [2025-11-25T10:40:42.234Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
775
+ [debug] [2025-11-25T10:40:42.525Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
776
+ [debug] [2025-11-25T10:40:42.526Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
777
+ [debug] [2025-11-25T10:40:42.789Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
778
+ [debug] [2025-11-25T10:40:42.789Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
779
+ [debug] [2025-11-25T10:40:42.790Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
780
+ [debug] [2025-11-25T10:40:42.790Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
781
+ [debug] [2025-11-25T10:40:42.792Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
782
+ [debug] [2025-11-25T10:40:42.792Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
783
+ [debug] [2025-11-25T10:40:42.793Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
784
+ [debug] [2025-11-25T10:40:42.793Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
785
+ [debug] [2025-11-25T10:40:42.999Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
786
+ [debug] [2025-11-25T10:40:43.069Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
787
+ [debug] [2025-11-25T10:40:43.069Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
788
+ [debug] [2025-11-25T10:40:43.069Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
789
+ [debug] [2025-11-25T10:40:43.460Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
790
+ [debug] [2025-11-25T10:40:43.460Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
791
+ [debug] [2025-11-25T10:40:43.601Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
792
+ [debug] [2025-11-25T10:40:43.602Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
793
+ [debug] [2025-11-25T10:40:43.602Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
794
+ [debug] [2025-11-25T10:40:43.603Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
795
+ [debug] [2025-11-25T10:40:43.620Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
796
+ [debug] [2025-11-25T10:40:43.620Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
797
+ [debug] [2025-11-25T10:40:43.621Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
798
+ [debug] [2025-11-25T10:40:43.621Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-extension-manager",
3
- "version": "1.1.10",
3
+ "version": "1.1.11",
4
4
  "description": "Browser Extension Manager dependency manager",
5
5
  "main": "dist/index.js",
6
6
  "exports": {