@gxp-dev/tools 2.0.62 → 2.0.64

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 (182) hide show
  1. package/README.md +32 -31
  2. package/bin/gx-devtools.js +74 -54
  3. package/bin/lib/cli.js +23 -21
  4. package/bin/lib/commands/add-dependency.js +366 -325
  5. package/bin/lib/commands/assets.js +137 -139
  6. package/bin/lib/commands/build.js +169 -174
  7. package/bin/lib/commands/datastore.js +181 -183
  8. package/bin/lib/commands/dev.js +127 -131
  9. package/bin/lib/commands/extensions.js +147 -149
  10. package/bin/lib/commands/extract-config.js +73 -67
  11. package/bin/lib/commands/index.js +12 -12
  12. package/bin/lib/commands/init.js +342 -240
  13. package/bin/lib/commands/publish.js +69 -75
  14. package/bin/lib/commands/socket.js +69 -69
  15. package/bin/lib/commands/ssl.js +14 -14
  16. package/bin/lib/constants.js +10 -24
  17. package/bin/lib/tui/App.tsx +761 -705
  18. package/bin/lib/tui/components/AIPanel.tsx +191 -171
  19. package/bin/lib/tui/components/CommandInput.tsx +394 -343
  20. package/bin/lib/tui/components/GeminiPanel.tsx +175 -151
  21. package/bin/lib/tui/components/Header.tsx +23 -21
  22. package/bin/lib/tui/components/LogPanel.tsx +244 -220
  23. package/bin/lib/tui/components/TabBar.tsx +50 -48
  24. package/bin/lib/tui/components/WelcomeScreen.tsx +126 -71
  25. package/bin/lib/tui/index.tsx +37 -39
  26. package/bin/lib/tui/services/AIService.ts +518 -462
  27. package/bin/lib/tui/services/ExtensionService.ts +140 -129
  28. package/bin/lib/tui/services/GeminiService.ts +367 -337
  29. package/bin/lib/tui/services/ServiceManager.ts +344 -322
  30. package/bin/lib/tui/services/SocketService.ts +168 -168
  31. package/bin/lib/tui/services/ViteService.ts +88 -88
  32. package/bin/lib/tui/services/index.ts +47 -22
  33. package/bin/lib/utils/ai-scaffold.js +291 -280
  34. package/bin/lib/utils/extract-config.js +157 -140
  35. package/bin/lib/utils/files.js +82 -86
  36. package/bin/lib/utils/index.js +7 -7
  37. package/bin/lib/utils/paths.js +34 -34
  38. package/bin/lib/utils/prompts.js +194 -169
  39. package/bin/lib/utils/ssl.js +79 -81
  40. package/browser-extensions/README.md +0 -1
  41. package/browser-extensions/chrome/background.js +244 -237
  42. package/browser-extensions/chrome/content.js +32 -29
  43. package/browser-extensions/chrome/devtools.html +7 -7
  44. package/browser-extensions/chrome/devtools.js +19 -19
  45. package/browser-extensions/chrome/inspector.js +802 -767
  46. package/browser-extensions/chrome/manifest.json +71 -63
  47. package/browser-extensions/chrome/panel.html +674 -636
  48. package/browser-extensions/chrome/panel.js +722 -712
  49. package/browser-extensions/chrome/popup.html +586 -543
  50. package/browser-extensions/chrome/popup.js +282 -244
  51. package/browser-extensions/chrome/rules.json +1 -1
  52. package/browser-extensions/chrome/test-chrome.html +216 -136
  53. package/browser-extensions/chrome/test-mixed-content.html +284 -189
  54. package/browser-extensions/chrome/test-uri-pattern.html +221 -198
  55. package/browser-extensions/firefox/README.md +9 -6
  56. package/browser-extensions/firefox/background.js +221 -218
  57. package/browser-extensions/firefox/content.js +55 -52
  58. package/browser-extensions/firefox/debug-errors.html +386 -228
  59. package/browser-extensions/firefox/debug-https.html +153 -105
  60. package/browser-extensions/firefox/devtools.html +7 -7
  61. package/browser-extensions/firefox/devtools.js +23 -20
  62. package/browser-extensions/firefox/inspector.js +802 -767
  63. package/browser-extensions/firefox/manifest.json +68 -68
  64. package/browser-extensions/firefox/panel.html +674 -636
  65. package/browser-extensions/firefox/panel.js +722 -712
  66. package/browser-extensions/firefox/popup.html +572 -535
  67. package/browser-extensions/firefox/popup.js +281 -236
  68. package/browser-extensions/firefox/test-gramercy.html +170 -125
  69. package/browser-extensions/firefox/test-imports.html +59 -55
  70. package/browser-extensions/firefox/test-masking.html +231 -140
  71. package/browser-extensions/firefox/test-uri-pattern.html +221 -198
  72. package/dist/tui/App.d.ts +1 -1
  73. package/dist/tui/App.d.ts.map +1 -1
  74. package/dist/tui/App.js +154 -150
  75. package/dist/tui/App.js.map +1 -1
  76. package/dist/tui/components/AIPanel.d.ts.map +1 -1
  77. package/dist/tui/components/AIPanel.js +42 -35
  78. package/dist/tui/components/AIPanel.js.map +1 -1
  79. package/dist/tui/components/CommandInput.d.ts +1 -1
  80. package/dist/tui/components/CommandInput.d.ts.map +1 -1
  81. package/dist/tui/components/CommandInput.js +92 -62
  82. package/dist/tui/components/CommandInput.js.map +1 -1
  83. package/dist/tui/components/GeminiPanel.d.ts.map +1 -1
  84. package/dist/tui/components/GeminiPanel.js +37 -30
  85. package/dist/tui/components/GeminiPanel.js.map +1 -1
  86. package/dist/tui/components/Header.d.ts.map +1 -1
  87. package/dist/tui/components/Header.js +1 -1
  88. package/dist/tui/components/Header.js.map +1 -1
  89. package/dist/tui/components/LogPanel.d.ts +1 -1
  90. package/dist/tui/components/LogPanel.d.ts.map +1 -1
  91. package/dist/tui/components/LogPanel.js +26 -24
  92. package/dist/tui/components/LogPanel.js.map +1 -1
  93. package/dist/tui/components/TabBar.d.ts +2 -2
  94. package/dist/tui/components/TabBar.d.ts.map +1 -1
  95. package/dist/tui/components/TabBar.js +11 -11
  96. package/dist/tui/components/TabBar.js.map +1 -1
  97. package/dist/tui/components/WelcomeScreen.d.ts.map +1 -1
  98. package/dist/tui/components/WelcomeScreen.js +6 -6
  99. package/dist/tui/components/WelcomeScreen.js.map +1 -1
  100. package/dist/tui/index.d.ts.map +1 -1
  101. package/dist/tui/index.js +8 -8
  102. package/dist/tui/index.js.map +1 -1
  103. package/dist/tui/services/AIService.d.ts +2 -2
  104. package/dist/tui/services/AIService.d.ts.map +1 -1
  105. package/dist/tui/services/AIService.js +165 -125
  106. package/dist/tui/services/AIService.js.map +1 -1
  107. package/dist/tui/services/ExtensionService.d.ts +1 -1
  108. package/dist/tui/services/ExtensionService.d.ts.map +1 -1
  109. package/dist/tui/services/ExtensionService.js +33 -26
  110. package/dist/tui/services/ExtensionService.js.map +1 -1
  111. package/dist/tui/services/GeminiService.d.ts +1 -1
  112. package/dist/tui/services/GeminiService.d.ts.map +1 -1
  113. package/dist/tui/services/GeminiService.js +87 -76
  114. package/dist/tui/services/GeminiService.js.map +1 -1
  115. package/dist/tui/services/ServiceManager.d.ts +3 -3
  116. package/dist/tui/services/ServiceManager.d.ts.map +1 -1
  117. package/dist/tui/services/ServiceManager.js +72 -58
  118. package/dist/tui/services/ServiceManager.js.map +1 -1
  119. package/dist/tui/services/SocketService.d.ts.map +1 -1
  120. package/dist/tui/services/SocketService.js +32 -32
  121. package/dist/tui/services/SocketService.js.map +1 -1
  122. package/dist/tui/services/ViteService.d.ts.map +1 -1
  123. package/dist/tui/services/ViteService.js +26 -28
  124. package/dist/tui/services/ViteService.js.map +1 -1
  125. package/dist/tui/services/index.d.ts +6 -6
  126. package/dist/tui/services/index.d.ts.map +1 -1
  127. package/dist/tui/services/index.js +6 -6
  128. package/dist/tui/services/index.js.map +1 -1
  129. package/mcp/gxp-api-server.js +83 -81
  130. package/package.json +109 -93
  131. package/runtime/PortalContainer.vue +258 -234
  132. package/runtime/dev-tools/DevToolsModal.vue +153 -155
  133. package/runtime/dev-tools/LayoutSwitcher.vue +144 -140
  134. package/runtime/dev-tools/MockDataEditor.vue +456 -433
  135. package/runtime/dev-tools/SocketSimulator.vue +379 -371
  136. package/runtime/dev-tools/StoreInspector.vue +517 -455
  137. package/runtime/dev-tools/index.js +5 -5
  138. package/runtime/fallback-layouts/PrivateLayout.vue +2 -2
  139. package/runtime/fallback-layouts/PublicLayout.vue +2 -2
  140. package/runtime/fallback-layouts/SystemLayout.vue +2 -2
  141. package/runtime/gxpStringsPlugin.js +159 -134
  142. package/runtime/index.html +17 -19
  143. package/runtime/main.js +24 -22
  144. package/runtime/mock-api/auth-middleware.js +15 -15
  145. package/runtime/mock-api/image-generator.js +46 -46
  146. package/runtime/mock-api/index.js +55 -55
  147. package/runtime/mock-api/response-generator.js +116 -105
  148. package/runtime/mock-api/route-generator.js +107 -84
  149. package/runtime/mock-api/socket-triggers.js +94 -93
  150. package/runtime/mock-api/spec-loader.js +79 -80
  151. package/runtime/package.json +3 -0
  152. package/runtime/server.js +68 -68
  153. package/runtime/stores/gxpPortalConfigStore.js +204 -186
  154. package/runtime/stores/index.js +2 -2
  155. package/runtime/vite-inspector-plugin.js +858 -707
  156. package/runtime/vite-source-tracker-plugin.js +132 -113
  157. package/runtime/vite.config.js +207 -132
  158. package/scripts/launch-chrome.js +41 -41
  159. package/scripts/pack-chrome.js +38 -39
  160. package/socket-events/AiSessionMessageCreated.json +17 -17
  161. package/socket-events/SocialStreamPostCreated.json +23 -23
  162. package/socket-events/SocialStreamPostVariantCompleted.json +22 -22
  163. package/template/.claude/agents/gxp-developer.md +100 -99
  164. package/template/.claude/settings.json +7 -7
  165. package/template/AGENTS.md +30 -23
  166. package/template/GEMINI.md +20 -20
  167. package/template/README.md +70 -53
  168. package/template/app-manifest.json +2 -4
  169. package/template/configuration.json +10 -10
  170. package/template/default-styling.css +1 -1
  171. package/template/index.html +18 -20
  172. package/template/main.js +24 -22
  173. package/template/src/DemoPage.vue +415 -362
  174. package/template/src/Plugin.vue +76 -85
  175. package/template/src/stores/index.js +3 -3
  176. package/template/src/stores/test-data.json +164 -172
  177. package/template/theme-layouts/AdditionalStyling.css +50 -50
  178. package/template/theme-layouts/PrivateLayout.vue +8 -12
  179. package/template/theme-layouts/PublicLayout.vue +8 -12
  180. package/template/theme-layouts/SystemLayout.vue +8 -12
  181. package/template/vite.extend.js +45 -0
  182. package/template/vite.config.js +0 -409
