extension-develop 3.16.0 → 3.16.1-canary.309.312cc73

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 (25) hide show
  1. package/dist/0~rspack-config.mjs +244 -39
  2. package/dist/946.mjs +62 -5
  3. package/dist/extension-js-devtools/chrome/background/service_worker.js +1 -1
  4. package/dist/extension-js-devtools/chrome/content_scripts/content-0.js +2 -2
  5. package/dist/extension-js-devtools/chrome/pages/centralized-logger.css +1 -1
  6. package/dist/extension-js-devtools/chrome/pages/welcome.css +1 -1
  7. package/dist/extension-js-devtools/chrome/scripts/logger-client.js +1 -1
  8. package/dist/extension-js-devtools/chromium/background/service_worker.js +1 -1
  9. package/dist/extension-js-devtools/chromium/content_scripts/content-0.js +2 -2
  10. package/dist/extension-js-devtools/chromium/pages/centralized-logger.css +1 -1
  11. package/dist/extension-js-devtools/chromium/pages/welcome.css +1 -1
  12. package/dist/extension-js-devtools/chromium/scripts/logger-client.js +1 -1
  13. package/dist/extension-js-devtools/edge/background/service_worker.js +1 -1
  14. package/dist/extension-js-devtools/edge/content_scripts/content-0.js +2 -2
  15. package/dist/extension-js-devtools/edge/pages/centralized-logger.css +1 -1
  16. package/dist/extension-js-devtools/edge/pages/welcome.css +1 -1
  17. package/dist/extension-js-devtools/edge/scripts/logger-client.js +1 -1
  18. package/dist/extension-js-devtools/firefox/background/scripts.js +1 -1
  19. package/dist/extension-js-devtools/firefox/content_scripts/content-0.js +2 -2
  20. package/dist/extension-js-devtools/firefox/pages/centralized-logger.css +1 -1
  21. package/dist/extension-js-devtools/firefox/pages/welcome.css +1 -1
  22. package/dist/extension-js-devtools/firefox/scripts/logger-client.js +1 -1
  23. package/dist/feature-scripts-content-script-wrapper.js +1 -1
  24. package/dist/feature-scripts-content-script-wrapper.mjs +1 -1
  25. package/package.json +2 -2
@@ -208,6 +208,45 @@ function specialFolderChangeDetected(action, folder, relativePath) {
208
208
  }
