extension 4.1.28 → 4.1.30

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/dist/597.cjs CHANGED
@@ -193,6 +193,8 @@ exports.modules = {
193
193
  var external_node_path_ = __webpack_require__("node:path");
194
194
  var messaging = __webpack_require__("./helpers/messaging.ts");
195
195
  var banner = __webpack_require__("./browsers/browsers-lib/banner.ts");
196
+ var browser_family = __webpack_require__("./browsers/browsers-lib/browser-family.ts");
197
+ var companion_session = __webpack_require__("./browsers/browsers-lib/companion-session.ts");
196
198
  var messages = __webpack_require__("./browsers/browsers-lib/messages.ts");
197
199
  var newtab_override = __webpack_require__("./browsers/browsers-lib/newtab-override.ts");
198
200
  var ready_stamp = __webpack_require__("./browsers/browsers-lib/ready-stamp.ts");
@@ -828,7 +830,12 @@ exports.modules = {
828
830
  else obj[key] = value;
829
831
  return obj;
830
832
  }
831
- const DEVTOOLS_COMPANION_ID_CHROMIUM = 'kgdaecdpfkikjncaalnmmnjjfpofkcbl';
833
+ function devtoolsCompanionWelcomeUrl(companionPath) {
834
+ return `chrome-extension://${(0, banner.vy)(companionPath)}/pages/welcome.html`;
835
+ }
836
+ const FORK_FIRST_RUN_PAGES = {
837
+ vivaldi: /^chrome-extension:\/\/mpognobbkildjkofajifpdfhcoklimli\/components\/welcome\//
838
+ };
832
839
  const __fileReadCache = new Map();
833
840
  function readTextFileCached(filePath) {
834
841
  try {
@@ -863,11 +870,32 @@ exports.modules = {
863
870
  url
864
871
  });
865
872
  }
873
+ async replaceForkFirstRunTabs(browser, replacementUrl) {
874
+ if (!this.cdp) return 0;
875
+ const pattern = FORK_FIRST_RUN_PAGES[String(browser || '').toLowerCase()];
876
+ if (!pattern) return 0;
877
+ const targets = await this.cdp.getTargets();
878
+ let replaced = 0;
879
+ for (const target of targets)if (target?.type === 'page') {
880
+ if (pattern.test(String(target?.url || ''))) try {
881
+ const attached = await this.cdp.sendCommand('Target.attachToTarget', {
882
+ targetId: target.targetId,
883
+ flatten: true
884
+ });
885
+ const sessionId = attached?.sessionId || '';
886
+ if (!sessionId) continue;
887
+ await this.cdp.sendCommand('Page.navigate', {
888
+ url: replacementUrl
889
+ }, sessionId);
890
+ replaced += 1;
891
+ } catch {}
892
+ }
893
+ return replaced;
894
+ }
866
895
  async closeSelfOpenedTabs() {
867
896
  if (!this.cdp) return 0;
868
- const selfIds = new Set([
869
- DEVTOOLS_COMPANION_ID_CHROMIUM
870
- ]);
897
+ const selfIds = new Set();
898
+ if (this.companionPath) selfIds.add((0, banner.vy)(this.companionPath));
871
899
  for (const extensionPath of this.extensionPaths || [])if (external_node_path_.resolve(extensionPath) !== external_node_path_.resolve(this.outPath)) selfIds.add((0, banner.vy)(extensionPath));
872
900
  const targets = await this.cdp.getTargets();
873
901
  let closed = 0;
@@ -892,7 +920,8 @@ exports.modules = {
892
920
  status: 'unknown'
893
921
  };
894
922
  const expectedId = (0, banner.vy)(this.outPath);
895
- if (expectedId && (0, ensure.tg)(this.outPath)) {
923
+ const loadedFromCommandLine = !(0, browser_family.v$)(this.browser);
924
+ if (expectedId && loadedFromCommandLine && (0, ensure.tg)(this.outPath)) {
896
925
  const present = await this.waitForExtensionTarget(expectedId, 12, 200);
897
926
  if (present) {
898
927
  if (!this.extensionId) this.extensionId = expectedId;
@@ -921,6 +950,25 @@ exports.modules = {
921
950
  getLoadRefusalReason() {
922
951
  return this.loadRefusalReason;
923
952
  }
953
+ async loadCompanions(extensionPaths) {
954
+ if (!this.cdp) return [];
955
+ const results = [];
956
+ for (const extensionPath of extensionPaths){
957
+ let outcome;
958
+ try {
959
+ outcome = await (0, ensure.iF)(this.cdp, extensionPath);
960
+ } catch {
961
+ outcome = {
962
+ status: 'unknown'
963
+ };
964
+ }
965
+ results.push({
966
+ path: extensionPath,
967
+ outcome
968
+ });
969
+ }
970
+ return results;
971
+ }
924
972
  async waitForExtensionTarget(extensionId, maxRetries, backoffMs) {
925
973
  const prefix = `chrome-extension://${extensionId}/`;
926
974
  for(let attempt = 0; attempt <= maxRetries; attempt++){
@@ -1136,9 +1184,11 @@ exports.modules = {
1136
1184
  }
1137
1185
  constructor(args){
1138
1186
  cdp_extension_controller_define_property(this, "outPath", void 0);
1187
+ cdp_extension_controller_define_property(this, "browser", void 0);
1139
1188
  cdp_extension_controller_define_property(this, "cdpPort", void 0);
1140
1189
  cdp_extension_controller_define_property(this, "profilePath", void 0);
1141
1190
  cdp_extension_controller_define_property(this, "extensionPaths", void 0);
1191
+ cdp_extension_controller_define_property(this, "companionPath", void 0);
1142
1192
  cdp_extension_controller_define_property(this, "pipeIn", void 0);
1143
1193
  cdp_extension_controller_define_property(this, "pipeOut", void 0);
1144
1194
  cdp_extension_controller_define_property(this, "logSink", void 0);
@@ -1146,9 +1196,11 @@ exports.modules = {
1146
1196
  cdp_extension_controller_define_property(this, "extensionId", null);
1147
1197
  cdp_extension_controller_define_property(this, "loadRefusalReason", null);
1148
1198
  this.outPath = args.outPath;
1199
+ this.browser = args.browser;
1149
1200
  this.cdpPort = args.cdpPort;
1150
1201
  this.profilePath = args.profilePath;
1151
1202
  this.extensionPaths = args.extensionPaths;
1203
+ this.companionPath = args.companionPath;
1152
1204
  this.pipeIn = args.pipeIn;
1153
1205
  this.pipeOut = args.pipeOut;
1154
1206
  this.logSink = args.logSink;
@@ -1162,6 +1214,7 @@ exports.modules = {
1162
1214
  const selectedExtensionPaths = extensionOutputPath && extensionOutputPath.length > 0 ? [
1163
1215
  extensionOutputPath
1164
1216
  ] : extensionPaths;
1217
+ const companionPath = extensionPaths.find(companion_session.Ck);
1165
1218
  const remoteDebugPortFlag = chromiumArgs.find((flag)=>flag.startsWith('--remote-debugging-port='));
1166
1219
  const chromeRemoteDebugPort = remoteDebugPortFlag ? parseInt(remoteDebugPortFlag.split('=')[1], 10) : (0, shared_utils.jl)(plugin.port, plugin.instanceId);
1167
1220
  const userDataDirFlag = chromiumArgs.find((flag)=>flag.startsWith('--user-data-dir='));
@@ -1173,10 +1226,11 @@ exports.modules = {
1173
1226
  }
1174
1227
  const cdpExtensionController = new CDPExtensionController({
1175
1228
  outPath: extensionOutputPath,
1176
- browser: 'chromium-based' === plugin.browser ? 'chrome' : plugin.browser,
1229
+ browser: plugin.browser,
1177
1230
  cdpPort: chromeRemoteDebugPort,
1178
1231
  profilePath: userDataDir || void 0,
1179
1232
  extensionPaths: selectedExtensionPaths,
1233
+ companionPath,
1180
1234
  pipeIn: pipeStreams?.input,
1181
1235
  pipeOut: pipeStreams?.output,
1182
1236
  logSink: plugin.logSink
@@ -1344,9 +1398,18 @@ exports.modules = {
1344
1398
  });
1345
1399
  } catch {}
1346
1400
  }
1401
+ try {
1402
+ if ((0, browser_family.v$)(plugin.browser)) {
1403
+ const results = await cdpExtensionController.loadCompanions((0, companion_session.xz)(extensionPaths, extensionOutputPath));
1404
+ if ((0, messaging._o)()) for (const { path: loadedPath, outcome } of results)(0, messaging._w)(`[CDP] companion ${loadedPath}: ${outcome.status}${'refused' === outcome.status ? ` (${outcome.reason})` : ''}`);
1405
+ }
1406
+ } catch {}
1347
1407
  try {
1348
1408
  if (extensionControllerInfo && !plugin.startingUrl && !plugin.noOpen && (0, newtab_override.c)(extensionOutputPath)) await cdpExtensionController.openTab('chrome://newtab/');
1349
1409
  } catch {}
1410
+ try {
1411
+ if (extensionControllerInfo) await cdpExtensionController.replaceForkFirstRunTabs(plugin.browser, plugin.noOpen || !companionPath ? 'about:blank' : devtoolsCompanionWelcomeUrl(companionPath));
1412
+ } catch {}
1350
1413
  try {
1351
1414
  if (plugin.noOpen) await cdpExtensionController.closeSelfOpenedTabs();
1352
1415
  } catch {}
package/dist/browsers.cjs CHANGED
@@ -283,6 +283,15 @@ var __webpack_modules__ = {
283
283
  'yandex',
284
284
  'chromium-based'
285
285
  ]);
286
+ const SYSTEM_LOCATED_CHROMIUM_FORKS = new Set([
287
+ 'brave',
288
+ 'opera',
289
+ 'vivaldi',
290
+ 'yandex'
291
+ ]);
292
+ const CDP_ONLY_EXTENSION_LOAD_BROWSERS = new Set([
293
+ 'yandex'
294
+ ]);
286
295
  const FIREFOX_BROWSERS = new Set([
287
296
  'firefox',
288
297
  'waterfox',
@@ -295,6 +304,12 @@ var __webpack_modules__ = {
295
304
  function isChromiumBrowser(browser) {
296
305
  return CHROMIUM_BROWSERS.has(String(browser));
297
306
  }
307
+ function isSystemLocatedChromiumFork(browser) {
308
+ return SYSTEM_LOCATED_CHROMIUM_FORKS.has(String(browser));
309
+ }
310
+ function loadsExtensionsOverCdpOnly(browser) {
311
+ return CDP_ONLY_EXTENSION_LOAD_BROWSERS.has(String(browser));
312
+ }
298
313
  function isFirefoxBrowser(browser) {
299
314
  return FIREFOX_BROWSERS.has(String(browser));
300
315
  }
@@ -306,25 +321,50 @@ var __webpack_modules__ = {
306
321
  }
307
322
  __webpack_require__.d(__webpack_exports__, {
308
323
  M_: ()=>isFirefoxBrowser,
324
+ cA: ()=>isSystemLocatedChromiumFork,
309
325
  eP: ()=>isEmulatorBrowser,
310
- rG: ()=>isChromiumBrowser
326
+ rG: ()=>isChromiumBrowser,
327
+ v$: ()=>loadsExtensionsOverCdpOnly
311
328
  });
312
329
  },
313
330
  "./browsers/browsers-lib/companion-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
314
331
  var node_fs__rspack_import_0 = __webpack_require__("node:fs");
315
332
  var node_path__rspack_import_1 = __webpack_require__("node:path");
316
333
  var _helpers_messaging__rspack_import_2 = __webpack_require__("./helpers/messaging.ts");
334
+ var _browser_family__rspack_import_3 = __webpack_require__("./browsers/browsers-lib/browser-family.ts");
317
335
  const COMPANION_SESSION_FLAGS_FILE = 'extension-js-session.json';
318
336
  const COMPANION_DIR_NAME = 'extension-js-devtools';
319
337
  function isDevtoolsCompanionPath(extensionPath) {
320
338
  return node_path__rspack_import_1.normalize(String(extensionPath || '')).split(/[\\/]+/).includes(COMPANION_DIR_NAME);
321
339
  }
340
+ function readManifest(extensionPath) {
341
+ try {
342
+ const parsed = JSON.parse(node_fs__rspack_import_0.readFileSync(node_path__rspack_import_1.join(extensionPath, 'manifest.json'), 'utf8'));
343
+ return parsed && 'object' == typeof parsed ? parsed : null;
344
+ } catch {
345
+ return null;
346
+ }
347
+ }
348
+ function companionPathsForCdpLoad(extensionPaths, outPath) {
349
+ return extensionPaths.filter((extensionPath)=>{
350
+ if (node_path__rspack_import_1.resolve(extensionPath) === node_path__rspack_import_1.resolve(outPath)) return false;
351
+ return !readManifest(extensionPath)?.theme;
352
+ });
353
+ }
354
+ function dropNewTabOverride(extensionPath) {
355
+ const manifestPath = node_path__rspack_import_1.join(extensionPath, 'manifest.json');
356
+ const manifest = readManifest(extensionPath);
357
+ if (!manifest || !('chrome_url_overrides' in manifest)) return;
358
+ delete manifest.chrome_url_overrides;
359
+ node_fs__rspack_import_0.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
360
+ }
322
361
  function stagedCompanionPath(stageRoot, companionPath) {
323
362
  return node_path__rspack_import_1.join(stageRoot, COMPANION_DIR_NAME, node_path__rspack_import_1.basename(companionPath));
324
363
  }
325
- function stageCompanionForNoOpen(input) {
364
+ function stageCompanionForSession(input) {
326
365
  const { extensionPaths } = input;
327
- if (!input.noOpen || !input.stageRoot) return extensionPaths;
366
+ const cdpOnly = (0, _browser_family__rspack_import_3.v$)(input.browser || '');
367
+ if (!input.noOpen && !cdpOnly || !input.stageRoot) return extensionPaths;
328
368
  const index = extensionPaths.findIndex((p)=>isDevtoolsCompanionPath(p));
329
369
  if (-1 === index) return extensionPaths;
330
370
  const source = extensionPaths[index];
@@ -339,11 +379,12 @@ var __webpack_modules__ = {
339
379
  recursive: true
340
380
  });
341
381
  const flags = {
342
- noOpen: true
382
+ noOpen: Boolean(input.noOpen)
343
383
  };
344
384
  node_fs__rspack_import_0.writeFileSync(node_path__rspack_import_1.join(staged, COMPANION_SESSION_FLAGS_FILE), `${JSON.stringify(flags)}\n`, 'utf8');
385
+ if (cdpOnly) dropNewTabOverride(staged);
345
386
  } catch (error) {
346
- if ((0, _helpers_messaging__rspack_import_2._o)()) (0, _helpers_messaging__rspack_import_2.mR)(`[browser] Could not stage the devtools companion for --no-open: ${error?.message || String(error)}`);
387
+ if ((0, _helpers_messaging__rspack_import_2._o)()) (0, _helpers_messaging__rspack_import_2.mR)(`[browser] Could not stage the devtools companion for this session: ${error?.message || String(error)}`);
347
388
  return extensionPaths;
348
389
  }
349
390
  const next = [
@@ -353,7 +394,9 @@ var __webpack_modules__ = {
353
394
  return next;
354
395
  }
355
396
  __webpack_require__.d(__webpack_exports__, {
356
- Br: ()=>stageCompanionForNoOpen
397
+ Ck: ()=>isDevtoolsCompanionPath,
398
+ mO: ()=>stageCompanionForSession,
399
+ xz: ()=>companionPathsForCdpLoad
357
400
  });
358
401
  },
359
402
  "./browsers/browsers-lib/constants.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
@@ -572,6 +615,10 @@ var __webpack_modules__ = {
572
615
  const steps = String(guidance || '').split('\n').map((line)=>line.trimEnd()).filter((line)=>line && !/^We couldn't find/i.test(line)).filter((line)=>!/^Re-run your command/i.test(line)).join('\n');
573
616
  return `${getLoggingPrefix('error')} ${capitalizedBrowserName(browser)} isn't installed.\n${steps}\nOr point at a binary with ${pintor__rspack_import_8_default().blue('--gecko-binary')} ${pintor__rspack_import_8_default().gray('<path>')}, or choose another browser with ${pintor__rspack_import_8_default().blue('--browser')} ${pintor__rspack_import_8_default().gray('<firefox|waterfox|librewolf|zen|floorp>')}.`;
574
617
  }
618
+ function chromiumForkNotInstalled(browser, guidance) {
619
+ const steps = String(guidance || '').split('\n').map((line)=>line.trimEnd()).filter((line)=>line && !/^We couldn't find/i.test(line)).filter((line)=>!/^Re-run your command/i.test(line)).join('\n');
620
+ return `${getLoggingPrefix('error')} ${capitalizedBrowserName(browser)} isn't installed.\n${steps}\nOr point at a binary with ${pintor__rspack_import_8_default().blue('--chromium-binary')} ${pintor__rspack_import_8_default().gray('<path>')}, or choose another browser with ${pintor__rspack_import_8_default().blue('--browser')} ${pintor__rspack_import_8_default().gray('<chrome|chromium|edge|brave|opera|vivaldi|yandex>')}.`;
621
+ }
575
622
  function usingManagedChromiumFamilyFallback(requestedBrowser, _fallbackBrowser, _binaryPath) {
576
623
  return `${getLoggingPrefix('warn')} ${managedBrowserDisplayName(requestedBrowser)} isn't installed.\nRun ${pintor__rspack_import_8_default().blue(`npx extension install ${requestedBrowser}`)} to use ${managedBrowserDisplayName(requestedBrowser)} itself.`;
577
624
  }
@@ -1018,6 +1065,7 @@ var __webpack_modules__ = {
1018
1065
  Gq: ()=>locatingBrowser,
1019
1066
  H1: ()=>safariRegenerationDiscards,
1020
1067
  HH: ()=>messageWithoutSenderError,
1068
+ I5: ()=>chromiumForkNotInstalled,
1021
1069
  Ih: ()=>browserNotInstalledError,
1022
1070
  JB: ()=>devChannelSnapshotInUse,
1023
1071
  KP: ()=>safariBuildCalled,
@@ -1553,7 +1601,7 @@ var __webpack_modules__ = {
1553
1601
  (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1554
1602
  } catch {}
1555
1603
  }
1556
- function stampReadyBrowserExited(extensionOutputPath, code) {
1604
+ function stampReadyBrowserExited(extensionOutputPath, code, signal = null) {
1557
1605
  try {
1558
1606
  if (!extensionOutputPath) return;
1559
1607
  const readyPath = readyPathFor(extensionOutputPath);
@@ -1561,10 +1609,11 @@ var __webpack_modules__ = {
1561
1609
  const ready = JSON.parse(node_fs__rspack_import_0.readFileSync(readyPath, 'utf-8'));
1562
1610
  ready.browserExitedAt = new Date().toISOString();
1563
1611
  ready.browserExitCode = code;
1612
+ ready.browserExitSignal = signal;
1564
1613
  if ('preview' === ready.command || 'start' === ready.command) {
1565
1614
  ready.status = 'error';
1566
1615
  ready.code = 'browser_exited';
1567
- ready.message = `the ${ready.browser || 'browser'} process exited (code ${code ?? 'unknown'}); nothing is running`;
1616
+ ready.message = `the ${ready.browser || 'browser'} process exited (${null == code && signal ? `signal ${signal}` : `code ${code ?? 'unknown'}`}); nothing is running`;
1568
1617
  }
1569
1618
  (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1570
1619
  } catch {}
@@ -2465,6 +2514,7 @@ var __webpack_modules__ = {
2465
2514
  var external_yandex_location_default = /*#__PURE__*/ __webpack_require__.n(external_yandex_location_namespaceObject);
2466
2515
  var messaging = __webpack_require__("./helpers/messaging.ts");
2467
2516
  var banner = __webpack_require__("./browsers/browsers-lib/banner.ts");
2517
+ var browser_family = __webpack_require__("./browsers/browsers-lib/browser-family.ts");
2468
2518
  const external_node_readline_namespaceObject = require("node:readline");
2469
2519
  var external_node_readline_default = /*#__PURE__*/ __webpack_require__.n(external_node_readline_namespaceObject);
2470
2520
  var browser_install_outcome = __webpack_require__("./helpers/browser-install-outcome.ts");
@@ -2841,6 +2891,18 @@ var __webpack_modules__ = {
2841
2891
  const edgeMasterPreferences = {
2842
2892
  ...masterPreferences
2843
2893
  };
2894
+ const forkPreferences = {
2895
+ vivaldi: {
2896
+ vivaldi: {
2897
+ startup: {
2898
+ has_seen_welcome_page: true
2899
+ }
2900
+ }
2901
+ }
2902
+ };
2903
+ function getForkPreferences(browser) {
2904
+ return forkPreferences[String(browser || '')] || {};
2905
+ }
2844
2906
  const DEFAULT_BROWSER_FLAGS = [
2845
2907
  '--no-first-run',
2846
2908
  '--disable-client-side-phishing-detection',
@@ -2886,7 +2948,8 @@ var __webpack_modules__ = {
2886
2948
  return merged;
2887
2949
  }
2888
2950
  function getChromiumMasterPreferences(browser) {
2889
- return 'edge' === browser ? edgeMasterPreferences : chromeMasterPreferences;
2951
+ const base = 'edge' === browser ? edgeMasterPreferences : chromeMasterPreferences;
2952
+ return deepMergePreferences(base, getForkPreferences(browser));
2890
2953
  }
2891
2954
  function seedChromiumPreferences(profilePath, browser, customPreferences) {
2892
2955
  const preferencesPath = external_node_path_.join(profilePath, 'Default', 'Preferences');
@@ -2959,9 +3022,10 @@ var __webpack_modules__ = {
2959
3022
  seedChromiumPreferences(userProfilePath, configOptions.browser, configOptions.preferences);
2960
3023
  } catch {}
2961
3024
  }
2962
- const extensionsForLaunch = (0, companion_session.Br)({
3025
+ const extensionsForLaunch = (0, companion_session.mO)({
2963
3026
  extensionPaths: extensionsToLoad,
2964
3027
  noOpen: configOptions.noOpen,
3028
+ browser: configOptions.browser,
2965
3029
  stageRoot: userProfilePath || void 0,
2966
3030
  provision
2967
3031
  });
@@ -3012,6 +3076,27 @@ var __webpack_modules__ = {
3012
3076
  (0, messaging._w)(messages.E8(chromiumConfig.join(' ')));
3013
3077
  }
3014
3078
  var extension_output_path = __webpack_require__("./browsers/run-chromium/chromium-launch/extension-output-path.ts");
3079
+ function chromiumForkInstallGuidance(browser) {
3080
+ const read = (fn)=>{
3081
+ try {
3082
+ return fn();
3083
+ } catch {
3084
+ return '';
3085
+ }
3086
+ };
3087
+ switch(browser){
3088
+ case 'brave':
3089
+ return read(()=>(0, external_brave_location_namespaceObject.getInstallGuidance)());
3090
+ case 'opera':
3091
+ return read(()=>(0, external_opera_location2_namespaceObject.getInstallGuidance)());
3092
+ case 'vivaldi':
3093
+ return read(()=>(0, external_vivaldi_location2_namespaceObject.getInstallGuidance)());
3094
+ case 'yandex':
3095
+ return read(()=>(0, external_yandex_location_namespaceObject.getInstallGuidance)());
3096
+ default:
3097
+ return null;
3098
+ }
3099
+ }
3015
3100
  const activeInstances = new Set();
3016
3101
  let globalHandlersInstalled = false;
3017
3102
  function cleanupOne(instance) {
@@ -3293,6 +3378,7 @@ var __webpack_modules__ = {
3293
3378
  };
3294
3379
  const isUsableBinary = (p)=>Boolean(p && external_node_fs_.existsSync(p));
3295
3380
  const resolveManagedBinary = ()=>{
3381
+ if ((0, browser_family.cA)(browser)) return null;
3296
3382
  try {
3297
3383
  const resolved = output_binaries_resolver.kI(compilation, 'chromium' === browser || 'chromium-based' === browser ? 'chromium' : 'edge' === browser ? 'edge' : 'chrome');
3298
3384
  const normalized = normalizePath(resolved || null);
@@ -3567,7 +3653,10 @@ var __webpack_modules__ = {
3567
3653
  }
3568
3654
  if (!browserBinaryLocation || !external_node_fs_.existsSync(browserBinaryLocation)) {
3569
3655
  if ('chromium' === browser || 'chromium-based' === browser) printInstallGuidance(getInstallGuidanceText('chromium'), 'chromium');
3570
- if (!printedGuidance && 'chromium' !== browser && 'chromium-based' !== browser) this.logger.error(messages.Ih(browser, browserBinaryLocation || ''));
3656
+ if (!printedGuidance && 'chromium' !== browser && 'chromium-based' !== browser) {
3657
+ const forkGuidance = chromiumForkInstallGuidance(browser);
3658
+ this.logger.error(null !== forkGuidance ? messages.I5(browser, forkGuidance) : messages.Ih(browser, browserBinaryLocation || ''));
3659
+ }
3571
3660
  if (process.env.VITEST || process.env.VITEST_WORKER_ID) throw new Error('Browser not installed or binary path not found');
3572
3661
  process.exit(1);
3573
3662
  }
@@ -3766,7 +3855,7 @@ var __webpack_modules__ = {
3766
3855
  const how = null == code ? `signal ${signal || 'unknown'}` : `code ${code}`;
3767
3856
  if (!(0, process_teardown.Op)(child)) {
3768
3857
  this.logger.error(this.closeHandlerContext?.isDevMode ? `[browser] ${this.options.browser} exited mid-session (${how}). The dev server is still running but reloads cannot be delivered, restart "extension dev" to relaunch the browser.` : `[browser] ${this.options.browser} exited (${how}); the preview session is over.`);
3769
- (0, ready_stamp.Wi)(this.closeHandlerContext?.extensionOutputPath, code);
3858
+ (0, ready_stamp.Wi)(this.closeHandlerContext?.extensionOutputPath, code, signal);
3770
3859
  }
3771
3860
  disposeSignalHandlers?.();
3772
3861
  const userDataDir = launchArgs.find((arg)=>arg.startsWith('--user-data-dir='))?.slice('--user-data-dir='.length).replace(/^"|"$/g, '');
@@ -4293,9 +4382,25 @@ var __webpack_modules__ = {
4293
4382
  'security.enterprise_roots.enabled': true,
4294
4383
  'xpinstall.signatures.required': false
4295
4384
  };
4296
- function getPreferences(customPrefs) {
4385
+ const forkPreferences = {
4386
+ zen: {
4387
+ 'zen.welcome-screen.seen': true,
4388
+ 'zen.updates.show-update-notification': false
4389
+ },
4390
+ floorp: {
4391
+ 'floorp.browser.welcome.page.shown': true,
4392
+ 'floorp.releaseNotes.mode': 'disabled',
4393
+ 'floorp.releaseNotes.choiceConfirmed': true,
4394
+ 'floorp.releaseNotes.promptShown': true
4395
+ }
4396
+ };
4397
+ function getForkPreferences(browser) {
4398
+ return forkPreferences[String(browser || '')] || {};
4399
+ }
4400
+ function getPreferences(customPrefs, browser) {
4297
4401
  return {
4298
4402
  ...masterPreferences,
4403
+ ...getForkPreferences(browser),
4299
4404
  ...customPrefs
4300
4405
  };
4301
4406
  }
@@ -4354,7 +4459,7 @@ var __webpack_modules__ = {
4354
4459
  } catch {}
4355
4460
  }
4356
4461
  if (profilePath && provision) try {
4357
- const prefs = getPreferences(configOptions?.preferences || {});
4462
+ const prefs = getPreferences(configOptions?.preferences || {}, String(browser));
4358
4463
  function serializeValue(value) {
4359
4464
  if ('string' == typeof value) return JSON.stringify(value);
4360
4465
  if ('boolean' == typeof value) return String(value);
@@ -4368,7 +4473,7 @@ var __webpack_modules__ = {
4368
4473
  const userJsContent = prefsToUserJs(prefs);
4369
4474
  external_node_fs_.writeFileSync(userJsPath, userJsContent);
4370
4475
  } catch {}
4371
- const extensionsToLoad = (0, companion_session.Br)({
4476
+ const extensionsToLoad = (0, companion_session.mO)({
4372
4477
  extensionPaths: configOptions.extension ? (0, runtime_options.fT)(configOptions.extension) : [],
4373
4478
  noOpen: configOptions.noOpen,
4374
4479
  stageRoot: profilePath || void 0,
@@ -5843,6 +5948,8 @@ var __webpack_modules__ = {
5843
5948
  (0, ready_stamp.M)(this.extensionOutputPath, {
5844
5949
  profilePath,
5845
5950
  browserPid: this.child?.pid,
5951
+ binary: this.child?.spawnfile || binary,
5952
+ binaryProvenance: this.host.launchBinaryProvenance,
5846
5953
  extensionId: this.extensionOutputPath ? (0, banner.MT)(this.extensionOutputPath) : void 0
5847
5954
  });
5848
5955
  this.wireChildLifecycle();
@@ -5879,6 +5986,8 @@ var __webpack_modules__ = {
5879
5986
  this.child = await this.spawnFirefoxChild(plan.binary, plan.args, wslFallbackBinary);
5880
5987
  (0, ready_stamp.M)(this.extensionOutputPath, {
5881
5988
  browserPid: this.child?.pid,
5989
+ binary: this.child?.spawnfile || plan.binary,
5990
+ binaryProvenance: this.host.launchBinaryProvenance,
5882
5991
  extensionId: this.extensionOutputPath ? (0, banner.MT)(this.extensionOutputPath) : void 0
5883
5992
  });
5884
5993
  this.wireChildLifecycle();
@@ -5968,7 +6077,7 @@ var __webpack_modules__ = {
5968
6077
  if ((0, messaging._o)()) this.ctx.logger?.info?.(messages.Th(this.host.browser));
5969
6078
  if (!expected) {
5970
6079
  this.ctx.logger?.error?.(`[browser] ${this.host.browser} exited (${null == code ? `signal ${signal || 'unknown'}` : `code ${code}`}) without being asked to. The add-on may have been rejected or the browser crashed; the session cannot be driven.`);
5971
- (0, ready_stamp.Wi)(this.extensionOutputPath, code);
6080
+ (0, ready_stamp.Wi)(this.extensionOutputPath, code, signal ?? null);
5972
6081
  }
5973
6082
  this.cleanupInstance().catch((err)=>{
5974
6083
  if ((0, messaging._o)()) this.ctx.logger?.error?.(`[browser] Cleanup error on child close: ${err?.message || err}`);
@@ -7029,7 +7138,7 @@ var __webpack_modules__ = {
7029
7138
  const display = browserDisplayName(browser);
7030
7139
  const line = String(versionLine || '').trim();
7031
7140
  if (!line) return display;
7032
- if (!/[a-zA-Z]/.test(line)) return `${display} ${line}`;
7141
+ if (/^v?\d+(?:\.\d+)*(?:[a-z]+\d*)?$/i.test(line)) return `${display} ${line}`;
7033
7142
  return line.charAt(0).toUpperCase() + line.slice(1);
7034
7143
  }
7035
7144
  const CARD_KEYS_ENV = 'EXTENSION_CLI_CARD_KEYS';
package/dist/cli.cjs CHANGED
@@ -284,6 +284,15 @@ var __webpack_modules__ = {
284
284
  'yandex',
285
285
  'chromium-based'
286
286
  ]);
287
+ const SYSTEM_LOCATED_CHROMIUM_FORKS = new Set([
288
+ 'brave',
289
+ 'opera',
290
+ 'vivaldi',
291
+ 'yandex'
292
+ ]);
293
+ const CDP_ONLY_EXTENSION_LOAD_BROWSERS = new Set([
294
+ 'yandex'
295
+ ]);
287
296
  const FIREFOX_BROWSERS = new Set([
288
297
  'firefox',
289
298
  'waterfox',
@@ -296,6 +305,12 @@ var __webpack_modules__ = {
296
305
  function isChromiumBrowser(browser) {
297
306
  return CHROMIUM_BROWSERS.has(String(browser));
298
307
  }
308
+ function isSystemLocatedChromiumFork(browser) {
309
+ return SYSTEM_LOCATED_CHROMIUM_FORKS.has(String(browser));
310
+ }
311
+ function loadsExtensionsOverCdpOnly(browser) {
312
+ return CDP_ONLY_EXTENSION_LOAD_BROWSERS.has(String(browser));
313
+ }
299
314
  function isFirefoxBrowser(browser) {
300
315
  return FIREFOX_BROWSERS.has(String(browser));
301
316
  }
@@ -307,25 +322,50 @@ var __webpack_modules__ = {
307
322
  }
308
323
  __webpack_require__.d(__webpack_exports__, {
309
324
  M_: ()=>isFirefoxBrowser,
325
+ cA: ()=>isSystemLocatedChromiumFork,
310
326
  eP: ()=>isEmulatorBrowser,
311
- rG: ()=>isChromiumBrowser
327
+ rG: ()=>isChromiumBrowser,
328
+ v$: ()=>loadsExtensionsOverCdpOnly
312
329
  });
313
330
  },
314
331
  "./browsers/browsers-lib/companion-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
315
332
  var node_fs__rspack_import_0 = __webpack_require__("node:fs");
316
333
  var node_path__rspack_import_1 = __webpack_require__("node:path");
317
334
  var _helpers_messaging__rspack_import_2 = __webpack_require__("./helpers/messaging.ts");
335
+ var _browser_family__rspack_import_3 = __webpack_require__("./browsers/browsers-lib/browser-family.ts");
318
336
  const COMPANION_SESSION_FLAGS_FILE = 'extension-js-session.json';
319
337
  const COMPANION_DIR_NAME = 'extension-js-devtools';
320
338
  function isDevtoolsCompanionPath(extensionPath) {
321
339
  return node_path__rspack_import_1.normalize(String(extensionPath || '')).split(/[\\/]+/).includes(COMPANION_DIR_NAME);
322
340
  }
341
+ function readManifest(extensionPath) {
342
+ try {
343
+ const parsed = JSON.parse(node_fs__rspack_import_0.readFileSync(node_path__rspack_import_1.join(extensionPath, 'manifest.json'), 'utf8'));
344
+ return parsed && 'object' == typeof parsed ? parsed : null;
345
+ } catch {
346
+ return null;
347
+ }
348
+ }
349
+ function companionPathsForCdpLoad(extensionPaths, outPath) {
350
+ return extensionPaths.filter((extensionPath)=>{
351
+ if (node_path__rspack_import_1.resolve(extensionPath) === node_path__rspack_import_1.resolve(outPath)) return false;
352
+ return !readManifest(extensionPath)?.theme;
353
+ });
354
+ }
355
+ function dropNewTabOverride(extensionPath) {
356
+ const manifestPath = node_path__rspack_import_1.join(extensionPath, 'manifest.json');
357
+ const manifest = readManifest(extensionPath);
358
+ if (!manifest || !('chrome_url_overrides' in manifest)) return;
359
+ delete manifest.chrome_url_overrides;
360
+ node_fs__rspack_import_0.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
361
+ }
323
362
  function stagedCompanionPath(stageRoot, companionPath) {
324
363
  return node_path__rspack_import_1.join(stageRoot, COMPANION_DIR_NAME, node_path__rspack_import_1.basename(companionPath));
325
364
  }
326
- function stageCompanionForNoOpen(input) {
365
+ function stageCompanionForSession(input) {
327
366
  const { extensionPaths } = input;
328
- if (!input.noOpen || !input.stageRoot) return extensionPaths;
367
+ const cdpOnly = (0, _browser_family__rspack_import_3.v$)(input.browser || '');
368
+ if (!input.noOpen && !cdpOnly || !input.stageRoot) return extensionPaths;
329
369
  const index = extensionPaths.findIndex((p)=>isDevtoolsCompanionPath(p));
330
370
  if (-1 === index) return extensionPaths;
331
371
  const source = extensionPaths[index];
@@ -340,11 +380,12 @@ var __webpack_modules__ = {
340
380
  recursive: true
341
381
  });
342
382
  const flags = {
343
- noOpen: true
383
+ noOpen: Boolean(input.noOpen)
344
384
  };
345
385
  node_fs__rspack_import_0.writeFileSync(node_path__rspack_import_1.join(staged, COMPANION_SESSION_FLAGS_FILE), `${JSON.stringify(flags)}\n`, 'utf8');
386
+ if (cdpOnly) dropNewTabOverride(staged);
346
387
  } catch (error) {
347
- if ((0, _helpers_messaging__rspack_import_2._o)()) (0, _helpers_messaging__rspack_import_2.mR)(`[browser] Could not stage the devtools companion for --no-open: ${error?.message || String(error)}`);
388
+ if ((0, _helpers_messaging__rspack_import_2._o)()) (0, _helpers_messaging__rspack_import_2.mR)(`[browser] Could not stage the devtools companion for this session: ${error?.message || String(error)}`);
348
389
  return extensionPaths;
349
390
  }
350
391
  const next = [
@@ -354,7 +395,9 @@ var __webpack_modules__ = {
354
395
  return next;
355
396
  }
356
397
  __webpack_require__.d(__webpack_exports__, {
357
- Br: ()=>stageCompanionForNoOpen
398
+ Ck: ()=>isDevtoolsCompanionPath,
399
+ mO: ()=>stageCompanionForSession,
400
+ xz: ()=>companionPathsForCdpLoad
358
401
  });
359
402
  },
360
403
  "./browsers/browsers-lib/constants.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
@@ -573,6 +616,10 @@ var __webpack_modules__ = {
573
616
  const steps = String(guidance || '').split('\n').map((line)=>line.trimEnd()).filter((line)=>line && !/^We couldn't find/i.test(line)).filter((line)=>!/^Re-run your command/i.test(line)).join('\n');
574
617
  return `${getLoggingPrefix('error')} ${capitalizedBrowserName(browser)} isn't installed.\n${steps}\nOr point at a binary with ${pintor__rspack_import_8_default().blue('--gecko-binary')} ${pintor__rspack_import_8_default().gray('<path>')}, or choose another browser with ${pintor__rspack_import_8_default().blue('--browser')} ${pintor__rspack_import_8_default().gray('<firefox|waterfox|librewolf|zen|floorp>')}.`;
575
618
  }
619
+ function chromiumForkNotInstalled(browser, guidance) {
620
+ const steps = String(guidance || '').split('\n').map((line)=>line.trimEnd()).filter((line)=>line && !/^We couldn't find/i.test(line)).filter((line)=>!/^Re-run your command/i.test(line)).join('\n');
621
+ return `${getLoggingPrefix('error')} ${capitalizedBrowserName(browser)} isn't installed.\n${steps}\nOr point at a binary with ${pintor__rspack_import_8_default().blue('--chromium-binary')} ${pintor__rspack_import_8_default().gray('<path>')}, or choose another browser with ${pintor__rspack_import_8_default().blue('--browser')} ${pintor__rspack_import_8_default().gray('<chrome|chromium|edge|brave|opera|vivaldi|yandex>')}.`;
622
+ }
576
623
  function usingManagedChromiumFamilyFallback(requestedBrowser, _fallbackBrowser, _binaryPath) {
577
624
  return `${getLoggingPrefix('warn')} ${managedBrowserDisplayName(requestedBrowser)} isn't installed.\nRun ${pintor__rspack_import_8_default().blue(`npx extension install ${requestedBrowser}`)} to use ${managedBrowserDisplayName(requestedBrowser)} itself.`;
578
625
  }
@@ -1019,6 +1066,7 @@ var __webpack_modules__ = {
1019
1066
  Gq: ()=>locatingBrowser,
1020
1067
  H1: ()=>safariRegenerationDiscards,
1021
1068
  HH: ()=>messageWithoutSenderError,
1069
+ I5: ()=>chromiumForkNotInstalled,
1022
1070
  Ih: ()=>browserNotInstalledError,
1023
1071
  JB: ()=>devChannelSnapshotInUse,
1024
1072
  KP: ()=>safariBuildCalled,
@@ -1554,7 +1602,7 @@ var __webpack_modules__ = {
1554
1602
  (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1555
1603
  } catch {}
1556
1604
  }
1557
- function stampReadyBrowserExited(extensionOutputPath, code) {
1605
+ function stampReadyBrowserExited(extensionOutputPath, code, signal = null) {
1558
1606
  try {
1559
1607
  if (!extensionOutputPath) return;
1560
1608
  const readyPath = readyPathFor(extensionOutputPath);
@@ -1562,10 +1610,11 @@ var __webpack_modules__ = {
1562
1610
  const ready = JSON.parse(node_fs__rspack_import_0.readFileSync(readyPath, 'utf-8'));
1563
1611
  ready.browserExitedAt = new Date().toISOString();
1564
1612
  ready.browserExitCode = code;
1613
+ ready.browserExitSignal = signal;
1565
1614
  if ('preview' === ready.command || 'start' === ready.command) {
1566
1615
  ready.status = 'error';
1567
1616
  ready.code = 'browser_exited';
1568
- ready.message = `the ${ready.browser || 'browser'} process exited (code ${code ?? 'unknown'}); nothing is running`;
1617
+ ready.message = `the ${ready.browser || 'browser'} process exited (${null == code && signal ? `signal ${signal}` : `code ${code ?? 'unknown'}`}); nothing is running`;
1569
1618
  }
1570
1619
  (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1571
1620
  } catch {}
@@ -2456,6 +2505,7 @@ var __webpack_modules__ = {
2456
2505
  var external_yandex_location_default = /*#__PURE__*/ __webpack_require__.n(external_yandex_location_namespaceObject);
2457
2506
  var messaging = __webpack_require__("./helpers/messaging.ts");
2458
2507
  var banner = __webpack_require__("./browsers/browsers-lib/banner.ts");
2508
+ var browser_family = __webpack_require__("./browsers/browsers-lib/browser-family.ts");
2459
2509
  const external_node_readline_namespaceObject = require("node:readline");
2460
2510
  var external_node_readline_default = /*#__PURE__*/ __webpack_require__.n(external_node_readline_namespaceObject);
2461
2511
  var browser_install_outcome = __webpack_require__("./helpers/browser-install-outcome.ts");
@@ -2832,6 +2882,18 @@ var __webpack_modules__ = {
2832
2882
  const edgeMasterPreferences = {
2833
2883
  ...masterPreferences
2834
2884
  };
2885
+ const forkPreferences = {
2886
+ vivaldi: {
2887
+ vivaldi: {
2888
+ startup: {
2889
+ has_seen_welcome_page: true
2890
+ }
2891
+ }
2892
+ }
2893
+ };
2894
+ function getForkPreferences(browser) {
2895
+ return forkPreferences[String(browser || '')] || {};
2896
+ }
2835
2897
  const DEFAULT_BROWSER_FLAGS = [
2836
2898
  '--no-first-run',
2837
2899
  '--disable-client-side-phishing-detection',
@@ -2877,7 +2939,8 @@ var __webpack_modules__ = {
2877
2939
  return merged;
2878
2940
  }
2879
2941
  function getChromiumMasterPreferences(browser) {
2880
- return 'edge' === browser ? edgeMasterPreferences : chromeMasterPreferences;
2942
+ const base = 'edge' === browser ? edgeMasterPreferences : chromeMasterPreferences;
2943
+ return deepMergePreferences(base, getForkPreferences(browser));
2881
2944
  }
2882
2945
  function seedChromiumPreferences(profilePath, browser, customPreferences) {
2883
2946
  const preferencesPath = external_node_path_.join(profilePath, 'Default', 'Preferences');
@@ -2950,9 +3013,10 @@ var __webpack_modules__ = {
2950
3013
  seedChromiumPreferences(userProfilePath, configOptions.browser, configOptions.preferences);
2951
3014
  } catch {}
2952
3015
  }
2953
- const extensionsForLaunch = (0, companion_session.Br)({
3016
+ const extensionsForLaunch = (0, companion_session.mO)({
2954
3017
  extensionPaths: extensionsToLoad,
2955
3018
  noOpen: configOptions.noOpen,
3019
+ browser: configOptions.browser,
2956
3020
  stageRoot: userProfilePath || void 0,
2957
3021
  provision
2958
3022
  });
@@ -3003,6 +3067,27 @@ var __webpack_modules__ = {
3003
3067
  (0, messaging._w)(messages.E8(chromiumConfig.join(' ')));
3004
3068
  }
3005
3069
  var extension_output_path = __webpack_require__("./browsers/run-chromium/chromium-launch/extension-output-path.ts");
3070
+ function chromiumForkInstallGuidance(browser) {
3071
+ const read = (fn)=>{
3072
+ try {
3073
+ return fn();
3074
+ } catch {
3075
+ return '';
3076
+ }
3077
+ };
3078
+ switch(browser){
3079
+ case 'brave':
3080
+ return read(()=>(0, external_brave_location_namespaceObject.getInstallGuidance)());
3081
+ case 'opera':
3082
+ return read(()=>(0, external_opera_location2_namespaceObject.getInstallGuidance)());
3083
+ case 'vivaldi':
3084
+ return read(()=>(0, external_vivaldi_location2_namespaceObject.getInstallGuidance)());
3085
+ case 'yandex':
3086
+ return read(()=>(0, external_yandex_location_namespaceObject.getInstallGuidance)());
3087
+ default:
3088
+ return null;
3089
+ }
3090
+ }
3006
3091
  const activeInstances = new Set();
3007
3092
  let globalHandlersInstalled = false;
3008
3093
  function cleanupOne(instance) {
@@ -3284,6 +3369,7 @@ var __webpack_modules__ = {
3284
3369
  };
3285
3370
  const isUsableBinary = (p)=>Boolean(p && external_node_fs_.existsSync(p));
3286
3371
  const resolveManagedBinary = ()=>{
3372
+ if ((0, browser_family.cA)(browser)) return null;
3287
3373
  try {
3288
3374
  const resolved = output_binaries_resolver.kI(compilation, 'chromium' === browser || 'chromium-based' === browser ? 'chromium' : 'edge' === browser ? 'edge' : 'chrome');
3289
3375
  const normalized = normalizePath(resolved || null);
@@ -3558,7 +3644,10 @@ var __webpack_modules__ = {
3558
3644
  }
3559
3645
  if (!browserBinaryLocation || !external_node_fs_.existsSync(browserBinaryLocation)) {
3560
3646
  if ('chromium' === browser || 'chromium-based' === browser) printInstallGuidance(getInstallGuidanceText('chromium'), 'chromium');
3561
- if (!printedGuidance && 'chromium' !== browser && 'chromium-based' !== browser) this.logger.error(messages.Ih(browser, browserBinaryLocation || ''));
3647
+ if (!printedGuidance && 'chromium' !== browser && 'chromium-based' !== browser) {
3648
+ const forkGuidance = chromiumForkInstallGuidance(browser);
3649
+ this.logger.error(null !== forkGuidance ? messages.I5(browser, forkGuidance) : messages.Ih(browser, browserBinaryLocation || ''));
3650
+ }
3562
3651
  if (process.env.VITEST || process.env.VITEST_WORKER_ID) throw new Error('Browser not installed or binary path not found');
3563
3652
  process.exit(1);
3564
3653
  }
@@ -3757,7 +3846,7 @@ var __webpack_modules__ = {
3757
3846
  const how = null == code ? `signal ${signal || 'unknown'}` : `code ${code}`;
3758
3847
  if (!(0, process_teardown.Op)(child)) {
3759
3848
  this.logger.error(this.closeHandlerContext?.isDevMode ? `[browser] ${this.options.browser} exited mid-session (${how}). The dev server is still running but reloads cannot be delivered, restart "extension dev" to relaunch the browser.` : `[browser] ${this.options.browser} exited (${how}); the preview session is over.`);
3760
- (0, ready_stamp.Wi)(this.closeHandlerContext?.extensionOutputPath, code);
3849
+ (0, ready_stamp.Wi)(this.closeHandlerContext?.extensionOutputPath, code, signal);
3761
3850
  }
3762
3851
  disposeSignalHandlers?.();
3763
3852
  const userDataDir = launchArgs.find((arg)=>arg.startsWith('--user-data-dir='))?.slice('--user-data-dir='.length).replace(/^"|"$/g, '');
@@ -4284,9 +4373,25 @@ var __webpack_modules__ = {
4284
4373
  'security.enterprise_roots.enabled': true,
4285
4374
  'xpinstall.signatures.required': false
4286
4375
  };
4287
- function getPreferences(customPrefs) {
4376
+ const forkPreferences = {
4377
+ zen: {
4378
+ 'zen.welcome-screen.seen': true,
4379
+ 'zen.updates.show-update-notification': false
4380
+ },
4381
+ floorp: {
4382
+ 'floorp.browser.welcome.page.shown': true,
4383
+ 'floorp.releaseNotes.mode': 'disabled',
4384
+ 'floorp.releaseNotes.choiceConfirmed': true,
4385
+ 'floorp.releaseNotes.promptShown': true
4386
+ }
4387
+ };
4388
+ function getForkPreferences(browser) {
4389
+ return forkPreferences[String(browser || '')] || {};
4390
+ }
4391
+ function getPreferences(customPrefs, browser) {
4288
4392
  return {
4289
4393
  ...masterPreferences,
4394
+ ...getForkPreferences(browser),
4290
4395
  ...customPrefs
4291
4396
  };
4292
4397
  }
@@ -4345,7 +4450,7 @@ var __webpack_modules__ = {
4345
4450
  } catch {}
4346
4451
  }
4347
4452
  if (profilePath && provision) try {
4348
- const prefs = getPreferences(configOptions?.preferences || {});
4453
+ const prefs = getPreferences(configOptions?.preferences || {}, String(browser));
4349
4454
  function serializeValue(value) {
4350
4455
  if ('string' == typeof value) return JSON.stringify(value);
4351
4456
  if ('boolean' == typeof value) return String(value);
@@ -4359,7 +4464,7 @@ var __webpack_modules__ = {
4359
4464
  const userJsContent = prefsToUserJs(prefs);
4360
4465
  external_node_fs_.writeFileSync(userJsPath, userJsContent);
4361
4466
  } catch {}
4362
- const extensionsToLoad = (0, companion_session.Br)({
4467
+ const extensionsToLoad = (0, companion_session.mO)({
4363
4468
  extensionPaths: configOptions.extension ? (0, runtime_options.fT)(configOptions.extension) : [],
4364
4469
  noOpen: configOptions.noOpen,
4365
4470
  stageRoot: profilePath || void 0,
@@ -5834,6 +5939,8 @@ var __webpack_modules__ = {
5834
5939
  (0, ready_stamp.M)(this.extensionOutputPath, {
5835
5940
  profilePath,
5836
5941
  browserPid: this.child?.pid,
5942
+ binary: this.child?.spawnfile || binary,
5943
+ binaryProvenance: this.host.launchBinaryProvenance,
5837
5944
  extensionId: this.extensionOutputPath ? (0, banner.MT)(this.extensionOutputPath) : void 0
5838
5945
  });
5839
5946
  this.wireChildLifecycle();
@@ -5870,6 +5977,8 @@ var __webpack_modules__ = {
5870
5977
  this.child = await this.spawnFirefoxChild(plan.binary, plan.args, wslFallbackBinary);
5871
5978
  (0, ready_stamp.M)(this.extensionOutputPath, {
5872
5979
  browserPid: this.child?.pid,
5980
+ binary: this.child?.spawnfile || plan.binary,
5981
+ binaryProvenance: this.host.launchBinaryProvenance,
5873
5982
  extensionId: this.extensionOutputPath ? (0, banner.MT)(this.extensionOutputPath) : void 0
5874
5983
  });
5875
5984
  this.wireChildLifecycle();
@@ -5959,7 +6068,7 @@ var __webpack_modules__ = {
5959
6068
  if ((0, messaging._o)()) this.ctx.logger?.info?.(messages.Th(this.host.browser));
5960
6069
  if (!expected) {
5961
6070
  this.ctx.logger?.error?.(`[browser] ${this.host.browser} exited (${null == code ? `signal ${signal || 'unknown'}` : `code ${code}`}) without being asked to. The add-on may have been rejected or the browser crashed; the session cannot be driven.`);
5962
- (0, ready_stamp.Wi)(this.extensionOutputPath, code);
6071
+ (0, ready_stamp.Wi)(this.extensionOutputPath, code, signal ?? null);
5963
6072
  }
5964
6073
  this.cleanupInstance().catch((err)=>{
5965
6074
  if ((0, messaging._o)()) this.ctx.logger?.error?.(`[browser] Cleanup error on child close: ${err?.message || err}`);
@@ -7073,7 +7182,7 @@ var __webpack_modules__ = {
7073
7182
  const display = browserDisplayName(browser);
7074
7183
  const line = String(versionLine || '').trim();
7075
7184
  if (!line) return display;
7076
- if (!/[a-zA-Z]/.test(line)) return `${display} ${line}`;
7185
+ if (/^v?\d+(?:\.\d+)*(?:[a-z]+\d*)?$/i.test(line)) return `${display} ${line}`;
7077
7186
  return line.charAt(0).toUpperCase() + line.slice(1);
7078
7187
  }
7079
7188
  const CARD_KEYS_ENV = 'EXTENSION_CLI_CARD_KEYS';
@@ -7870,7 +7979,7 @@ var __webpack_modules__ = {
7870
7979
  return Math.min(Math.max(n, min), max);
7871
7980
  }
7872
7981
  const TEMPLATE_CORPUS_REPO = 'extension-js/examples';
7873
- const TEMPLATE_CORPUS_REF = '893a06ba86125ac721ca2df71e6eec7aba123e38';
7982
+ const TEMPLATE_CORPUS_REF = '639c381c2bcf09b15fb442e22c251567dfa68c6a';
7874
7983
  const TEMPLATE_CORPUS_SLUGS = [
7875
7984
  'action',
7876
7985
  'action-locales',
@@ -8164,6 +8273,7 @@ var __webpack_modules__ = {
8164
8273
  'inspect',
8165
8274
  'install',
8166
8275
  'logs',
8276
+ 'navigate',
8167
8277
  'open',
8168
8278
  'preview',
8169
8279
  'publish',
@@ -8625,6 +8735,21 @@ var __webpack_modules__ = {
8625
8735
  description: 'Open an extension surface: popup, options, sidebar, action, or command (requires --allow-control)',
8626
8736
  supportsSourceInspection: false
8627
8737
  },
8738
+ {
8739
+ name: 'navigate',
8740
+ positionals: [
8741
+ {
8742
+ name: 'url',
8743
+ required: true
8744
+ },
8745
+ {
8746
+ name: 'project-path',
8747
+ required: false
8748
+ }
8749
+ ],
8750
+ description: 'Open a url in a tab through the extension: the active tab, --tab <id>, or a new tab with --new-tab (requires --allow-control). A static tabs call, so it works where an MV3 background refuses eval',
8751
+ supportsSourceInspection: false
8752
+ },
8628
8753
  {
8629
8754
  name: 'inspect',
8630
8755
  positionals: [
@@ -9237,6 +9362,18 @@ Cross-browser compatibility
9237
9362
  remedy
9238
9363
  ].filter(Boolean).join('\n');
9239
9364
  }
9365
+ function navigateFailed(url, reason, engine, remedy) {
9366
+ const engineNote = engine ? messages_arg(` (engine ${engine})`) : '';
9367
+ return [
9368
+ `${getLoggingPrefix('error')} Can't navigate a tab to ${messaging.Sc.val(url)}`,
9369
+ `${messaging.Sc.label('REASON')} ${messaging.Sc.val(reason)}${engineNote}`,
9370
+ remedy
9371
+ ].filter(Boolean).join('\n');
9372
+ }
9373
+ function navigatedTab(url, tabId, created) {
9374
+ const where = null == tabId ? 'a tab' : `${created ? 'new ' : ''}tab ${messaging.Sc.val(String(tabId))}`;
9375
+ return `${getLoggingPrefix('success')} Navigated ${where} to ${messaging.Sc.val(url)}`;
9376
+ }
9240
9377
  function openSurfaceGestureStep(surface) {
9241
9378
  return `Click the extension's toolbar entry, or its row in the extensions menu, to open the ${openSurfaceNoun(surface)}.`;
9242
9379
  }
@@ -9595,8 +9732,20 @@ Cross-browser compatibility
9595
9732
  needs_headed_window: messaging.Lp.E_HEADED_WINDOW_REQUIRED,
9596
9733
  needs_user_gesture: messaging.Lp.E_USER_GESTURE_REQUIRED,
9597
9734
  surface_not_open: messaging.Lp.E_TARGET_NOT_FOUND,
9598
- api_unavailable: messaging.Lp.E_NOT_IMPLEMENTED
9735
+ surface_reply_failed: messaging.Lp.E_INTERNAL,
9736
+ api_unavailable: messaging.Lp.E_NOT_IMPLEMENTED,
9737
+ url_refused: messaging.Lp.E_ARGS,
9738
+ tab_not_found: messaging.Lp.E_TARGET_NOT_FOUND
9599
9739
  };
9740
+ const URL_REFUSED_HINT_GECKO = "Firefox refuses privileged pages (about:newtab, about:config, about:addons, and chrome:, file:, data: and javascript: urls) from an extension's tabs API. Only web urls and about:blank open this way. Open the extension's own pages by their moz-extension:// url instead.";
9741
+ const URL_REFUSED_HINT_CHROMIUM = "Chromium refuses javascript: urls from an extension's tabs API. To run code in a page, use extension eval --context content --tab <id> on a session started with --allow-eval.";
9742
+ const URL_REFUSED_HINT_GENERIC = "The browser refuses this url from an extension's tabs API. Web urls and about:blank open on every engine.";
9743
+ function urlRefusedHint(engine) {
9744
+ if ('firefox' === engine) return URL_REFUSED_HINT_GECKO;
9745
+ if ('chromium' === engine) return URL_REFUSED_HINT_CHROMIUM;
9746
+ return URL_REFUSED_HINT_GENERIC;
9747
+ }
9748
+ const TAB_NOT_FOUND_HINT = "List the open tabs and their ids with extension inspect --list-tabs, or drop --tab to target the active tab.";
9600
9749
  function codeForBridgeError(name, message, refusal) {
9601
9750
  if (refusal && refusal in REFUSAL_TO_CODE) return REFUSAL_TO_CODE[refusal];
9602
9751
  if ('Timeout' === name) return messaging.Lp.E_TIMEOUT;
@@ -9605,7 +9754,7 @@ Cross-browser compatibility
9605
9754
  if ('EvalDisabled' === name || 'EvalTokenMismatch' === name || 'Forbidden' === name) return messaging.Lp.E_EVAL_REFUSED;
9606
9755
  if ('TargetNotFound' === name) return messaging.Lp.E_TARGET_NOT_FOUND;
9607
9756
  if ('BadRequest' === name) return messaging.Lp.E_ARGS;
9608
- if ('Unsupported' === name) return /needs a --tab id|is not open/i.test(message) ? messaging.Lp.E_TARGET_NOT_FOUND : messaging.Lp.E_NOT_IMPLEMENTED;
9757
+ if ('Unsupported' === name) return /needs a --tab id|is not open|no open tab matches|no active tab/i.test(message) ? messaging.Lp.E_TARGET_NOT_FOUND : messaging.Lp.E_NOT_IMPLEMENTED;
9609
9758
  if ('EvalError' === name) return messaging.Lp.E_EVAL;
9610
9759
  if ('InspectError' === name) return messaging.Lp.E_INSPECT;
9611
9760
  if ('StorageError' === name) return messaging.Lp.E_STORAGE;
@@ -9632,7 +9781,7 @@ Cross-browser compatibility
9632
9781
  const message = 'string' == typeof raw.message ? raw.message : 'command failed';
9633
9782
  const refusal = 'string' == typeof raw.code ? raw.code : void 0;
9634
9783
  const code = codeForBridgeError(name, message, refusal);
9635
- const hint = 'string' == typeof raw.hint ? raw.hint : code === messaging.Lp.E_EVAL ? 'The expression threw inside the page. Check the expression itself.' : code === messaging.Lp.E_USER_GESTURE_REQUIRED ? "The browser opens this surface only in response to a click, and refuses to open it any other way. Click the extension in the browser toolbar to open it." : void 0;
9784
+ const hint = 'string' == typeof raw.hint ? raw.hint : 'url_refused' === refusal ? urlRefusedHint(raw.engine) : 'tab_not_found' === refusal ? TAB_NOT_FOUND_HINT : code === messaging.Lp.E_EVAL ? 'The expression threw inside the page. Check the expression itself.' : code === messaging.Lp.E_USER_GESTURE_REQUIRED ? "The browser opens this surface only in response to a click, and refuses to open it any other way. Click the extension in the browser toolbar to open it." : void 0;
9636
9785
  return {
9637
9786
  ...extras,
9638
9787
  ...messaging.Pr.fail(command, statusForCode(code), {
@@ -9703,6 +9852,14 @@ Cross-browser compatibility
9703
9852
  hint: openSurfaceGestureStep(surface)
9704
9853
  };
9705
9854
  }
9855
+ function navigateResultLines(value) {
9856
+ if (!value || 'object' != typeof value) return;
9857
+ const reply = value;
9858
+ if ('string' != typeof reply.url) return;
9859
+ return [
9860
+ navigatedTab(reply.url, 'number' == typeof reply.tabId ? reply.tabId : null, true === reply.created)
9861
+ ];
9862
+ }
9706
9863
  function openResultLines(value) {
9707
9864
  if (!value || 'object' != typeof value) return;
9708
9865
  const reply = value;
@@ -9896,7 +10053,17 @@ Cross-browser compatibility
9896
10053
  output: opts.output
9897
10054
  });
9898
10055
  });
9899
- commonOptions(program.command('reload').arguments('[project-path]').description(commandDescriptions.reload).option('--context <background|content|page>', 'target context (default background)').option('--tab <id>', 'for content/page: a specific tab')).action(async (projectPathArg, opts)=>{
10056
+ commonOptions(program.command('reload').arguments('[project-path]').description(commandDescriptions.reload).option('--context <background|content|page>', 'target context (default background)').option('--url <pattern>', 'for content/page: document to target (resolved to its tab)').option('--tab <id>', 'for content/page: a specific tab (default: the --url match, else the active tab)')).action(async (projectPathArg, opts)=>{
10057
+ const context = opts.context || 'background';
10058
+ if (![
10059
+ 'background',
10060
+ 'content',
10061
+ 'page'
10062
+ ].includes(context)) fail(`reload takes --context background, content or page (got ${context}). A ${context} page reloads with the extension: run extension reload without --context.`, {
10063
+ command: 'reload',
10064
+ code: messaging.Lp.E_ARGS,
10065
+ output: opts.output
10066
+ });
9900
10067
  await runCommand({
9901
10068
  projectPathArg,
9902
10069
  command: 'reload',
@@ -9938,6 +10105,34 @@ Cross-browser compatibility
9938
10105
  } : void 0
9939
10106
  });
9940
10107
  });
10108
+ commonOptions(program.command('navigate').arguments('<url> [project-path]').description('Open a url in a tab through the extension: the active tab, --tab <id>, or a new tab with --new-tab (requires --allow-control). A static tabs call, so it works where an MV3 background refuses eval').option('--tab <id>', 'the tab to navigate (default: the active tab)').option('--new-tab', 'open the url in a new tab instead of the active one').option('--background', 'with --new-tab: open it without activating it')).action(async (url, projectPathArg, opts)=>{
10109
+ if (!/^[a-z][a-z0-9+.-]*:/i.test(url)) fail(`navigate needs an absolute url (got ${url})`, {
10110
+ command: 'navigate',
10111
+ code: messaging.Lp.E_ARGS,
10112
+ output: opts.output
10113
+ });
10114
+ const target = {
10115
+ context: 'background'
10116
+ };
10117
+ if (opts.tab) target.tabId = Number(opts.tab);
10118
+ const args = {
10119
+ url
10120
+ };
10121
+ if (opts.newTab) args.newTab = true;
10122
+ if (opts.newTab && opts.background) args.active = false;
10123
+ await runCommand({
10124
+ projectPathArg,
10125
+ command: 'navigate',
10126
+ op: 'tabs.navigate',
10127
+ target,
10128
+ args,
10129
+ opts,
10130
+ pretty: {
10131
+ value: navigateResultLines,
10132
+ failure: (error)=>navigateFailed(url, error.message, error.engine, error.hint)
10133
+ }
10134
+ });
10135
+ });
9941
10136
  commonOptions(program.command('open').arguments('<surface> [project-path]').description('Open an extension surface: popup, options, sidebar, action, or command (requires --allow-control)').option('--name <command>', 'with `open command`: the chrome.commands name to trigger')).action(async (surface, projectPathArg, opts)=>{
9942
10137
  const allowed = [
9943
10138
  'popup',
@@ -1,7 +1,11 @@
1
1
  import type { BrowserType } from '../browsers-types.js';
2
2
  export declare const CHROMIUM_BROWSERS: ReadonlySet<string>;
3
+ export declare const SYSTEM_LOCATED_CHROMIUM_FORKS: ReadonlySet<string>;
4
+ export declare const CDP_ONLY_EXTENSION_LOAD_BROWSERS: ReadonlySet<string>;
3
5
  export declare const FIREFOX_BROWSERS: ReadonlySet<string>;
4
6
  export declare function isChromiumBrowser(browser: BrowserType | string): boolean;
7
+ export declare function isSystemLocatedChromiumFork(browser: BrowserType | string): boolean;
8
+ export declare function loadsExtensionsOverCdpOnly(browser: BrowserType | string): boolean;
5
9
  export declare function isFirefoxBrowser(browser: BrowserType | string): boolean;
6
10
  export declare const EMULATOR_BROWSERS: ReadonlySet<string>;
7
11
  export declare function isEmulatorBrowser(browser: BrowserType | string): boolean;
@@ -3,10 +3,12 @@ export interface CompanionSessionFlags {
3
3
  noOpen: boolean;
4
4
  }
5
5
  export declare function isDevtoolsCompanionPath(extensionPath: string): boolean;
6
+ export declare function companionPathsForCdpLoad(extensionPaths: string[], outPath: string): string[];
6
7
  export declare function stagedCompanionPath(stageRoot: string, companionPath: string): string;
7
- export declare function stageCompanionForNoOpen(input: {
8
+ export declare function stageCompanionForSession(input: {
8
9
  extensionPaths: string[];
9
10
  noOpen?: boolean;
11
+ browser?: string;
10
12
  stageRoot?: string;
11
13
  provision?: boolean;
12
14
  }): string[];
@@ -12,6 +12,7 @@ export declare function firefoxRdpRuntimeCapabilitySummary(state: 'available' |
12
12
  export declare function skippingBrowserLaunchDueToCompileErrors(): string;
13
13
  export declare function browserNotInstalledError(browser: Browser, browserBinaryLocation: string): string;
14
14
  export declare function geckoForkNotInstalled(browser: Browser, guidance: string): string;
15
+ export declare function chromiumForkNotInstalled(browser: Browser, guidance: string): string;
15
16
  export declare function usingManagedChromiumFamilyFallback(requestedBrowser: Browser, _fallbackBrowser: Browser, _binaryPath: string): string;
16
17
  export declare function preferringSystemBrowserOverSnapshot(_systemBinary: string, _snapshotBinary: string): string;
17
18
  export declare function mv2NotSupportedByChromium(extensionPath: string): string;
@@ -16,4 +16,4 @@ export declare function stampReadyProfileLocked(extensionOutputPath: string | un
16
16
  pid: number;
17
17
  };
18
18
  }): void;
19
- export declare function stampReadyBrowserExited(extensionOutputPath: string | undefined, code: number | null): void;
19
+ export declare function stampReadyBrowserExited(extensionOutputPath: string | undefined, code: number | null, signal?: string | null): void;
@@ -8,11 +8,14 @@ interface ExtensionInfoResult {
8
8
  name?: string;
9
9
  version?: string;
10
10
  }
11
+ export declare function devtoolsCompanionWelcomeUrl(companionPath: string): string;
11
12
  export declare class CDPExtensionController {
12
13
  private readonly outPath;
14
+ private readonly browser;
13
15
  private readonly cdpPort;
14
16
  private readonly profilePath?;
15
17
  private readonly extensionPaths?;
18
+ private readonly companionPath?;
16
19
  private readonly pipeIn?;
17
20
  private readonly pipeOut?;
18
21
  private readonly logSink?;
@@ -21,10 +24,11 @@ export declare class CDPExtensionController {
21
24
  private loadRefusalReason;
22
25
  constructor(args: {
23
26
  outPath: string;
24
- browser: 'chrome' | 'edge' | 'chromium-based';
27
+ browser: string;
25
28
  cdpPort: number;
26
29
  profilePath?: string;
27
30
  extensionPaths?: string[];
31
+ companionPath?: string;
28
32
  pipeIn?: Readable;
29
33
  pipeOut?: Writable;
30
34
  logSink?: BrowserLogSink;
@@ -32,9 +36,14 @@ export declare class CDPExtensionController {
32
36
  connect(): Promise<void>;
33
37
  ensureDeveloperMode(): Promise<DeveloperModeOutcome>;
34
38
  openTab(url: string): Promise<void>;
39
+ replaceForkFirstRunTabs(browser: string, replacementUrl: string): Promise<number>;
35
40
  closeSelfOpenedTabs(): Promise<number>;
36
41
  verifyGuestLoaded(): Promise<LoadUnpackedOutcome>;
37
42
  getLoadRefusalReason(): string | null;
43
+ loadCompanions(extensionPaths: string[]): Promise<Array<{
44
+ path: string;
45
+ outcome: LoadUnpackedOutcome;
46
+ }>>;
38
47
  private waitForExtensionTarget;
39
48
  ensureLoaded(): Promise<ExtensionInfoResult>;
40
49
  private deriveExtensionIdFromTargets;
@@ -1,5 +1,6 @@
1
1
  import type { CompilationLike, DefaultBrowserFlags, PluginInterface } from '../../browsers-types.js';
2
2
  export declare const DEFAULT_BROWSER_FLAGS: DefaultBrowserFlags[];
3
+ export declare function getChromiumMasterPreferences(browser: PluginInterface['browser']): Record<string, unknown>;
3
4
  export interface BrowserConfigMode {
4
5
  provision?: boolean;
5
6
  }
@@ -0,0 +1 @@
1
+ export declare function chromiumForkInstallGuidance(browser: unknown): string | null;
@@ -160,4 +160,5 @@ declare const edgeMasterPreferences: {
160
160
  enabled: boolean;
161
161
  };
162
162
  };
163
+ export declare function getForkPreferences(browser?: string): Record<string, unknown>;
163
164
  export { chromeMasterPreferences, edgeMasterPreferences };
@@ -67,7 +67,8 @@ declare const masterPreferences: {
67
67
  'xpinstall.signatures.required': boolean;
68
68
  };
69
69
  export default masterPreferences;
70
- export declare function getPreferences(customPrefs: Record<string, unknown>): {
70
+ export declare function getForkPreferences(browser?: string): Record<string, unknown>;
71
+ export declare function getPreferences(customPrefs: Record<string, unknown>, browser?: string): {
71
72
  'browser.aboutwelcome.enabled': boolean;
72
73
  'browser.startup.homepage_override.mstone': string;
73
74
  'browser.shell.didSkipDefaultBrowserCheckOnFirstRun': boolean;
@@ -113,6 +113,17 @@ declare const COMMAND_TABLE: readonly [{
113
113
  }];
114
114
  readonly description: 'Open an extension surface: popup, options, sidebar, action, or command (requires --allow-control)';
115
115
  readonly supportsSourceInspection: false;
116
+ }, {
117
+ readonly name: 'navigate';
118
+ readonly positionals: readonly [{
119
+ readonly name: 'url';
120
+ readonly required: true;
121
+ }, {
122
+ readonly name: 'project-path';
123
+ readonly required: false;
124
+ }];
125
+ readonly description: 'Open a url in a tab through the extension: the active tab, --tab <id>, or a new tab with --new-tab (requires --allow-control). A static tabs call, so it works where an MV3 background refuses eval';
126
+ readonly supportsSourceInspection: false;
116
127
  }, {
117
128
  readonly name: 'inspect';
118
129
  readonly positionals: readonly [{
@@ -286,6 +297,8 @@ export declare function replayedActionClick(listeners: number): string;
286
297
  export declare function replayedCommand(listeners: number, command?: string): string;
287
298
  export declare function openSurfaceWarning(warning: string): string;
288
299
  export declare function openSurfaceFailed(surface: string, reason: string, engine?: string, remedy?: string): string;
300
+ export declare function navigateFailed(url: string, reason: string, engine?: string, remedy?: string): string;
301
+ export declare function navigatedTab(url: string, tabId: number | null, created: boolean): string;
289
302
  export declare function openSurfaceGestureStep(surface: string): string;
290
303
  export declare function openSurfaceNeedsGesturePlain(surface: string): string;
291
304
  export declare function openSurfaceNeedsGesture(surface: string): string;
@@ -1,5 +1,5 @@
1
1
  import { Telemetry, type TelemetrySource } from './telemetry.js';
2
- type KnownCommand = 'build' | 'capabilities' | 'create' | 'dev' | 'doctor' | 'eval' | 'inspect' | 'install' | 'logs' | 'open' | 'preview' | 'publish' | 'reload' | 'start' | 'storage' | 'telemetry' | 'uninstall' | 'unknown';
2
+ type KnownCommand = 'build' | 'capabilities' | 'create' | 'dev' | 'doctor' | 'eval' | 'inspect' | 'install' | 'logs' | 'navigate' | 'open' | 'preview' | 'publish' | 'reload' | 'start' | 'storage' | 'telemetry' | 'uninstall' | 'unknown';
3
3
  export declare const KNOWN_COMMANDS: ReadonlySet<KnownCommand>;
4
4
  export declare function detectInvokedCommand(argv: string[]): KnownCommand;
5
5
  export declare function advertisedTemplateName(value: string | undefined): string | undefined;
@@ -1,6 +1,6 @@
1
1
  export declare const DEFAULT_TEMPLATE = "typescript";
2
2
  export declare const BUNDLED_TEMPLATES: readonly string[];
3
- export declare const TEMPLATE_CATALOG_URL = "https://github.com/extension-js/examples/tree/893a06ba86125ac721ca2df71e6eec7aba123e38/examples";
3
+ export declare const TEMPLATE_CATALOG_URL = "https://github.com/extension-js/examples/tree/639c381c2bcf09b15fb442e22c251567dfa68c6a/examples";
4
4
  export interface TemplateGroup {
5
5
  title: string;
6
6
  summary: string;
@@ -1,3 +1,3 @@
1
1
  export declare const TEMPLATE_CORPUS_REPO = "extension-js/examples";
2
- export declare const TEMPLATE_CORPUS_REF = "893a06ba86125ac721ca2df71e6eec7aba123e38";
2
+ export declare const TEMPLATE_CORPUS_REF = "639c381c2bcf09b15fb442e22c251567dfa68c6a";
3
3
  export declare const TEMPLATE_CORPUS_SLUGS: readonly string[];
package/package.json CHANGED
@@ -38,7 +38,7 @@
38
38
  "extension": "./bin/extension.cjs"
39
39
  },
40
40
  "name": "extension",
41
- "version": "4.1.28",
41
+ "version": "4.1.30",
42
42
  "description": "The cross-browser extension framework. Build Chrome, Edge, Firefox, and Safari extensions with no build configuration.",
43
43
  "homepage": "https://extension.js.org/",
44
44
  "funding": "https://github.com/sponsors/cezaraugusto",
@@ -104,10 +104,10 @@
104
104
  "chromium-location": "2.1.2",
105
105
  "commander": "^15.0.0",
106
106
  "edge-location": "2.3.1",
107
- "extension-create": "4.1.28",
108
- "extension-develop": "4.1.28",
109
- "extension-install": "4.1.28",
110
- "firefox-location2": "3.1.1",
107
+ "extension-create": "4.1.30",
108
+ "extension-develop": "4.1.30",
109
+ "extension-install": "4.1.30",
110
+ "firefox-location2": "3.2.0",
111
111
  "floorp-location": "1.0.0",
112
112
  "librewolf-location": "1.2.1",
113
113
  "opera-location2": "2.1.1",