@@ -25,17 +25,17 @@ let config = {
25
25
  maskingMode: false,
26
26
  clearCacheOnEnable: true,
27
27
  disableCacheForRedirects: true,
28
- };
28
+ }
29
29
 
30
- let notificationTimeouts = new Map();
31
- let cacheBlacklist = new Set();
30
+ let notificationTimeouts = new Map()
31
+ let cacheBlacklist = new Set()
32
32
 
33
33
  // Initialize extension
34
- chrome.runtime.onStartup.addListener(initializeExtension);
35
- chrome.runtime.onInstalled.addListener(initializeExtension);
34
+ chrome.runtime.onStartup.addListener(initializeExtension)
35
+ chrome.runtime.onInstalled.addListener(initializeExtension)
36
36
 
37
37
  async function initializeExtension() {
38
- console.log("[JavaScript Proxy] Initializing extension...");
38
+ console.log("[JavaScript Proxy] Initializing extension...")
39
39
  try {
40
40
  // Load saved configuration
41
41
  const defaultConfig = {
@@ -66,22 +66,22 @@ async function initializeExtension() {
66
66
  maskingMode: false,
67
67
  clearCacheOnEnable: true,
68
68
  disableCacheForRedirects: true,
69
- };
69
+ }
70
70
 
71
- const result = await chrome.storage.sync.get(defaultConfig);
72
- config = result;
71
+ const result = await chrome.storage.sync.get(defaultConfig)
72
+ config = result
73
73
 
74
74
  // Migrate legacy configuration to new rules format
75
- config = migrateConfig(config);
75
+ config = migrateConfig(config)
76
76
 
77
- console.log("[JavaScript Proxy] Loaded configuration:", config);
77
+ console.log("[JavaScript Proxy] Loaded configuration:", config)
78
78
 
79
- updateIcon();
80
- updateRequestListener();
79
+ updateIcon()
80
+ updateRequestListener()
81
81
 
82
- console.log("[JavaScript Proxy] Extension initialized successfully");
82
+ console.log("[JavaScript Proxy] Extension initialized successfully")
83
83
  } catch (error) {
84
- console.error("[JavaScript Proxy] Failed to initialize:", error);
84
+ console.error("[JavaScript Proxy] Failed to initialize:", error)
85
85
  }
86
86
  }