209
209
  class WarnUponFolderChanges {
210
210
  pendingChanges = [];
211
+ knownFolderFiles = new Set();
212
+ hasSnapshot = false;
213
+ snapshotFolderFiles(projectPath) {
214
+ if (this.hasSnapshot) return;
215
+ this.hasSnapshot = true;
216
+ const SKIP_DIRS = new Set([
217
+ 'node_modules',
218
+ 'dist',
219
+ 'build',
220
+ '.git',
221
+ '.turbo',
222
+ '.next',
223
+ 'coverage'
224
+ ]);
225
+ const walk = (dir)=>{
226
+ let entries;
227
+ try {
228
+ entries = __rspack_external_fs.readdirSync(dir, {
229
+ withFileTypes: true
230
+ });
231
+ } catch {
232
+ return;
233
+ }
234
+ for (const entry of entries){
235
+ if (entry.name.startsWith('.')) continue;
236
+ if (SKIP_DIRS.has(entry.name)) continue;
237
+ const full = __rspack_external_path.join(dir, entry.name);
238
+ if (entry.isFile()) this.knownFolderFiles.add(full);
239
+ else if (entry.isDirectory()) walk(full);
240
+ }
241
+ };
242
+ for (const folder of [
243
+ 'pages',
244
+ "scripts"
245
+ ]){
246
+ const folderPath = __rspack_external_path.join(projectPath, folder);
247
+ if (__rspack_external_fs.existsSync(folderPath)) walk(folderPath);
248
+ }
249
+ }
211
250
  getContextDependencyPaths(projectPath) {
212
251
  const dependencies = new Set();
213
252
  for (const folder of [
@@ -247,6 +286,7 @@ class WarnUponFolderChanges {
247
286
  }
248
287
  collectChanges(compiler) {
249
288
  const projectPath = compiler.options.context || process.cwd();
289
+ this.snapshotFolderFiles(projectPath);
250
290
  const pagesPath = __rspack_external_path.join(projectPath, 'pages') + __rspack_external_path.sep;
251
291
  const scriptsPath = __rspack_external_path.join(projectPath, "scripts") + __rspack_external_path.sep;
252
292
  const extensionsSupported = compiler.options.resolve?.extensions;
@@ -254,13 +294,23 @@ class WarnUponFolderChanges {
254
294
  const modifiedFiles = compiler.modifiedFiles || new Set();
255
295
  const removedFiles = compiler.removedFiles || new Set();
256
296
  for (const filePath of modifiedFiles){
257
- if (filePath.startsWith(pagesPath) && filePath.endsWith('.html')) this.trackChange(projectPath, 'pages', 'add', filePath);
297
+ const isPreexisting = this.knownFolderFiles.has(filePath);
298
+ if (filePath.startsWith(pagesPath) && filePath.endsWith('.html')) {
299
+ if (isPreexisting) continue;
300
+ this.knownFolderFiles.add(filePath);
301
+ this.trackChange(projectPath, 'pages', 'add', filePath);
302
+ continue;
303
+ }
258
304
  if (filePath.startsWith(scriptsPath)) {
259
305
  const ext = __rspack_external_path.extname(filePath).toLowerCase();
260
- if (supportedScripts.has(ext)) this.trackChange(projectPath, "scripts", 'add', filePath);
306
+ if (!supportedScripts.has(ext)) continue;
307
+ if (isPreexisting) continue;
308
+ this.knownFolderFiles.add(filePath);
309
+ this.trackChange(projectPath, "scripts", 'add', filePath);
261
310
  }
262
311
  }
263
312
  for (const filePath of removedFiles){
313
+ this.knownFolderFiles.delete(filePath);
264
314
  if (filePath.startsWith(pagesPath) && filePath.endsWith('.html')) this.trackChange(projectPath, 'pages', 'remove', filePath);
265
315
  if (filePath.startsWith(scriptsPath)) {
266
316
  const ext = __rspack_external_path.extname(filePath).toLowerCase();
@@ -4059,12 +4109,6 @@ function normalizeManifestFile(filePath) {
4059
4109
  if (/[*?[\]{}]/.test(normalized)) return;
4060
4110
  return normalized;
4061
4111
  }
4062
- function compilationHasAsset(compilation, filename) {
4063
- if ('function' == typeof compilation.getAsset) {
4064
- if (compilation.getAsset(filename)) return true;
4065
- }
4066
- return Boolean(compilation.assets?.[filename]);
4067
- }
4068
4112
  function collectRequiredManifestFiles(manifest) {
4069
4113
  const required = new Set();
4070
4114
  const addFile = (filePath)=>{
@@ -4083,12 +4127,10 @@ function collectRequiredManifestFiles(manifest) {
4083
4127
  ...required
4084
4128
  ];
4085
4129
  }
4086
- function isFinalManifestReadyForDisk(compilation, manifestSource) {
4087
- const manifest = readJsonSafe(manifestSource);
4088
- if (!manifest) return false;
4089
- const requiredFiles = collectRequiredManifestFiles(manifest);
4090
- if (0 === requiredFiles.length) return true;
4091
- return requiredFiles.every((filename)=>compilationHasAsset(compilation, filename));
4130
+ function findMissingFilesOnDisk(outputPath, required) {
4131
+ const missing = [];
4132
+ for (const relativeFile of required)if (!__rspack_external_fs.existsSync(__rspack_external_path.join(outputPath, relativeFile))) missing.push(relativeFile);
4133
+ return missing;
4092
4134
  }
4093
4135
  function writeFileAtomically(targetPath, content) {
4094
4136
  const directory = __rspack_external_path.dirname(targetPath);
@@ -4101,32 +4143,61 @@ function writeFileAtomically(targetPath, content) {
4101
4143
  }
4102
4144
  class PersistManifestToDisk {
4103
4145
  apply(compiler) {
4104
- compiler.hooks.thisCompilation.tap('manifest:persist-manifest', (compilation)=>{
4146
+ let pendingManifestSource;
4147
+ let pendingOutputPath;
4148
+ let pendingHadErrors = false;
4149
+ compiler.hooks.thisCompilation.tap('manifest:persist-manifest:capture', (compilation)=>{
4105
4150
  compilation.hooks.processAssets.tap({
4106
- name: 'manifest:persist-manifest',
4151
+ name: 'manifest:persist-manifest:capture',
4107
4152
  stage: core_Compilation.PROCESS_ASSETS_STAGE_REPORT + 1000
4108
4153
  }, ()=>{
4109
- if (compilation.errors.length > 0) return;
4110
- const outputPath = compilation.outputOptions.path || compiler.options.output?.path;
4111
- if (!outputPath) return;
4154
+ pendingHadErrors = compilation.errors.length > 0;
4155
+ pendingOutputPath = compilation.outputOptions.path || compiler.options.output?.path;
4112
4156
  const manifestAsset = compilation.getAsset('manifest.json');
4113
4157
  const manifestSource = getCurrentManifestContent(compilation) || manifestAsset?.source?.source?.().toString();
4114
- if (!manifestSource) return;
4115
- if (!isFinalManifestReadyForDisk(compilation, manifestSource)) return;
4116
- const manifestOutputPath = __rspack_external_path.join(outputPath, 'manifest.json');
4117
- try {
4118
- try {
4119
- const currentOnDisk = __rspack_external_fs.readFileSync(manifestOutputPath, 'utf-8');
4120
- if (currentOnDisk === manifestSource) return;
4121
- } catch {}
4122
- writeFileAtomically(manifestOutputPath, manifestSource);
4123
- } catch (error) {
4124
- const err = new core.WebpackError(`Failed to persist manifest.json to disk: ${error.message}`);
4125
- err.file = 'manifest.json';
4126
- compilation.errors.push(err);
4127
- }
4158
+ pendingManifestSource = 'string' == typeof manifestSource ? manifestSource : void 0;
4128
4159
  });
4129
4160
  });
4161
+ compiler.hooks.afterEmit.tap('manifest:persist-manifest:flush', (compilation)=>{
4162
+ const outputPath = pendingOutputPath;
4163
+ const manifestSource = pendingManifestSource;
4164
+ const hadErrors = pendingHadErrors;
4165
+ pendingManifestSource = void 0;
4166
+ pendingOutputPath = void 0;
4167
+ pendingHadErrors = false;
4168
+ if (hadErrors || !outputPath || !manifestSource) return;
4169
+ const manifest = readJsonSafe(manifestSource);
4170
+ if (!manifest) return;
4171
+ const requiredFiles = collectRequiredManifestFiles(manifest);
4172
+ const missingFiles = findMissingFilesOnDisk(outputPath, requiredFiles);
4173
+ if (missingFiles.length > 0) {
4174
+ const sample = missingFiles.slice(0, 5).join('\n - ');
4175
+ const more = missingFiles.length > 5 ? `\n ... and ${missingFiles.length - 5} more` : '';
4176
+ const err = new core.WebpackError([
4177
+ 'manifest.json references files that were not emitted to disk for this build:',
4178
+ ` - ${sample}${more}`,
4179
+ '',
4180
+ 'The previous manifest.json was kept to avoid loading a broken extension.',
4181
+ 'This usually means the bundler skipped a chunk during an incremental rebuild.',
4182
+ 'Try saving any source file again, or restart `extension dev` if it persists.'
4183
+ ].join('\n'));
4184
+ err.file = 'manifest.json';
4185
+ compilation.errors.push(err);
4186
+ return;
4187
+ }
4188
+ const manifestOutputPath = __rspack_external_path.join(outputPath, 'manifest.json');
4189
+ try {
4190
+ try {
4191
+ const currentOnDisk = __rspack_external_fs.readFileSync(manifestOutputPath, 'utf-8');
4192
+ if (currentOnDisk === manifestSource) return;
4193
+ } catch {}
4194
+ writeFileAtomically(manifestOutputPath, manifestSource);
4195
+ } catch (error) {
4196
+ const err = new core.WebpackError(`Failed to persist manifest.json to disk: ${error.message}`);
4197
+ err.file = 'manifest.json';
4198
+ compilation.errors.push(err);
4199
+ }
4200
+ });
4130
4201
  }
4131
4202
  }
4132
4203
  class AddDependencies {
@@ -6585,8 +6656,9 @@ class SetupBackgroundEntry {
6585
6656
  const browser = this.browser;
6586
6657
  const minimumBgScript = resolveDevelopDistFile('firefox' === browser || 'gecko-based' === browser ? 'minimum-firefox-file' : 'minimum-chromium-file');
6587
6658
  const dirname = __rspack_external_path.dirname(this.manifestPath);
6588
- let manifestBg = scripts_lib_manifest_filterKeysForThisBrowser(manifest, browser);
6589
- manifestBg = manifestBg?.background ?? manifest.background;
6659
+ const filteredManifest = scripts_lib_manifest_filterKeysForThisBrowser(manifest, browser) || manifest;
6660
+ const manifestBg = filteredManifest?.background ?? manifest.background;
6661
+ const manifestVersion = filteredManifest?.manifest_version ?? manifest.manifest_version;
6590
6662
  function hookError(maybeError) {
6591
6663
  compiler.hooks.thisCompilation.tap('run-chromium:setup-background-entry', (compilation)=>{
6592
6664
  utils_reportToCompilation(compilation, compiler, maybeError, 'error');
@@ -6601,7 +6673,7 @@ class SetupBackgroundEntry {
6601
6673
  } else this.addDefaultEntry(compiler, "background/script", minimumBgScript);
6602
6674
  return;
6603
6675
  }
6604
- if (3 === manifest.manifest_version) {
6676
+ if (3 === manifestVersion) {
6605
6677
  const serviceWorker = manifestBg?.service_worker;
6606
6678
  if (serviceWorker) {
6607
6679
  const swPath = __rspack_external_path.join(dirname, serviceWorker);
@@ -6610,7 +6682,7 @@ class SetupBackgroundEntry {
6610
6682
  const existingEntry = compiler.options.entry && 'background/service_worker' in compiler.options.entry ? compiler.options.entry['background/service_worker'] : void 0;
6611
6683
  if (!existingEntry && __rspack_external_fs.existsSync(swPath)) this.addDefaultEntry(compiler, 'background/service_worker', swPath);
6612
6684
  } else this.addDefaultEntry(compiler, 'background/service_worker', minimumBgScript);
6613
- } else if (2 === manifest.manifest_version) {
6685
+ } else if (2 === manifestVersion) {
6614
6686
  const bgScripts = manifestBg?.scripts;
6615
6687
  if (bgScripts && bgScripts.length > 0) {
6616
6688
  const bgScriptPath = __rspack_external_path.join(dirname, bgScripts[0]);
@@ -6949,6 +7021,138 @@ class SetupReloadStrategy {
6949
7021
  }).apply(compiler);
6950
7022
  }
6951
7023
  }
7024
+ const SCRIPTS_REPLAY_SHIM_SOURCE = `;(function () {
7025
+ try {
7026
+ if (typeof globalThis !== "object" || !globalThis) return;
7027
+ var chromeRef =
7028
+ (globalThis.chrome && globalThis.chrome.scripting && typeof globalThis.chrome.scripting.executeScript === "function")
7029
+ ? globalThis.chrome
7030
+ : (globalThis.browser && globalThis.browser.scripting && typeof globalThis.browser.scripting.executeScript === "function")
7031
+ ? globalThis.browser
7032
+ : null;
7033
+ if (!chromeRef) return;
7034
+ if (globalThis.__extjsScriptsReplayInstalled) return;
7035
+ globalThis.__extjsScriptsReplayInstalled = true;
7036
+
7037
+ var registry = new Map();
7038
+ var originalExecuteScript = chromeRef.scripting.executeScript.bind(chromeRef.scripting);
7039
+
7040
+ var serialize = function (entry) {
7041
+ try {
7042
+ return JSON.stringify({
7043
+ files: entry && Array.isArray(entry.files) ? entry.files : [],
7044
+ world: entry && entry.world ? String(entry.world) : ""
7045
+ });
7046
+ } catch (error) {
7047
+ return "";
7048
+ }
7049
+ };
7050
+
7051
+ var track = function (injection) {
7052
+ try {
7053
+ var tabId = injection && injection.target && injection.target.tabId;
7054
+ var files =
7055
+ injection && Array.isArray(injection.files) ? injection.files.slice() : null;
7056
+ if (typeof tabId !== "number") return;
7057
+ if (!files || !files.length) return;
7058
+ var world = injection.world ? String(injection.world) : undefined;
7059
+ var entry = { files: files, world: world, sig: serialize({ files: files, world: world }) };
7060
+ var existing = registry.get(tabId) || [];
7061
+ // Dedupe by signature — repeated identical injections (e.g. user
7062
+ // clicks the action twice) shouldn't stack in the replay list.
7063
+ if (existing.some(function (e) { return e.sig === entry.sig; })) return;
7064
+ existing.push(entry);
7065
+ // Cap to the most recent 50 distinct injections per tab so a misbehaving
7066
+ // user loop can't grow the registry unbounded.
7067
+ registry.set(tabId, existing.slice(-50));
7068
+ } catch (error) {
7069
+ // Tracking is best-effort; never break the user's executeScript call.
7070
+ }
7071
+ };
7072
+
7073
+ chromeRef.scripting.executeScript = function (injection, callback) {
7074
+ track(injection);
7075
+ return originalExecuteScript(injection, callback);
7076
+ };
7077
+
7078
+ var normalizeFile = function (value) {
7079
+ return String(value || "").replace(/^[/\\\\]+/, "");
7080
+ };
7081
+
7082
+ var fileMatches = function (entryFile, changedNormalized) {
7083
+ var fn = normalizeFile(entryFile);
7084
+ for (var i = 0; i < changedNormalized.length; i++) {
7085
+ var c = changedNormalized[i];
7086
+ if (!c) continue;
7087
+ if (fn === c) return true;
7088
+ if (fn.length > c.length && fn.slice(fn.length - c.length - 1) === "/" + c) return true;
7089
+ if (c.length > fn.length && c.slice(c.length - fn.length - 1) === "/" + fn) return true;
7090
+ }
7091
+ return false;
7092
+ };
7093
+
7094
+ globalThis.__extjsScriptsReplay = function (changedFiles) {
7095
+ var changedNormalized = (Array.isArray(changedFiles) ? changedFiles : []).map(normalizeFile);
7096
+ var promises = [];
7097
+ registry.forEach(function (entries, tabId) {
7098
+ entries.forEach(function (entry) {
7099
+ var matches = false;
7100
+ for (var i = 0; i < entry.files.length; i++) {
7101
+ if (fileMatches(entry.files[i], changedNormalized)) {
7102
+ matches = true;
7103
+ break;
7104
+ }
7105
+ }
7106
+ if (!matches) return;
7107
+ try {
7108
+ promises.push(
7109
+ originalExecuteScript({
7110
+ target: { tabId: tabId },
7111
+ files: entry.files,
7112
+ world: entry.world
7113
+ }).then(
7114
+ function () { return { ok: true, tabId: tabId, files: entry.files }; },
7115
+ function (error) {
7116
+ return {
7117
+ ok: false,
7118
+ tabId: tabId,
7119
+ files: entry.files,
7120
+ error: String((error && error.message) || error)
7121
+ };
7122
+ }
7123
+ )
7124
+ );
7125
+ } catch (error) {
7126
+ // Tab may have closed; skip silently.
7127
+ }
7128
+ });
7129
+ });
7130
+ return Promise.all(promises);
7131
+ };
7132
+ } catch (error) {
7133
+ // Best-effort shim; do not break the SW bootstrap on any failure.
7134
+ }
7135
+ })();
7136
+ `;
7137
+ const BACKGROUND_ASSET = /(^|\/)background\/(?:service_worker|script)\.js$/i;
7138
+ class InjectScriptsReplayShim {
7139
+ apply(compiler) {
7140
+ compiler.hooks.thisCompilation.tap(InjectScriptsReplayShim.name, (compilation)=>{
7141
+ compilation.hooks.processAssets.tap({
7142
+ name: InjectScriptsReplayShim.name,
7143
+ stage: core_Compilation.PROCESS_ASSETS_STAGE_REPORT + 100
7144
+ }, ()=>{
7145
+ for (const asset of compilation.getAssets()){
7146
+ if (!BACKGROUND_ASSET.test(asset.name)) continue;
7147
+ const original = asset.source.source().toString();
7148
+ if (-1 !== original.indexOf('__extjsScriptsReplayInstalled')) continue;
7149
+ const next = SCRIPTS_REPLAY_SHIM_SOURCE + '\n' + original;
7150
+ compilation.updateAsset(asset.name, new core_sources.RawSource(next));
7151
+ }
7152
+ });
7153
+ });
7154
+ }
7155
+ }
6952
7156
  const DEV_SERVER_CLIENT_MARKERS = [
6953
7157
  '@rspack/dev-server/client/index.js?',
6954
7158
  '@rspack/dev-server/client/utils/ansiHTML.js',
@@ -7105,6 +7309,7 @@ class ScriptsPlugin {
7105
7309
  manifestPath: this.manifestPath,
7106
7310
  browser: this.browser
7107
7311
  }).apply(compiler);
7312
+ new InjectScriptsReplayShim().apply(compiler);
7108
7313
  }
7109
7314
  }
7110
7315
  }
@@ -8515,9 +8720,9 @@ function webpackConfig(projectStructure, devOptions) {
8515
8720
  clean: devOptions.output.clean,
8516
8721
  path: primaryExtensionOutputDir,
8517
8722
  publicPath: '/',
8518
- filename: 'development' === (devOptions.mode || 'development') ? (pathData)=>{
8723
+ filename: 'development' === (devOptions.mode || 'development') && false !== devOptions.hashContentScripts ? (pathData)=>{
8519
8724
  const chunkName = pathData.chunk?.name;
8520
- if ('string' == typeof chunkName && /^content_scripts\/content-\d+$/.test(chunkName)) return `${chunkName}.[fullhash:8].js`;
8725
+ if ('string' == typeof chunkName && /^content_scripts\/content-\d+$/.test(chunkName)) return `${chunkName}.[contenthash:8].js`;
8521
8726
  return '[name].js';
8522
8727
  } : '[name].js',
8523
8728
  hotUpdateChunkFilename: 'hot/[id].[fullhash].hot-update.js',
package/dist/946.mjs CHANGED
@@ -12,7 +12,7 @@ import * as __rspack_external_path from "path";
12
12
  import * as __rspack_external_fs from "fs";
13
13
  import * as __rspack_external_os from "os";
14
14
  import * as __rspack_external_vm from "vm";
15
- var package_namespaceObject = JSON.parse('{"rE":"3.16.0","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^2.0.1","@rspack/dev-server":"^2.0.1","@rspack/plugin-preact-refresh":"1.1.5","@rspack/plugin-react-refresh":"1.6.2","@swc/core":"^1.15.8","@swc/helpers":"^0.5.18","@vue/compiler-sfc":"3.5.26","adm-zip":"^0.5.16","browser-extension-manifest-fields":"^2.2.3","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^17.2.3","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.5.1","less-loader":"12.3.2","loader-utils":"^3.3.1","magic-string":"^0.30.21","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.10","postcss-loader":"8.2.1","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","react-refresh":"0.18.0","sass-loader":"16.0.7","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","typescript":"5.9.3","unique-names-generator":"^4.7.1","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3"}}');
15
+ var package_namespaceObject = JSON.parse('{"rE":"3.16.1-canary.309.312cc73","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^2.0.1","@rspack/dev-server":"^2.0.1","@rspack/plugin-preact-refresh":"1.1.5","@rspack/plugin-react-refresh":"1.6.2","@swc/core":"^1.15.8","@swc/helpers":"^0.5.18","@vue/compiler-sfc":"3.5.26","adm-zip":"^0.5.16","browser-extension-manifest-fields":"^2.2.3","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^17.2.3","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.5.1","less-loader":"12.3.2","loader-utils":"^3.3.1","magic-string":"^0.30.21","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.10","postcss-loader":"8.2.1","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","react-refresh":"0.18.0","sass-loader":"16.0.7","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","typescript":"5.9.3","unique-names-generator":"^4.7.1","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3"}}');
16
16
  const fmt = {
17
17
  heading: (title)=>pintor.underline(pintor.blue(title)),
18
18
  label: (key)=>pintor.gray(key.toUpperCase()),
@@ -49,8 +49,24 @@ function getLoggingPrefix(type) {
49
49
  function isPathLike(input) {
50
50
  return input.includes('/') || input.includes('\\') || __rspack_external_path.isAbsolute(input);
51
51
  }
52
- function manifestNotFoundError(manifestPath) {
53
- return `${getLoggingPrefix('error')} Manifest file not found.\n${pintor.red('Ensure the path to your extension exists and try again.')}\n${pintor.red('NOT FOUND')}\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}`;
52
+ function resolvedWorkspaceManifest(projectPath, manifestPath) {
53
+ const manifestDir = __rspack_external_path.dirname(manifestPath);
54
+ const packageDir = 'src' === __rspack_external_path.basename(manifestDir) ? __rspack_external_path.dirname(manifestDir) : manifestDir;
55
+ const display = __rspack_external_path.relative(projectPath, packageDir) || packageDir;
56
+ return `${getLoggingPrefix('info')} ${pintor.gray('Workspace root detected — resolved extension package:')} ${pintor.brightBlue(display)}`;
57
+ }
58
+ function manifestNotFoundError(manifestPath, candidates = []) {
59
+ const base = `${getLoggingPrefix('error')} Manifest file not found.\n${pintor.red('Ensure the path to your extension exists and try again.')}\n${pintor.red('NOT FOUND')}\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}`;
60
+ if (!candidates.length) return base;
61
+ const projectRoot = __rspack_external_path.dirname(manifestPath);
62
+ const hint = 1 === candidates.length ? "Did you mean to point at this workspace package?" : "Did you mean to point at one of these workspace packages?";
63
+ const suggestions = candidates.map((candidate)=>{
64
+ const dir = 'manifest.json' === __rspack_external_path.basename(candidate) ? __rspack_external_path.dirname(candidate) : candidate;
65
+ const normalized = 'src' === __rspack_external_path.basename(dir) ? __rspack_external_path.dirname(dir) : dir;
66
+ const display = __rspack_external_path.isAbsolute(normalized) ? __rspack_external_path.relative(projectRoot, normalized) || normalized : normalized;
67
+ return ` extension dev ${display}`;
68
+ }).join('\n');
69
+ return `${base}\n\n${pintor.gray(hint)}\n${pintor.brightBlue(suggestions)}`;
54
70
  }
55
71
  function previewing(browser) {
56
72
  return `${getLoggingPrefix('info')} Previewing the extension on ${capitalizedBrowserName(browser)}...`;
@@ -502,6 +518,41 @@ async function getProjectPath(pathOrRemoteUrl) {
502
518
  }
503
519
  return __rspack_external_path.resolve(process.cwd(), pathOrRemoteUrl);
504
520
  }
521
+ function collectManifestCandidates(rootDir, maxDepth) {
522
+ const SKIP_DIRS = new Set([
523
+ 'node_modules',
524
+ 'dist',
525
+ 'build',
526
+ 'out',
527
+ '.git',
528
+ '.turbo',
529
+ '.next',
530
+ 'coverage',
531
+ '.cache',
532
+ '.vercel'
533
+ ]);
534
+ const results = [];
535
+ const walk = (dir, depth)=>{
536
+ if (depth > maxDepth || results.length >= 10) return;
537
+ let entries;
538
+ try {
539
+ entries = __rspack_external_fs.readdirSync(dir, {
540
+ withFileTypes: true
541
+ });
542
+ } catch {
543
+ return;
544
+ }
545
+ for (const entry of entries){
546
+ if (entry.isFile() && 'manifest.json' === entry.name) {
547
+ results.push(__rspack_external_path.join(dir, entry.name));
548
+ continue;
549
+ }
550
+ if (entry.isDirectory() && !entry.name.startsWith('.') && !SKIP_DIRS.has(entry.name)) walk(__rspack_external_path.join(dir, entry.name), depth + 1);
551
+ }
552
+ };
553
+ walk(rootDir, 0);
554
+ return results;
555
+ }
505
556
  async function getProjectStructure(pathOrRemoteUrl) {
506
557
  const projectPath = await getProjectPath(pathOrRemoteUrl);
507
558
  const isUnderDir = (baseDir, candidatePath)=>{
@@ -513,8 +564,14 @@ async function getProjectStructure(pathOrRemoteUrl) {
513
564
  const rootManifestPath = __rspack_external_path.join(projectPath, 'manifest.json');
514
565
  const srcManifestPath = __rspack_external_path.join(projectPath, 'src', 'manifest.json');
515
566
  let manifestPath = __rspack_external_fs.existsSync(srcManifestPath) ? srcManifestPath : rootManifestPath;
516
- if (!__rspack_external_fs.existsSync(manifestPath)) {
517
- if (packageJsonDirFromProject) throw new Error(manifestNotFoundError(manifestPath));
567
+ if (!__rspack_external_fs.existsSync(manifestPath)) if (packageJsonDirFromProject) {
568
+ const absoluteCandidates = collectManifestCandidates(projectPath, 3);
569
+ const relativeCandidates = absoluteCandidates.map((candidate)=>__rspack_external_path.relative(projectPath, candidate) || candidate);
570
+ if (1 === absoluteCandidates.length) {
571
+ manifestPath = absoluteCandidates[0];
572
+ console.log(resolvedWorkspaceManifest(projectPath, manifestPath));
573
+ } else throw new Error(manifestNotFoundError(manifestPath, relativeCandidates));
574
+ } else {
518
575
  const findManifest = (dir)=>{
519
576
  const files = __rspack_external_fs.readdirSync(dir, {
520
577
  withFileTypes: true
@@ -23,4 +23,4 @@
23
23
  ██████████████████████████████████████████████████████████
24
24
  ██████████████████████████████████████████████████████████
25
25
  MIT (c) ${new Date().getFullYear()} - Cezar Augusto and the Extension.js authors.
26
- `,"background: transparent; color: #0971fe; "),!t){try{await n()}catch{try{chrome.tabs.create({url:o})}catch{}}return}let i=String(t.url||""),s=i.startsWith(`${a}://newtab`)||i.startsWith(`${a}://welcome`);0;s?await n():r(t,o)})}catch{}}let o=[],i=new Map,s=new Set;try{chrome.storage.session.get(["logger_capture_stacks"],e=>{e?.logger_capture_stacks}),chrome.storage.session.onChanged.addListener((e,t)=>{"session"===t&&"logger_capture_stacks"in e&&e.logger_capture_stacks?.newValue})}catch{}function c(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}function l(e){if(o.push(e),o.length>2e3&&o.shift(),"number"==typeof e.tabId){let t=i.get(e.tabId)||[];t.push(e),t.length>1e3&&t.shift(),i.set(e.tabId,t)}for(let t of s)try{let r={type:"append",event:e};t.postMessage(r)}catch{}}chrome.runtime.onConnect.addListener(e=>{if("logger"!==e.name)return;let t=t=>(function(e,t){var r;let n,a;if("subscribe"===t.type){s.add(e);try{e.postMessage({type:"init",events:o})}catch{}return}let i=e.sender?.id;if(i&&i===chrome.runtime.id)return;let l=e.sender?.tab?.id,d=e.sender?.frameId,u=e.sender?.tab?.incognito,m=e.sender?.tab?.windowId;if(r=i||`tab:${l??"unknown"}`,n=Date.now(),(a=h.get(r))?n-a.ts>1e3?(a.ts=n,a.count=1,!!0):(a.count+=1,!!(a.count>200)):(h.set(r,{ts:n,count:1}),!!0))return;let y=p(t.messageParts),v={id:c(),timestamp:Date.now(),level:t.level,context:t.context,messageParts:y,eventType:"dx.signal"===t.eventType||"log"===t.eventType?t.eventType:"log",code:"string"==typeof t.code?f(t.code,128):void 0,status:"ok"===t.status||"warn"===t.status||"fail"===t.status?t.status:void 0,data:b(t.data),remediation:"string"==typeof t.remediation?f(t.remediation,512):void 0,url:t.url,stack:t.stack,errorName:t.errorName,tabId:l,frameId:d,sourceExtensionId:i,incognito:u,windowId:m};g(v)})(e,t);e.onMessage.addListener(t),e.onDisconnect.addListener(()=>{s.delete(e);try{e.onMessage.removeListener(t)}catch{}})}),chrome.action.onClicked.addListener(async()=>{try{await chrome.sidePanel.setPanelBehavior({openPanelOnActionClick:!0})}catch{}});let d=[],u=new Set;function m(e){try{return JSON.stringify(e)}catch{return String(e)}}function g(e){let t=`${e.eventType??"log"}|${e.code??""}|${e.status??""}|${e.level}|${e.context}|${e.tabId??""}|${e.frameId??""}|${e.url??""}|${m(e.messageParts)}|${m(e.data)}`.slice(0,512);if(!u.has(t)){if(u.add(t),d.push(t),d.length>2e3){let e=d.shift();e&&u.delete(e)}if(e.url&&!e.hostname)try{let t=new URL(e.url);e.hostname=`${t.hostname}${t.pathname}`}catch{}if(null!=e.tabId&&null==e.title)try{chrome.tabs.get(e.tabId,t=>{if(chrome.runtime.lastError)return l(e);e.title=t?.title||e.title,l(e)});return}catch{}l(e)}}let h=new Map;function f(e,t=2048){return e.length<=t?e:e.slice(0,t)+"..."}function y(e){try{return JSON.stringify(e)}catch{try{return String(e)}catch{return"[unserializable]"}}}function p(e){try{let t=[];for(let r of e??[])if("string"==typeof r?t.push(f(r)):r instanceof Error?t.push(f(`${r.name}: ${r.message}`)):t.push(f(y(r))),t.join(" ").length>8192)break;return t}catch{return[y(e)]}}function b(e){if(e&&"object"==typeof e)try{let t=JSON.stringify(e);if(!t)return;let r=JSON.parse(t);if(0===Object.keys(r).length)return;return r}catch{return}}function v(e,t,r={}){g({id:c(),timestamp:Date.now(),level:e,context:"background",messageParts:t,url:"string"==typeof r.url?r.url:void 0,tabId:"number"==typeof r.tabId?r.tabId:void 0,frameId:"number"==typeof r.frameId?r.frameId:void 0})}async function x(){let e=(await new Promise(e=>{chrome.management.getAll(e)})||[]).filter(e=>{let t;return e.id!==chrome.runtime.id&&"igcijhgmihmjbbahdabahfbpffalcfnn"!==e.id&&"development"===e.installType&&"theme"!==e.type&&!((t=String(e.name||"").toLowerCase()).includes("extension.js built-in developer tools")||t.includes("extension.js theme"))});if(0===e.length)return{ok:!0,extensionEnabled:null};let t=e.find(e=>e.enabled)||e[e.length-1];return{ok:!0,extensionEnabled:!!t?.enabled,extensionName:t?.name,extensionId:t?.id}}async function w(e){if(e.startsWith("data:"))return e;let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch icon: ${t.status}`);let r=await t.blob();return await new Promise((e,t)=>{let n=new FileReader;n.onload=()=>e(String(n.result||"")),n.onerror=()=>t(Error("Failed to read icon blob")),n.readAsDataURL(r)})}chrome.runtime.onInstalled.addListener(e=>{v("info",["extension installed",e.reason,e.previousVersion??null])}),chrome.storage.session.get(["logger_events"],e=>{let t=Array.isArray(e?.logger_events)?e.logger_events:[];if(t.length)for(let e of t.slice(-2e3))o.push(e)}),setInterval(()=>{chrome.storage.session.set({logger_events:o.slice(-200)})},2e3),chrome.runtime.onStartup.addListener(()=>{v("info",["extension startup"]);try{v("info",["TEST_LOG: background-start"])}catch{}}),chrome.tabs.onCreated.addListener(e=>{v("info",["tab created"],{tabId:e.id??void 0,url:e.url})}),chrome.tabs.onUpdated.addListener((e,t,r)=>{"loading"===t.status&&v("debug",["tab loading"],{tabId:e,url:r.url}),"complete"===t.status&&v("debug",["tab complete"],{tabId:e,url:r.url}),"string"==typeof t.url&&v("info",["tab url changed",t.url],{tabId:e,url:t.url})}),chrome.tabs.onRemoved.addListener((e,t)=>{v("info",["tab removed",{windowId:t.windowId,isWindowClosing:t.isWindowClosing}],{tabId:e})}),chrome.webNavigation.onBeforeNavigate.addListener(e=>{0===e.frameId&&v("info",["Before navigate"],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.webNavigation.onCommitted.addListener(e=>{0===e.frameId&&v("info",["Navigation committed"],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.webNavigation.onCompleted.addListener(e=>{0===e.frameId&&v("info",["Navigation completed"],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.webNavigation.onErrorOccurred.addListener(e=>{0===e.frameId&&v("error",["Navigation error",e.error],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.webNavigation.onHistoryStateUpdated.addListener(e=>{0===e.frameId&&v("info",["History state updated"],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.runtime.onMessage.addListener((e,t,r)=>e&&"get-events"===e.type?(r({events:o.slice(-500)}),!0):!!e&&"clear-events"===e.type&&(o.length=0,r({ok:!0}),!0)),chrome.runtime.onMessage.addListener((e,t,r)=>{if((!t?.id||t.id===chrome.runtime.id)&&e){if("resolve-icon-url"===e.type)return e.url&&function(e){if(e.startsWith("data:"))return!0;try{let t=new URL(e);return"moz-extension:"===t.protocol||"chrome-extension:"===t.protocol}catch{return!1}}(e.url)?(w(e.url).then(e=>r({ok:!0,dataUrl:e})).catch(e=>r({ok:!1,error:String(e)})),!0):void r({ok:!1,error:"Unsupported icon URL"});if("get-dx-status"===e.type)return x().then(e=>r(e)).catch(e=>r({ok:!1,error:String(e||"Unknown error")})),!0;if("dx-signal"===e.type){try{var n={level:e.level||"info",context:e.context||"content",messageParts:Array.isArray(e.messageParts)&&e.messageParts.length>0?e.messageParts:[e.code||"DX_SIGNAL"],eventType:e.eventType||"dx.signal",code:e.code,status:e.status,data:e.data,remediation:e.remediation,url:"string"==typeof e.url?e.url:void 0,stack:"string"==typeof e.stack?e.stack:void 0,errorName:"string"==typeof e.errorName?e.errorName:void 0};g({id:c(),timestamp:Date.now(),level:n.level,context:n.context,messageParts:p(n.messageParts||[]),eventType:"dx.signal"===n.eventType||"log"===n.eventType?n.eventType:"log",code:"string"==typeof n.code?f(String(n.code),128):void 0,status:"ok"===n.status||"warn"===n.status||"fail"===n.status?n.status:void 0,data:b(n.data),remediation:"string"==typeof n.remediation?f(n.remediation,512):void 0,url:n.url,stack:n.stack,errorName:n.errorName,tabId:n.tabId,frameId:n.frameId}),r({ok:!0})}catch(e){r({ok:!1,error:String(e||"Unknown error")})}return!0}}}),chrome.runtime.onStartup.addListener(async()=>{await a()}),chrome.runtime.onInstalled.addListener(async()=>{await a()})})();
26
+ `,"background: transparent; color: #0971fe; "),!t){try{await n()}catch{try{chrome.tabs.create({url:o})}catch{}}return}let i=String(t.url||""),s=i.startsWith(`${a}://newtab`)||i.startsWith(`${a}://welcome`);0;s?await n():r(t,o)})}catch{}}let o=[],i=new Map,s=new Set;try{chrome.storage.session.get(["logger_capture_stacks"],e=>{e?.logger_capture_stacks}),chrome.storage.session.onChanged.addListener((e,t)=>{"session"===t&&"logger_capture_stacks"in e&&e.logger_capture_stacks?.newValue})}catch{}function d(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}function c(e){if(o.push(e),o.length>2e3&&o.shift(),"number"==typeof e.tabId){let t=i.get(e.tabId)||[];t.push(e),t.length>1e3&&t.shift(),i.set(e.tabId,t)}for(let t of s)try{let r={type:"append",event:e};t.postMessage(r)}catch{}}chrome.runtime.onConnect.addListener(e=>{if("logger"!==e.name)return;let t=t=>(function(e,t){var r;let n,a;if("subscribe"===t.type){s.add(e);try{e.postMessage({type:"init",events:o})}catch{}return}let i=e.sender?.id;if(i&&i===chrome.runtime.id)return;let c=e.sender?.tab?.id,l=e.sender?.frameId,u=e.sender?.tab?.incognito,m=e.sender?.tab?.windowId;if(r=i||`tab:${c??"unknown"}`,n=Date.now(),(a=h.get(r))?n-a.ts>1e3?(a.ts=n,a.count=1,!!0):(a.count+=1,!!(a.count>200)):(h.set(r,{ts:n,count:1}),!!0))return;let y=p(t.messageParts),v={id:d(),timestamp:Date.now(),level:t.level,context:t.context,messageParts:y,eventType:"dx.signal"===t.eventType||"log"===t.eventType?t.eventType:"log",code:"string"==typeof t.code?f(t.code,128):void 0,status:"ok"===t.status||"warn"===t.status||"fail"===t.status?t.status:void 0,data:b(t.data),remediation:"string"==typeof t.remediation?f(t.remediation,512):void 0,url:t.url,stack:t.stack,errorName:t.errorName,tabId:c,frameId:l,sourceExtensionId:i,incognito:u,windowId:m};g(v)})(e,t);e.onMessage.addListener(t),e.onDisconnect.addListener(()=>{s.delete(e);try{e.onMessage.removeListener(t)}catch{}})}),chrome.action.onClicked.addListener(async()=>{try{await chrome.sidePanel.setPanelBehavior({openPanelOnActionClick:!0})}catch{}});let l=[],u=new Set;function m(e){try{return JSON.stringify(e)}catch{return String(e)}}function g(e){let t=`${e.eventType??"log"}|${e.code??""}|${e.status??""}|${e.level}|${e.context}|${e.tabId??""}|${e.frameId??""}|${e.url??""}|${m(e.messageParts)}|${m(e.data)}`.slice(0,512);if(!u.has(t)){if(u.add(t),l.push(t),l.length>2e3){let e=l.shift();e&&u.delete(e)}if(e.url&&!e.hostname)try{let t=new URL(e.url);e.hostname=`${t.hostname}${t.pathname}`}catch{}if(null!=e.tabId&&null==e.title)try{chrome.tabs.get(e.tabId,t=>{if(chrome.runtime.lastError)return c(e);e.title=t?.title||e.title,c(e)});return}catch{}c(e)}}let h=new Map;function f(e,t=2048){return e.length<=t?e:e.slice(0,t)+"..."}function y(e){try{return JSON.stringify(e)}catch{try{return String(e)}catch{return"[unserializable]"}}}function p(e){try{let t=[];for(let r of e??[])if("string"==typeof r?t.push(f(r)):r instanceof Error?t.push(f(`${r.name}: ${r.message}`)):t.push(f(y(r))),t.join(" ").length>8192)break;return t}catch{return[y(e)]}}function b(e){if(e&&"object"==typeof e)try{let t=JSON.stringify(e);if(!t)return;let r=JSON.parse(t);if(0===Object.keys(r).length)return;return r}catch{return}}function v(e,t,r={}){g({id:d(),timestamp:Date.now(),level:e,context:"background",messageParts:t,url:"string"==typeof r.url?r.url:void 0,tabId:"number"==typeof r.tabId?r.tabId:void 0,frameId:"number"==typeof r.frameId?r.frameId:void 0})}function x(e){let t=String(e.name||"").toLowerCase();return t.includes("extension.js built-in developer tools")||t.includes("extension.js theme")}async function w(){let e=(await new Promise(e=>{chrome.management.getAll(e)})||[]).filter(e=>e.id!==chrome.runtime.id&&"igcijhgmihmjbbahdabahfbpffalcfnn"!==e.id&&"development"===e.installType&&"theme"!==e.type&&!x(e));if(0===e.length)return{ok:!0,extensionEnabled:null};let t=e.find(e=>e.enabled)||e[e.length-1];return{ok:!0,extensionEnabled:!!t?.enabled,extensionName:t?.name,extensionId:t?.id}}async function I(e){if(e.startsWith("data:"))return e;let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch icon: ${t.status}`);let r=await t.blob();return await new Promise((e,t)=>{let n=new FileReader;n.onload=()=>e(String(n.result||"")),n.onerror=()=>t(Error("Failed to read icon blob")),n.readAsDataURL(r)})}function L(e){return!!e&&e.id!==chrome.runtime.id&&"development"===e.installType&&"theme"!==e.type&&!x(e)}function k(e){try{chrome.tabs.query({},t=>{for(let r of t||[])if("number"==typeof r.id)try{chrome.tabs.sendMessage(r.id,{type:"extjs-dev-reload",state:e}).catch(()=>{})}catch{}})}catch{}}chrome.runtime.onInstalled.addListener(e=>{v("info",["extension installed",e.reason,e.previousVersion??null])}),chrome.storage.session.get(["logger_events"],e=>{let t=Array.isArray(e?.logger_events)?e.logger_events:[];if(t.length)for(let e of t.slice(-2e3))o.push(e)}),setInterval(()=>{chrome.storage.session.set({logger_events:o.slice(-200)})},2e3),chrome.runtime.onStartup.addListener(()=>{v("info",["extension startup"]);try{v("info",["TEST_LOG: background-start"])}catch{}}),chrome.tabs.onCreated.addListener(e=>{v("info",["tab created"],{tabId:e.id??void 0,url:e.url})}),chrome.tabs.onUpdated.addListener((e,t,r)=>{"loading"===t.status&&v("debug",["tab loading"],{tabId:e,url:r.url}),"complete"===t.status&&v("debug",["tab complete"],{tabId:e,url:r.url}),"string"==typeof t.url&&v("info",["tab url changed",t.url],{tabId:e,url:t.url})}),chrome.tabs.onRemoved.addListener((e,t)=>{v("info",["tab removed",{windowId:t.windowId,isWindowClosing:t.isWindowClosing}],{tabId:e})}),chrome.webNavigation.onBeforeNavigate.addListener(e=>{0===e.frameId&&v("info",["Before navigate"],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.webNavigation.onCommitted.addListener(e=>{0===e.frameId&&v("info",["Navigation committed"],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.webNavigation.onCompleted.addListener(e=>{0===e.frameId&&v("info",["Navigation completed"],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.webNavigation.onErrorOccurred.addListener(e=>{0===e.frameId&&v("error",["Navigation error",e.error],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.webNavigation.onHistoryStateUpdated.addListener(e=>{0===e.frameId&&v("info",["History state updated"],{tabId:e.tabId,frameId:e.frameId,url:e.url,title:"[navigation]"})}),chrome.runtime.onMessage.addListener((e,t,r)=>e&&"get-events"===e.type?(r({events:o.slice(-500)}),!0):!!e&&"clear-events"===e.type&&(o.length=0,r({ok:!0}),!0)),chrome.runtime.onMessage.addListener((e,t,r)=>{if((!t?.id||t.id===chrome.runtime.id)&&e){if("resolve-icon-url"===e.type)return e.url&&function(e){if(e.startsWith("data:"))return!0;try{let t=new URL(e);return"moz-extension:"===t.protocol||"chrome-extension:"===t.protocol}catch{return!1}}(e.url)?(I(e.url).then(e=>r({ok:!0,dataUrl:e})).catch(e=>r({ok:!1,error:String(e)})),!0):void r({ok:!1,error:"Unsupported icon URL"});if("get-dx-status"===e.type)return w().then(e=>r(e)).catch(e=>r({ok:!1,error:String(e||"Unknown error")})),!0;if("dx-signal"===e.type){try{var n={level:e.level||"info",context:e.context||"content",messageParts:Array.isArray(e.messageParts)&&e.messageParts.length>0?e.messageParts:[e.code||"DX_SIGNAL"],eventType:e.eventType||"dx.signal",code:e.code,status:e.status,data:e.data,remediation:e.remediation,url:"string"==typeof e.url?e.url:void 0,stack:"string"==typeof e.stack?e.stack:void 0,errorName:"string"==typeof e.errorName?e.errorName:void 0};g({id:d(),timestamp:Date.now(),level:n.level,context:n.context,messageParts:p(n.messageParts||[]),eventType:"dx.signal"===n.eventType||"log"===n.eventType?n.eventType:"log",code:"string"==typeof n.code?f(String(n.code),128):void 0,status:"ok"===n.status||"warn"===n.status||"fail"===n.status?n.status:void 0,data:b(n.data),remediation:"string"==typeof n.remediation?f(n.remediation,512):void 0,url:n.url,stack:n.stack,errorName:n.errorName,tabId:n.tabId,frameId:n.frameId}),r({ok:!0})}catch(e){r({ok:!1,error:String(e||"Unknown error")})}return!0}}}),chrome.runtime.onStartup.addListener(async()=>{await a()}),chrome.runtime.onInstalled.addListener(async()=>{await a()}),"function"==typeof chrome.management?.onDisabled?.addListener&&chrome.management.onDisabled.addListener(e=>{L(e)&&k("reloading")}),"function"==typeof chrome.management?.onEnabled?.addListener&&chrome.management.onEnabled.addListener(e=>{L(e)&&k("reloaded")}),"function"==typeof chrome.management?.onInstalled?.addListener&&chrome.management.onInstalled.addListener(e=>{L(e)&&k("reloaded")})})();