87
87
 
@@ -107,7 +107,7 @@ function migrateConfig(config) {
107
107
  returnBlank: false,
108
108
  useCustomPattern: false,
109
109
  },
110
- };
110
+ }
111
111
  } else {
112
112
  // Ensure all required fields exist
113
113
  if (!config.rules.js) {
@@ -119,7 +119,7 @@ function migrateConfig(config) {
119
119
  redirectUrl:
120
120
  config.redirectUrl || "https://localhost:3060/src/Plugin.vue",
121
121
  useCustomPattern: config.useCustomPattern || false,
122
- };
122
+ }
123
123
  }
124
124
  if (!config.rules.css) {
125
125
  config.rules.css = {
@@ -129,16 +129,16 @@ function migrateConfig(config) {
129
129
  redirectUrl: "",
130
130
  returnBlank: true,
131
131
  useCustomPattern: false,
132
- };
132
+ }
133
133
  }
134
134
  }
135
135
 
136
- return config;
136
+ return config
137
137
  }
138
138
 
139
139
  // Update toolbar icon based on state
140
140
  function updateIcon() {
141
- const iconPath = config.enabled ? "icons/gx_on" : "icons/gx_off";
141
+ const iconPath = config.enabled ? "icons/gx_on" : "icons/gx_off"
142
142
  chrome.action.setIcon({
143
143
  path: {
144
144
  16: `${iconPath}_16.png`,
@@ -146,39 +146,39 @@ function updateIcon() {
146
146
  64: `${iconPath}_64.png`,
147
147
  128: `${iconPath}_128.png`,
148
148
  },
149
- });
149
+ })
150
150
 
151
151
  const title = config.enabled
152
152
  ? "JavaScript Proxy (ON)"
153
- : "JavaScript Proxy (OFF)";
154
- chrome.action.setTitle({ title });
153
+ : "JavaScript Proxy (OFF)"
154
+ chrome.action.setTitle({ title })
155
155
  }
156
156
 
157
157
  // Cache management functions
158
158
  async function clearCacheForPattern(urlPattern) {
159
159
  try {
160
- console.log(`[JavaScript Proxy] Clearing cache for pattern: ${urlPattern}`);
160
+ console.log(`[JavaScript Proxy] Clearing cache for pattern: ${urlPattern}`)
161
161
 
162
162
  // Clear browser cache
163
163
  await chrome.browsingData.removeCache({
164
164
  origins: [], // Empty array means all origins
165
165
  since: 0, // Clear all cache entries
166
- });
166
+ })
167
167
 
168
168
  // Clear service worker caches by injecting script into active tabs
169
- await clearServiceWorkerCaches(urlPattern);
169
+ await clearServiceWorkerCaches(urlPattern)
170
170
 
171
- console.log("[JavaScript Proxy] Cache cleared successfully");
171
+ console.log("[JavaScript Proxy] Cache cleared successfully")
172
172
  } catch (error) {
173
- console.error("[JavaScript Proxy] Error clearing cache:", error);
174
- throw error; // Re-throw to let the caller handle the error
173
+ console.error("[JavaScript Proxy] Error clearing cache:", error)
174
+ throw error // Re-throw to let the caller handle the error
175
175
  }
176
176
  }
177
177
 
178
178
  async function clearServiceWorkerCaches(urlPattern) {
179
179
  try {
180
180
  // Get all active tabs
181
- const tabs = await chrome.tabs.query({});
181
+ const tabs = await chrome.tabs.query({})
182
182
 
183
183
  // Inject the script into each tab
184
184
  for (const tab of tabs) {
@@ -193,20 +193,20 @@ async function clearServiceWorkerCaches(urlPattern) {
193
193
  func: async function (pattern) {
194
194
  try {
195
195
  if ("caches" in window) {
196
- const cacheNames = await caches.keys();
197
- const regex = new RegExp(pattern, "i");
196
+ const cacheNames = await caches.keys()
197
+ const regex = new RegExp(pattern, "i")
198
198
 
199
199
  for (const cacheName of cacheNames) {
200
- const cache = await caches.open(cacheName);
201
- const requests = await cache.keys();
200
+ const cache = await caches.open(cacheName)
201
+ const requests = await cache.keys()
202
202
 
203
203
  for (const request of requests) {
204
204
  if (regex.test(request.url)) {
205
- await cache.delete(request);
205
+ await cache.delete(request)
206
206
  console.log(
207
207
  "[JavaScript Proxy] Deleted from cache:",
208
- request.url
209
- );
208
+ request.url,
209
+ )
210
210
  }
211
211
  }
212
212
  }
@@ -219,77 +219,77 @@ async function clearServiceWorkerCaches(urlPattern) {
219
219
  navigator.serviceWorker.controller.postMessage({
220
220
  type: "CLEAR_CACHE_FOR_PATTERN",
221
221
  pattern: pattern,
222
- });
222
+ })
223
223
  }
224
224
  }
225
225
  } catch (error) {
226
226
  console.error(
227
227
  "[JavaScript Proxy] Error clearing service worker cache:",
228
- error
229
- );
228
+ error,
229
+ )
230
230
  }
231
231
  },
232
232
  args: [urlPattern.replace(/\\/g, "\\\\")],
233
- });
233
+ })
234
234
  }
235
235
  } catch (error) {
236
236
  // Tab might not allow script injection, continue with others
237
237
  console.debug(
238
238
  `[JavaScript Proxy] Could not inject cache clear script into tab ${tab.id}:`,
239
- error
240
- );
239
+ error,
240
+ )
241
241
  }
242
242
  }
243
243
 
244
- console.log("[JavaScript Proxy] Service worker cache clearing attempted");
244
+ console.log("[JavaScript Proxy] Service worker cache clearing attempted")
245
245
  } catch (error) {
246
246
  console.error(
247
247
  "[JavaScript Proxy] Error clearing service worker caches:",
248
- error
249
- );
248
+ error,
249
+ )
250
250
  }
251
251
  }
252
252
 
253
253
  async function addToCacheBlacklist(url) {
254
254
  try {
255
- const urlObj = new URL(url);
256
- const origin = urlObj.origin;
257
- cacheBlacklist.add(origin);
258
- console.log(`[JavaScript Proxy] Added ${origin} to cache blacklist`);
255
+ const urlObj = new URL(url)
256
+ const origin = urlObj.origin
257
+ cacheBlacklist.add(origin)
258
+ console.log(`[JavaScript Proxy] Added ${origin} to cache blacklist`)
259
259
  } catch (error) {
260
- console.error("[JavaScript Proxy] Error adding to cache blacklist:", error);
260
+ console.error("[JavaScript Proxy] Error adding to cache blacklist:", error)
261
261
  }
262
262
  }
263
263
 
264
264
  function shouldDisableCache(url) {
265
- if (!config.disableCacheForRedirects) return false;
265
+ if (!config.disableCacheForRedirects) return false
266
266
 
267
267
  try {
268
268
  // Check against all enabled rules
269
269
  for (const [ruleType, rule] of Object.entries(config.rules || {})) {
270
270
  if (rule.enabled) {
271
271
  const pattern =
272
- rule.useCustomPattern && rule.pattern ? rule.pattern : rule.pattern;
273
- const regex = new RegExp(pattern, "i");
272
+ rule.useCustomPattern && rule.pattern ? rule.pattern : rule.pattern
273
+ const regex = new RegExp(pattern, "i")
274
274
  if (regex.test(url)) {
275
- return true;
275
+ return true
276
276
  }
277
277
  }
278
278
  }
279
279
 
280
280
  // Fallback to legacy pattern for backward compatibility
281
281
  if (config.urlPattern) {
282
- const regex = new RegExp(config.urlPattern, "i");
283
- return regex.test(url);
282
+ const regex = new RegExp(config.urlPattern, "i")
283
+ return regex.test(url)
284
284
  }
285
285
 
286
- return false;
286
+ return false
287
287
  } catch (error) {
288
288
  console.error(
289
289
  "[JavaScript Proxy] Error checking cache disable pattern:",
290
- error
291
- );
292
- return false;
290
+ error,
291
+ )
292
+ return false
293
293
  }
294
294
  }
295
295
 
@@ -299,27 +299,27 @@ async function updateRequestListener() {
299
299
  try {
300
300
  await chrome.declarativeNetRequest.updateDynamicRules({
301
301
  removeRuleIds: [1, 2, 3, 4, 5], // Remove up to 5 rules
302
- });
302
+ })
303
303
  } catch (error) {
304
304
  // Rules might not exist, that's fine
305
305
  }
306
306
 
307
307
  if (config.enabled && !config.maskingMode) {
308
- const rulesToAdd = [];
309
- let ruleId = 1;
308
+ const rulesToAdd = []
309
+ let ruleId = 1
310
310
 
311
311
  // Process each rule type
312
312
  for (const [ruleType, rule] of Object.entries(config.rules || {})) {
313
313
  if (rule.enabled && rule.pattern) {
314
314
  if (rule.returnBlank) {
315
315
  // For blank returns, we'll handle in webRequest (can't return blank with declarativeNetRequest)
316
- continue;
316
+ continue
317
317
  }
318
318
 
319
319
  if (rule.redirectUrl) {
320
320
  // Clear cache if enabled
321
321
  if (config.clearCacheOnEnable) {
322
- await clearCacheForPattern(rule.pattern);
322
+ await clearCacheForPattern(rule.pattern)
323
323
  }
324
324
 
325
325
  // Add redirect rule using declarativeNetRequest
@@ -336,9 +336,9 @@ async function updateRequestListener() {
336
336
  regexFilter: rule.pattern,
337
337
  resourceTypes: ruleType === "js" ? ["script"] : ["stylesheet"],
338
338
  },
339
- };
339
+ }
340
340
 
341
- rulesToAdd.push(redirectRule);
341
+ rulesToAdd.push(redirectRule)
342
342
  }
343
343
  }
344
344
  }
@@ -346,7 +346,7 @@ async function updateRequestListener() {
346
346
  // Add legacy rule for backward compatibility
347
347
  if (config.urlPattern && config.redirectUrl && rulesToAdd.length === 0) {
348
348
  if (config.clearCacheOnEnable) {
349
- await clearCacheForPattern(config.urlPattern);
349
+ await clearCacheForPattern(config.urlPattern)
350
350
  }
351
351
 
352
352
  const legacyRule = {
@@ -362,30 +362,30 @@ async function updateRequestListener() {
362
362
  regexFilter: config.urlPattern,
363
363
  resourceTypes: ["script"],
364
364
  },
365
- };
365
+ }
366
366
 
367
- rulesToAdd.push(legacyRule);
367
+ rulesToAdd.push(legacyRule)
368
368
  }
369
369
 
370
370
  if (rulesToAdd.length > 0) {
371
371
  try {
372
372
  await chrome.declarativeNetRequest.updateDynamicRules({
373
373
  addRules: rulesToAdd,
374
- });
375
- console.log("[JavaScript Proxy] Added redirect rules:", rulesToAdd);
374
+ })
375
+ console.log("[JavaScript Proxy] Added redirect rules:", rulesToAdd)
376
376
  } catch (error) {
377
- console.error("[JavaScript Proxy] Error adding redirect rules:", error);
377
+ console.error("[JavaScript Proxy] Error adding redirect rules:", error)
378
378
  }
379
379
  }
380
380
  }
381
381
 
382
382
  // For masking mode or blank returns, we need webRequest API
383
- updateWebRequestListener();
383
+ updateWebRequestListener()
384
384
  }
385
385
 
386
386
  // Handle web requests for masking mode and blank returns (fallback to webRequest for complex logic)
387
387
  function handleRequest(details) {
388
- if (!config.enabled) return {};
388
+ if (!config.enabled) return {}
389
389
 
390
390
  // Skip data URLs and blob URLs
391
391
  if (
@@ -394,61 +394,61 @@ function handleRequest(details) {
394
394
  details.url.startsWith("chrome:") ||
395
395
  details.url.startsWith("chrome-extension:")
396
396
  ) {
397
- return {};
397
+ return {}
398
398
  }
399
399
 
400
400
  try {
401
401
  // Check each rule type
402
402
  for (const [ruleType, rule] of Object.entries(config.rules || {})) {
403
- if (!rule.enabled || !rule.pattern) continue;
403
+ if (!rule.enabled || !rule.pattern) continue
404
404
 
405
405
  // Check if this rule type matches the resource type
406
- if (ruleType === "js" && details.type !== "script") continue;
407
- if (ruleType === "css" && details.type !== "stylesheet") continue;
406
+ if (ruleType === "js" && details.type !== "script") continue
407
+ if (ruleType === "css" && details.type !== "stylesheet") continue
408
408
 
409
- const regex = new RegExp(rule.pattern, "i");
409
+ const regex = new RegExp(rule.pattern, "i")
410
410
 
411
411
  // Test the full URL against the pattern
412
412
  if (regex.test(details.url)) {
413
413
  // Handle blank return for CSS
414
414
  if (rule.returnBlank) {
415
415
  console.log(
416
- `[JavaScript Proxy] Returning blank for ${ruleType}: ${details.url}`
417
- );
416
+ `[JavaScript Proxy] Returning blank for ${ruleType}: ${details.url}`,
417
+ )
418
418
  // Return a data URL with empty content
419
419
  const blankUrl =
420
420
  ruleType === "css"
421
421
  ? "data:text/css;charset=utf-8,"
422
- : "data:text/javascript;charset=utf-8,";
423
- return { redirectUrl: blankUrl };
422
+ : "data:text/javascript;charset=utf-8,"
423
+ return { redirectUrl: blankUrl }
424
424
  }
425
425
 
426
426
  // Handle masking mode or rules without declarativeNetRequest redirect
427
427
  if (config.maskingMode || !rule.redirectUrl) {
428
428
  if (rule.redirectUrl) {
429
- let newUrl = rule.redirectUrl;
429
+ let newUrl = rule.redirectUrl
430
430
 
431
431
  // Ensure URL has protocol
432
432
  if (!newUrl.includes("://")) {
433
- newUrl = "https://" + newUrl;
433
+ newUrl = "https://" + newUrl
434
434
  }
435
435
 
436
436
  // Check if this would create a redirect loop
437
437
  if (details.url === newUrl || details.url.includes("localhost")) {
438
438
  console.log(
439
- `[JavaScript Proxy] Skipping redirect loop: ${details.url}`
440
- );
441
- return {};
439
+ `[JavaScript Proxy] Skipping redirect loop: ${details.url}`,
440
+ )
441
+ return {}
442
442
  }
443
443
 
444
444
  // Store original URL for header modification
445
- storeOriginalUrl(details.requestId, details.url, newUrl);
445
+ storeOriginalUrl(details.requestId, details.url, newUrl)
446
446
 
447
447
  console.log(
448
- `[JavaScript Proxy] Masking ${ruleType}: ${details.url} (routing to ${newUrl})`
449
- );
448
+ `[JavaScript Proxy] Masking ${ruleType}: ${details.url} (routing to ${newUrl})`,
449
+ )
450
450
 
451
- return { redirectUrl: newUrl };
451
+ return { redirectUrl: newUrl }
452
452
  }
453
453
  }
454
454
  }
@@ -456,52 +456,52 @@ function handleRequest(details) {
456
456
 
457
457
  // Fallback to legacy pattern for backward compatibility
458
458
  if (config.maskingMode && config.urlPattern) {
459
- const regex = new RegExp(config.urlPattern, "i");
459
+ const regex = new RegExp(config.urlPattern, "i")
460
460
 
461
461
  if (regex.test(details.url) && details.type === "script") {
462
- let newUrl = config.redirectUrl;
462
+ let newUrl = config.redirectUrl
463
463
 
464
464
  if (!newUrl.includes("://")) {
465
- newUrl = "https://" + newUrl;
465
+ newUrl = "https://" + newUrl
466
466
  }
467
467
 
468
468
  if (details.url === newUrl || details.url.includes("localhost")) {
469
469
  console.log(
470
- `[JavaScript Proxy] Skipping redirect loop: ${details.url}`
471
- );
472
- return {};
470
+ `[JavaScript Proxy] Skipping redirect loop: ${details.url}`,
471
+ )
472
+ return {}
473
473
  }
474
474
 
475
- storeOriginalUrl(details.requestId, details.url, newUrl);
475
+ storeOriginalUrl(details.requestId, details.url, newUrl)
476
476
 
477
477
  console.log(
478
- `[JavaScript Proxy] Legacy masking: ${details.url} (routing to ${newUrl})`
479
- );
478
+ `[JavaScript Proxy] Legacy masking: ${details.url} (routing to ${newUrl})`,
479
+ )
480
480
 
481
- return { redirectUrl: newUrl };
481
+ return { redirectUrl: newUrl }
482
482
  }
483
483
  }
484
484
  } catch (error) {
485
- console.error("[JavaScript Proxy] Error processing request:", error);
485
+ console.error("[JavaScript Proxy] Error processing request:", error)
486
486
  }
487
487
 
488
- return {};
488
+ return {}
489
489
  }
490
490
 
491
491
  // Store mapping of request IDs to proxy info for header modification
492
- const pendingProxyRequests = new Map();
492
+ const pendingProxyRequests = new Map()
493
493
 
494
494
  function storeOriginalUrl(requestId, originalUrl, redirectUrl) {
495
495
  pendingProxyRequests.set(requestId, {
496
496
  originalUrl,
497
497
  redirectUrl,
498
498
  timestamp: Date.now(),
499
- });
499
+ })
500
500
 
501
501
  // Clean up old entries after 30 seconds
502
502
  setTimeout(() => {
503
- pendingProxyRequests.delete(requestId);
504
- }, 30000);
503
+ pendingProxyRequests.delete(requestId)
504
+ }, 30000)
505
505
  }
506
506
 
507
507
  // Update webRequest listener for masking mode
@@ -511,19 +511,19 @@ function updateWebRequestListener() {
511
511
  chrome.webRequest &&
512
512
  chrome.webRequest.onBeforeRequest.hasListener(handleRequest)
513
513
  ) {
514
- chrome.webRequest.onBeforeRequest.removeListener(handleRequest);
514
+ chrome.webRequest.onBeforeRequest.removeListener(handleRequest)
515
515
  }
516
516
  if (
517
517
  chrome.webRequest &&
518
518
  chrome.webRequest.onBeforeSendHeaders.hasListener(handleRequestHeaders)
519
519
  ) {
520
- chrome.webRequest.onBeforeSendHeaders.removeListener(handleRequestHeaders);
520
+ chrome.webRequest.onBeforeSendHeaders.removeListener(handleRequestHeaders)
521
521
  }
522
522
  if (
523
523
  chrome.webRequest &&
524
524
  chrome.webRequest.onHeadersReceived.hasListener(handleResponseHeaders)
525
525
  ) {
526
- chrome.webRequest.onHeadersReceived.removeListener(handleResponseHeaders);
526
+ chrome.webRequest.onHeadersReceived.removeListener(handleResponseHeaders)
527
527
  }
528
528
 
529
529
  // Check if we need webRequest for any features
@@ -531,60 +531,60 @@ function updateWebRequestListener() {
531
531
  config.maskingMode ||
532
532
  config.disableCacheForRedirects ||
533
533
  Object.values(config.rules || {}).some(
534
- (rule) => rule.enabled && rule.returnBlank
535
- );
534
+ (rule) => rule.enabled && rule.returnBlank,
535
+ )
536
536
 
537
537
  // Add webRequest listeners for masking mode, cache control, or blank returns
538
538
  if (config.enabled && chrome.webRequest && needsWebRequest) {
539
539
  chrome.webRequest.onBeforeRequest.addListener(
540
540
  handleRequest,
541
541
  { urls: ["<all_urls>"] },
542
- ["blocking"]
543
- );
542
+ ["blocking"],
543
+ )
544
544
 
545
545
  chrome.webRequest.onBeforeSendHeaders.addListener(
546
546
  handleRequestHeaders,
547
547
  { urls: ["<all_urls>"] },
548
- ["blocking", "requestHeaders"]
549
- );
548
+ ["blocking", "requestHeaders"],
549
+ )
550
550
 
551
551
  chrome.webRequest.onHeadersReceived.addListener(
552
552
  handleResponseHeaders,
553
553
  { urls: ["<all_urls>"] },
554
- ["blocking", "responseHeaders"]
555
- );
554
+ ["blocking", "responseHeaders"],
555
+ )
556
556
 
557
557
  console.log(
558
- "[JavaScript Proxy] WebRequest listeners enabled for masking mode"
559
- );
558
+ "[JavaScript Proxy] WebRequest listeners enabled for masking mode",
559
+ )
560
560
  } else {
561
- console.log("[JavaScript Proxy] WebRequest listeners disabled");
561
+ console.log("[JavaScript Proxy] WebRequest listeners disabled")
562
562
  }
563
563
  }
564
564
 
565
565
  // Handle request headers for masking mode and cache control
566
566
  function handleRequestHeaders(details) {
567
- if (!config.enabled) return {};
567
+ if (!config.enabled) return {}
568
568
 
569
569
  // Initialize modifications
570
- const modifications = { requestHeaders: details.requestHeaders };
571
- let hasModifications = false;
570
+ const modifications = { requestHeaders: details.requestHeaders }
571
+ let hasModifications = false
572
572
 
573
573
  // Handle masking mode
574
574
  if (config.maskingMode) {
575
- const proxyInfo = pendingProxyRequests.get(details.requestId);
575
+ const proxyInfo = pendingProxyRequests.get(details.requestId)
576
576
  if (proxyInfo) {
577
577
  // Add/modify headers to properly route to localhost
578
578
  const hostHeader = modifications.requestHeaders.find(
579
- (h) => h.name.toLowerCase() === "host"
580
- );
579
+ (h) => h.name.toLowerCase() === "host",
580
+ )
581
581
  if (hostHeader) {
582
582
  try {
583
- const proxyUrl = new URL(proxyInfo.redirectUrl);
584
- hostHeader.value = proxyUrl.host;
585
- hasModifications = true;
583
+ const proxyUrl = new URL(proxyInfo.redirectUrl)
584
+ hostHeader.value = proxyUrl.host
585
+ hasModifications = true
586
586
  } catch (error) {
587
- console.error("[JavaScript Proxy] Error parsing proxy URL:", error);
587
+ console.error("[JavaScript Proxy] Error parsing proxy URL:", error)
588
588
  }
589
589
  }
590
590
  }
@@ -602,39 +602,39 @@ function handleRequestHeaders(details) {
602
602
  { name: "Expires", value: "0" },
603
603
  { name: "If-None-Match", value: "*" },
604
604
  { name: "If-Modified-Since", value: "Thu, 01 Jan 1970 00:00:00 GMT" },
605
- ];
605
+ ]
606
606
 
607
607
  cacheHeaders.forEach((cacheHeader) => {
608
608
  const existingHeader = modifications.requestHeaders.find(
609
- (h) => h.name.toLowerCase() === cacheHeader.name.toLowerCase()
610
- );
609
+ (h) => h.name.toLowerCase() === cacheHeader.name.toLowerCase(),
610
+ )
611
611
  if (existingHeader) {
612
- existingHeader.value = cacheHeader.value;
612
+ existingHeader.value = cacheHeader.value
613
613
  } else {
614
- modifications.requestHeaders.push(cacheHeader);
614
+ modifications.requestHeaders.push(cacheHeader)
615
615
  }
616
- hasModifications = true;
617
- });
616
+ hasModifications = true
617
+ })
618
618
 
619
619
  console.log(
620
- `[JavaScript Proxy] Added cache-busting headers for: ${details.url}`
621
- );
620
+ `[JavaScript Proxy] Added cache-busting headers for: ${details.url}`,
621
+ )
622
622
  }
623
623
 
624
- return hasModifications ? modifications : {};
624
+ return hasModifications ? modifications : {}
625
625
  }
626
626
 
627
627
  // Handle response headers for masking mode and cache control
628
628
  function handleResponseHeaders(details) {
629
- if (!config.enabled) return {};
629
+ if (!config.enabled) return {}
630
630
 
631
631
  // Initialize modifications
632
- const modifications = { responseHeaders: details.responseHeaders };
633
- let hasModifications = false;
632
+ const modifications = { responseHeaders: details.responseHeaders }
633
+ let hasModifications = false
634
634
 
635
635
  // Handle masking mode
636
636
  if (config.maskingMode) {
637
- const proxyInfo = pendingProxyRequests.get(details.requestId);
637
+ const proxyInfo = pendingProxyRequests.get(details.requestId)
638
638
  if (proxyInfo) {
639
639
  // Add CORS headers if needed
640
640
  const corsHeaders = [
@@ -647,19 +647,19 @@ function handleResponseHeaders(details) {
647
647
  name: "Access-Control-Allow-Headers",
648
648
  value: "Content-Type, Authorization",
649
649
  },
650
- ];
650
+ ]
651
651
 
652
652
  corsHeaders.forEach((corsHeader) => {
653
653
  const existingHeader = modifications.responseHeaders.find(
654
- (h) => h.name.toLowerCase() === corsHeader.name.toLowerCase()
655
- );
654
+ (h) => h.name.toLowerCase() === corsHeader.name.toLowerCase(),
655
+ )
656
656
  if (existingHeader) {
657
- existingHeader.value = corsHeader.value;
657
+ existingHeader.value = corsHeader.value
658
658
  } else {
659
- modifications.responseHeaders.push(corsHeader);
659
+ modifications.responseHeaders.push(corsHeader)
660
660
  }
661
- hasModifications = true;
662
- });
661
+ hasModifications = true
662
+ })
663
663
  }
664
664
  }
665
665
 
@@ -677,197 +677,204 @@ function handleResponseHeaders(details) {
677
677
  { name: "ETag", value: `"${Date.now()}-${Math.random()}"` },
678
678
  { name: "Vary", value: "*" },
679
679
  { name: "X-Cache-Control", value: "no-cache" },
680
- ];
680
+ ]
681
681
 
682
682
  cacheHeaders.forEach((cacheHeader) => {
683
683
  const existingHeader = modifications.responseHeaders.find(
684
- (h) => h.name.toLowerCase() === cacheHeader.name.toLowerCase()
685
- );
684
+ (h) => h.name.toLowerCase() === cacheHeader.name.toLowerCase(),
685
+ )
686
686
  if (existingHeader) {
687
- existingHeader.value = cacheHeader.value;
687
+ existingHeader.value = cacheHeader.value
688
688
  } else {
689
- modifications.responseHeaders.push(cacheHeader);
689
+ modifications.responseHeaders.push(cacheHeader)
690
690
  }
691
- hasModifications = true;
692
- });
691
+ hasModifications = true
692
+ })
693
693
 
694
694
  console.log(
695
- `[JavaScript Proxy] Added response cache-busting headers for: ${details.url}`
696
- );
695
+ `[JavaScript Proxy] Added response cache-busting headers for: ${details.url}`,
696
+ )
697
697
  }
698
698
 
699
699
  if (hasModifications) {
700
700
  console.log(
701
- `[JavaScript Proxy] Modified response headers for: ${details.url}`
702
- );
701
+ `[JavaScript Proxy] Modified response headers for: ${details.url}`,
702
+ )
703
703
  }
704
704
 
705
- return hasModifications ? modifications : {};
705
+ return hasModifications ? modifications : {}
706
706
  }
707
707
 
708
708
  // Show desktop notification for proxy activity (when using masking mode)
709
709
  function showProxyNotification(from, to, requestType = "") {
710
- const shortFrom = from.length > 50 ? from.substring(0, 47) + "..." : from;
711
- const shortTo = to.length > 30 ? to.substring(0, 27) + "..." : to;
710
+ const shortFrom = from.length > 50 ? from.substring(0, 47) + "..." : from
711
+ const shortTo = to.length > 30 ? to.substring(0, 27) + "..." : to
712
712
 
713
- const notificationId = `proxy-${Date.now()}`;
713
+ const notificationId = `proxy-${Date.now()}`
714
714
 
715
715
  chrome.notifications.create(notificationId, {
716
716
  type: "basic",
717
717
  iconUrl: "icons/gx_on_64.png",
718
718
  title: "JavaScript Proxy Active",
719
719
  message: `${requestType}\n${shortFrom}\n→ ${shortTo}`,
720
- });
720
+ })
721
721
 
722
722
  // Clear existing timeout for this type
723
723
  if (notificationTimeouts.has("proxy")) {
724
- clearTimeout(notificationTimeouts.get("proxy"));
724
+ clearTimeout(notificationTimeouts.get("proxy"))
725
725
  }
726
726
 
727
727
  // Auto-dismiss after 3 seconds
728
728
  const timeoutId = setTimeout(() => {
729
- chrome.notifications.clear(notificationId);
730
- notificationTimeouts.delete("proxy");
731
- }, 3000);
729
+ chrome.notifications.clear(notificationId)
730
+ notificationTimeouts.delete("proxy")
731
+ }, 3000)
732
732
 
733
- notificationTimeouts.set("proxy", timeoutId);
733
+ notificationTimeouts.set("proxy", timeoutId)
734
734
  }
735
735
 
736
736
  // ============================================================
737
737
  // DevTools Panel Communication
738
738
  // ============================================================
739
739
 
740
- const devtoolsConnections = new Map();
740
+ const devtoolsConnections = new Map()
741
741
 
742
742
  chrome.runtime.onConnect.addListener((port) => {
743
- if (port.name === 'gxp-devtools-panel') {
743
+ if (port.name === "gxp-devtools-panel") {
744
744
  const extensionListener = (message, port) => {
745
- if (message.name === 'init') {
746
- devtoolsConnections.set(message.tabId, port);
747
- console.log('[GxP DevTools] Panel connected for tab:', message.tabId);
745
+ if (message.name === "init") {
746
+ devtoolsConnections.set(message.tabId, port)
747
+ console.log("[GxP DevTools] Panel connected for tab:", message.tabId)
748
748
  }
749
749
 
750
750
  // Forward messages to content script
751
751
  if (message.tabId && message.action) {
752
752
  chrome.tabs.sendMessage(message.tabId, message, (response) => {
753
- port.postMessage(response);
754
- });
753
+ port.postMessage(response)
754
+ })
755
755
  }
756
- };
756
+ }
757
757
 
758
- port.onMessage.addListener(extensionListener);
758
+ port.onMessage.addListener(extensionListener)
759
759
 
760
760
  port.onDisconnect.addListener(() => {
761
761
  // Remove the connection when panel is closed
762
762
  for (const [tabId, connectedPort] of devtoolsConnections.entries()) {
763
763
  if (connectedPort === port) {
764
- devtoolsConnections.delete(tabId);
765
- console.log('[GxP DevTools] Panel disconnected for tab:', tabId);
766
- break;
764
+ devtoolsConnections.delete(tabId)
765
+ console.log("[GxP DevTools] Panel disconnected for tab:", tabId)
766
+ break
767
767
  }
768
768
  }
769
- });
769
+ })
770
770
  }
771
- });
771
+ })
772
772
 
773
773
  // Forward messages from content script to DevTools panel
774
774
  function forwardToDevTools(tabId, message) {
775
- const port = devtoolsConnections.get(tabId);
775
+ const port = devtoolsConnections.get(tabId)
776
776
  if (port) {
777
777
  try {
778
- port.postMessage(message);
778
+ port.postMessage(message)
779
779
  } catch (error) {
780
- console.error('[GxP DevTools] Error forwarding to panel:', error);
780
+ console.error("[GxP DevTools] Error forwarding to panel:", error)
781
781
  }
782
782
  }
783
783
  }
784
784
 
785
785
  // Handle messages from popup
786
786
  chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
787
- console.log("[JavaScript Proxy] Received message:", request);
787
+ console.log("[JavaScript Proxy] Received message:", request)
788
788
 
789
789
  // Handle messages from content script about element selection
790
- if (request.type === 'elementSelected' && sender.tab) {
791
- forwardToDevTools(sender.tab.id, request);
792
- return;
790
+ if (request.type === "elementSelected" && sender.tab) {
791
+ forwardToDevTools(sender.tab.id, request)
792
+ return
793
793
  }
794
794
 
795
795
  switch (request.action) {
796
796
  case "toggleProxy":
797
- config.enabled = request.enabled;
798
- chrome.storage.sync.set({ enabled: config.enabled });
799
- updateIcon();
800
- updateRequestListener();
797
+ config.enabled = request.enabled
798
+ chrome.storage.sync.set({ enabled: config.enabled })
799
+ updateIcon()
800
+ updateRequestListener()
801
801
  // Clear cache when enabling the proxy
802
802
  if (config.enabled && config.clearCacheOnEnable) {
803
- clearCacheForPattern(config.urlPattern);
803
+ clearCacheForPattern(config.urlPattern)
804
804
  }
805
- sendResponse({ success: true, enabled: config.enabled });
806
- return false; // Synchronous response
805
+ sendResponse({ success: true, enabled: config.enabled })
806
+ return false // Synchronous response
807
807
 
808
808
  case "updateConfig":
809
- config = { ...config, ...request.config };
810
- chrome.storage.sync.set(config);
811
- updateIcon();
812
- updateRequestListener();
813
- sendResponse({ success: true });
814
- return false; // Synchronous response
809
+ config = { ...config, ...request.config }
810
+ chrome.storage.sync.set(config)
811
+ updateIcon()
812
+ updateRequestListener()
813
+ sendResponse({ success: true })
814
+ return false // Synchronous response
815
815
 
816
816
  case "getConfig":
817
- sendResponse(config);
818
- return false; // Synchronous response
817
+ sendResponse(config)
818
+ return false // Synchronous response
819
819
 
820
820
  case "clearCache":
821
821
  console.log(
822
822
  "[JavaScript Proxy] Starting cache clear for pattern:",
823
- config.urlPattern
824
- );
823
+ config.urlPattern,
824
+ )
825
825
  clearCacheForPattern(config.urlPattern)
826
826
  .then(() => {
827
- console.log("[JavaScript Proxy] Cache clear completed successfully");
828
- sendResponse({ success: true });
827
+ console.log("[JavaScript Proxy] Cache clear completed successfully")
828
+ sendResponse({ success: true })
829
829
  })
830
830
  .catch((error) => {
831
- console.error("[JavaScript Proxy] Cache clear error:", error);
831
+ console.error("[JavaScript Proxy] Cache clear error:", error)
832
832
  sendResponse({
833
833
  success: false,
834
834
  error: error.message || error.toString(),
835
- });
836
- });
837
- return true; // Keep message channel open for async response
835
+ })
836
+ })
837
+ return true // Keep message channel open for async response
838
838
 
839
839
  case "openDevTools":
840
840
  // Open DevTools for the specified tab
841
841
  // Note: Chrome doesn't have a direct API to open DevTools to a specific panel
842
842
  // We inject a script that triggers the inspector and prompt user to open DevTools
843
843
  if (request.tabId) {
844
- chrome.scripting.executeScript({
845
- target: { tabId: request.tabId },
846
- func: () => {
847
- // Log a message suggesting to open DevTools
848
- console.log('%c[GxP Inspector] Inspector enabled! Press F12 or Ctrl+Shift+J to open DevTools and see the GxP Inspector panel.', 'color: #667eea; font-weight: bold; font-size: 14px;');
849
- }
850
- }).catch(err => console.log('[GxP DevTools] Could not inject script:', err));
844
+ chrome.scripting
845
+ .executeScript({
846
+ target: { tabId: request.tabId },
847
+ func: () => {
848
+ // Log a message suggesting to open DevTools
849
+ console.log(
850
+ "%c[GxP Inspector] Inspector enabled! Press F12 or Ctrl+Shift+J to open DevTools and see the GxP Inspector panel.",
851
+ "color: #667eea; font-weight: bold; font-size: 14px;",
852
+ )
853
+ },
854
+ })
855
+ .catch((err) =>
856
+ console.log("[GxP DevTools] Could not inject script:", err),
857
+ )
851
858
  }
852
- sendResponse({ success: true });
853
- return false;
859
+ sendResponse({ success: true })
860
+ return false
854
861
 
855
862
  default:
856
- console.warn("[JavaScript Proxy] Unknown action:", request.action);
857
- sendResponse({ success: false, error: "Unknown action" });
858
- return false; // Synchronous response
863
+ console.warn("[JavaScript Proxy] Unknown action:", request.action)
864
+ sendResponse({ success: false, error: "Unknown action" })
865
+ return false // Synchronous response
859
866
  }
860
- });
867
+ })
861
868
 
862
869
  // Clear expired proxy requests periodically
863
870
  setInterval(() => {
864
- const now = Date.now();
871
+ const now = Date.now()
865
872
  for (const [requestId, info] of pendingProxyRequests.entries()) {
866
873
  if (now - info.timestamp > 30000) {
867
- pendingProxyRequests.delete(requestId);
874
+ pendingProxyRequests.delete(requestId)
868
875
  }
869
876
  }
870
- }, 10000);
877
+ }, 10000)
871
878
 
872
879
  // Initialize on startup
873
- initializeExtension();
880
+ initializeExtension()