extension 4.1.20 → 4.1.22

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 (27) hide show
  1. package/README.md +18 -16
  2. package/dist/{84.cjs → 597.cjs} +80 -2
  3. package/dist/browsers.cjs +408 -103
  4. package/dist/cli.cjs +558 -148
  5. package/dist/extension/browsers/__spec__/safari-fake-tools.d.ts +27 -0
  6. package/dist/extension/browsers/browsers-lib/messages.d.ts +2 -1
  7. package/dist/extension/browsers/browsers-lib/process-teardown.d.ts +3 -0
  8. package/dist/extension/browsers/browsers-lib/ready-stamp.d.ts +1 -0
  9. package/dist/extension/browsers/browsers-lib/resolve-live-pid.d.ts +25 -0
  10. package/dist/extension/browsers/browsers-lib/write-json-atomic.d.ts +1 -0
  11. package/dist/extension/browsers/browsers-types.d.ts +1 -1
  12. package/dist/extension/browsers/index.d.ts +1 -1
  13. package/dist/extension/browsers/run-chromium/cdp/cdp-extension-controller/index.d.ts +2 -0
  14. package/dist/extension/browsers/run-chromium/cdp/ensure-developer-mode.d.ts +12 -0
  15. package/dist/extension/browsers/run-firefox/firefox-launch/index.d.ts +9 -0
  16. package/dist/extension/browsers/run-firefox/firefox-launch/process-handlers.d.ts +1 -1
  17. package/dist/extension/browsers/run-safari/safari-launch/index.d.ts +1 -1
  18. package/dist/extension/browsers/run-safari/safari-launch/tools.d.ts +17 -0
  19. package/dist/extension/browsers/run-safari/safari-packager.d.ts +2 -1
  20. package/dist/extension/browsers/run-safari/safari-types.d.ts +2 -0
  21. package/dist/extension/config-types.d.ts +5 -2
  22. package/dist/extension/helpers/messages.d.ts +7 -0
  23. package/dist/extension/helpers/messaging.d.ts +1 -0
  24. package/dist/extension/helpers/node-version-guard.d.ts +3 -1
  25. package/dist/extension/helpers/template-catalog.d.ts +1 -1
  26. package/dist/extension/helpers/template-corpus.generated.d.ts +1 -1
  27. package/package.json +5 -7
package/dist/browsers.cjs CHANGED
@@ -229,7 +229,7 @@ var __webpack_modules__ = {
229
229
  (0, _helpers_messaging__rspack_import_3._w)(_messages__rspack_import_5.io());
230
230
  }
231
231
  } catch {
232
- const provenanceNote = _messages__rspack_import_5.xX(opts.binaryProvenance);
232
+ const provenanceNote = _messages__rspack_import_5.xX(opts.binaryProvenance, opts.browser);
233
233
  (0, _helpers_messaging__rspack_import_3._w)(_messages__rspack_import_5.io());
234
234
  (0, _helpers_messaging__rspack_import_3._w)((0, _helpers_messaging__rspack_import_3.Nr)({
235
235
  rows: [
@@ -420,6 +420,7 @@ var __webpack_modules__ = {
420
420
  var pintor__rspack_import_8 = __webpack_require__("pintor");
421
421
  var pintor__rspack_import_8_default = /*#__PURE__*/ __webpack_require__.n(pintor__rspack_import_8);
422
422
  var _helpers_messaging__rspack_import_9 = __webpack_require__("./helpers/messaging.ts");
423
+ var _browser_family__rspack_import_10 = __webpack_require__("./browsers/browsers-lib/browser-family.ts");
423
424
  const require1 = (0, node_module__rspack_import_1.createRequire)(__rslib_import_meta_url__);
424
425
  function getLoggingPrefix(type) {
425
426
  return (0, _helpers_messaging__rspack_import_9.Pl)(type);
@@ -749,7 +750,7 @@ var __webpack_modules__ = {
749
750
  return `${getLoggingPrefix('warn')} safari-web-extension-converter reported ${pintor__rspack_import_8_default().yellow(String(warnings.length))} ${1 === warnings.length ? 'warning' : 'warnings'}, some manifest keys/APIs may not be supported by Safari:\n` + warnings.map((line)=>` ${pintor__rspack_import_8_default().gray('•')} ${line}`).join('\n') + (kept.length ? `\nExtension.js kept ${1 === kept.length ? 'one of these keys' : 'some of these keys'} on purpose:\n${keptLines}` : '');
750
751
  }
751
752
  function safariDefaultBundleIdNote(bundleId) {
752
- return `${getLoggingPrefix('warn')} The bundle id ${pintor__rspack_import_8_default().gray(bundleId)} is generated from the app name.\nEvery project built from the same source shares this id, and the first team to register it takes it.\nSet your own with ${pintor__rspack_import_8_default().blue('--bundle-id')} before your first submission.\nAfter a submission, a new id is a new extension with none of your users.`;
753
+ return `${getLoggingPrefix('info')} Bundle id ${pintor__rspack_import_8_default().gray(bundleId)} (generated, set ${pintor__rspack_import_8_default().blue('--bundle-id')} to own it).`;
753
754
  }
754
755
  function safariOpenHint(appPath, appName) {
755
756
  return `${getLoggingPrefix('info')} Launch it once to register with Safari: ${pintor__rspack_import_8_default().blue('open')} ${pintor__rspack_import_8_default().underline(`"${appPath}"`)}\nThen turn on ${pintor__rspack_import_8_default().yellow(appName)} in Safari ▸ Settings ▸ Extensions.`;
@@ -771,6 +772,9 @@ var __webpack_modules__ = {
771
772
  function safariRegistered(appName) {
772
773
  return `${getLoggingPrefix('success')} Safari recognizes ${pintor__rspack_import_8_default().yellow(appName)}, finish enabling it with the steps above.`;
773
774
  }
775
+ function safariPidUnresolved(appName) {
776
+ return `${getLoggingPrefix('warn')} Opened ${pintor__rspack_import_8_default().yellow(appName)} but could not find its process id.\nThe session's ready.json names the app and the extension without a ${pintor__rspack_import_8_default().gray('browserPid')}.`;
777
+ }
774
778
  function safariNotYetRegistered(appName) {
775
779
  return `${getLoggingPrefix('info')} Safari hasn't picked up ${pintor__rspack_import_8_default().yellow(appName)} yet.\nOpen the app once, then check Safari ▸ Settings ▸ Extensions.`;
776
780
  }
@@ -825,9 +829,15 @@ var __webpack_modules__ = {
825
829
  if (rest.startsWith(node_path__rspack_import_3.sep) || rest.startsWith('/')) return `~${rest}`;
826
830
  return raw;
827
831
  }
828
- function binaryProvenanceNote(provenance) {
829
- if ('pinned' === provenance) return '(pinned with --chromium-binary)';
830
- return '';
832
+ function binaryProvenanceNote(provenance, browser) {
833
+ if ('pinned' !== provenance) return '';
834
+ return `(pinned with ${pinnedBinaryFlag(browser)})`;
835
+ }
836
+ function pinnedBinaryFlag(browser) {
837
+ const name = String(browser || '');
838
+ if ((0, _browser_family__rspack_import_10.M_)(name)) return '--gecko-binary';
839
+ if ('safari' === name || 'webkit-based' === name) return '--safari-binary';
840
+ return '--chromium-binary';
831
841
  }
832
842
  function runningInDevelopment(manifest, browser, message, browserVersionLine, updateSuffix, opts) {
833
843
  const capitalize = (str)=>str.charAt(0).toUpperCase() + str.slice(1);
@@ -863,7 +873,7 @@ var __webpack_modules__ = {
863
873
  const baseBrowserLabel = (0, _helpers_messaging__rspack_import_9.A6)(String(browser || 'unknown'), resolveBrowserVersionLine(browser, browserVersionLine, {
864
874
  pinned: opts?.binaryProvenance === 'pinned'
865
875
  }));
866
- const provenanceNote = binaryProvenanceNote(opts?.binaryProvenance);
876
+ const provenanceNote = binaryProvenanceNote(opts?.binaryProvenance, browser);
867
877
  const browserLabel = provenanceNote ? `${baseBrowserLabel} ${provenanceNote}` : baseBrowserLabel;
868
878
  const cleanId = String(id || '').trim();
869
879
  const includeExtensionId = opts?.includeExtensionId !== false;
@@ -1032,6 +1042,7 @@ var __webpack_modules__ = {
1032
1042
  jR: ()=>safariBuilding,
1033
1043
  jc: ()=>safariProjectStale,
1034
1044
  jk: ()=>requireGeckoBinaryForGeckoBased,
1045
+ jn: ()=>safariPidUnresolved,
1035
1046
  kK: ()=>preferringSystemBrowserOverSnapshot,
1036
1047
  l9: ()=>parsingPacketError,
1037
1048
  lO: ()=>firefoxDryRunArgs,
@@ -1321,17 +1332,21 @@ var __webpack_modules__ = {
1321
1332
  var _messages__rspack_import_2 = __webpack_require__("./browsers/browsers-lib/messages.ts");
1322
1333
  const FORCE_KILL_GRACE_MS = 5000;
1323
1334
  const terminatedByUs = new WeakSet();
1335
+ const terminatedPids = new Set();
1324
1336
  function wasTerminatedByUs(child) {
1325
1337
  return !!child && terminatedByUs.has(child);
1326
1338
  }
1339
+ function wasPidTerminatedByUs(pid) {
1340
+ return 'number' == typeof pid && terminatedPids.has(pid);
1341
+ }
1327
1342
  function authorLog(line) {
1328
1343
  if (line && (0, _helpers_messaging__rspack_import_1._o)()) (0, _helpers_messaging__rspack_import_1._w)(line);
1329
1344
  }
1330
- function killWindowsTree(child, sync) {
1331
- if ('win32' !== process.platform) return;
1345
+ function killWindowsTree(pid, sync) {
1346
+ if ('win32' !== process.platform || !pid) return;
1332
1347
  const args = [
1333
1348
  '/PID',
1334
- String(child.pid),
1349
+ String(pid),
1335
1350
  '/T',
1336
1351
  '/F'
1337
1352
  ];
@@ -1346,10 +1361,37 @@ var __webpack_modules__ = {
1346
1361
  }).on('error', ()=>{});
1347
1362
  } catch {}
1348
1363
  }
1364
+ function signalPid(pid, signal) {
1365
+ try {
1366
+ process.kill(pid, signal);
1367
+ return true;
1368
+ } catch {
1369
+ return false;
1370
+ }
1371
+ }
1372
+ function gracefulTerminatePid(pid, browser) {
1373
+ if (!pid || terminatedPids.has(pid)) return;
1374
+ terminatedPids.add(pid);
1375
+ killWindowsTree(pid, false);
1376
+ authorLog(_messages__rspack_import_2.XH(browser));
1377
+ signalPid(pid, 'SIGTERM');
1378
+ const killTimer = setTimeout(()=>{
1379
+ authorLog(_messages__rspack_import_2.AG(browser));
1380
+ signalPid(pid, 'SIGKILL');
1381
+ }, FORCE_KILL_GRACE_MS);
1382
+ killTimer.unref?.();
1383
+ }
1384
+ function forceKillPidOnExit(pid, browser) {
1385
+ if (!pid) return;
1386
+ terminatedPids.add(pid);
1387
+ killWindowsTree(pid, true);
1388
+ authorLog(_messages__rspack_import_2.AG(browser));
1389
+ signalPid(pid, 'SIGKILL');
1390
+ }
1349
1391
  function gracefulTerminateChild(child, browser) {
1350
1392
  if (!child || child.killed) return;
1351
1393
  terminatedByUs.add(child);
1352
- killWindowsTree(child, false);
1394
+ killWindowsTree(child.pid, false);
1353
1395
  authorLog(_messages__rspack_import_2.XH(browser));
1354
1396
  child.kill('SIGTERM');
1355
1397
  const killTimer = setTimeout(()=>{
@@ -1363,7 +1405,7 @@ var __webpack_modules__ = {
1363
1405
  function forceKillChildOnExit(child, browser) {
1364
1406
  if (!child) return;
1365
1407
  terminatedByUs.add(child);
1366
- killWindowsTree(child, true);
1408
+ killWindowsTree(child.pid, true);
1367
1409
  try {
1368
1410
  authorLog(_messages__rspack_import_2.AG(browser));
1369
1411
  child.kill('SIGKILL');
@@ -1384,7 +1426,10 @@ var __webpack_modules__ = {
1384
1426
  $Y: ()=>forceKillChildOnExit,
1385
1427
  Df: ()=>gracefulTerminateChild,
1386
1428
  FA: ()=>isBenignSocketTeardown,
1387
- Op: ()=>wasTerminatedByUs
1429
+ Op: ()=>wasTerminatedByUs,
1430
+ PU: ()=>wasPidTerminatedByUs,
1431
+ Qx: ()=>forceKillPidOnExit,
1432
+ _T: ()=>gracefulTerminatePid
1388
1433
  });
1389
1434
  },
1390
1435
  "./browsers/browsers-lib/ready-message.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
@@ -1404,6 +1449,7 @@ var __webpack_modules__ = {
1404
1449
  "./browsers/browsers-lib/ready-stamp.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1405
1450
  var node_fs__rspack_import_0 = __webpack_require__("node:fs");
1406
1451
  var node_path__rspack_import_1 = __webpack_require__("node:path");
1452
+ var _write_json_atomic__rspack_import_2 = __webpack_require__("./browsers/browsers-lib/write-json-atomic.ts");
1407
1453
  function readyPathFor(extensionOutputPath) {
1408
1454
  return node_path__rspack_import_1.join(node_path__rspack_import_1.dirname(extensionOutputPath), 'extension-js', node_path__rspack_import_1.basename(extensionOutputPath), 'ready.json');
1409
1455
  }
@@ -1415,7 +1461,7 @@ var __webpack_modules__ = {
1415
1461
  const ready = JSON.parse(node_fs__rspack_import_0.readFileSync(readyPath, 'utf-8'));
1416
1462
  if (ready.rdpPort === rdpPort) return;
1417
1463
  ready.rdpPort = rdpPort;
1418
- node_fs__rspack_import_0.writeFileSync(readyPath, JSON.stringify(ready, null, 2));
1464
+ (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1419
1465
  } catch {}
1420
1466
  }
1421
1467
  function stampReadyBrowserLaunch(extensionOutputPath, details) {
@@ -1427,13 +1473,14 @@ var __webpack_modules__ = {
1427
1473
  const profilePath = String(details?.profilePath || '').trim();
1428
1474
  if (profilePath) ready.profilePath = profilePath;
1429
1475
  if ('number' == typeof details?.browserPid && Number.isFinite(details.browserPid)) ready.browserPid = details.browserPid;
1476
+ if ('number' == typeof details?.launcherPid && Number.isFinite(details.launcherPid)) ready.launcherPid = details.launcherPid;
1430
1477
  const extensionId = String(details?.extensionId || '').trim();
1431
1478
  if (extensionId) ready.extensionId = extensionId;
1432
1479
  const binary = String(details?.binary || '').trim();
1433
1480
  if (binary) ready.binary = binary;
1434
1481
  const provenance = String(details?.binaryProvenance || '').trim();
1435
1482
  if (provenance) ready.binaryProvenance = provenance;
1436
- node_fs__rspack_import_0.writeFileSync(readyPath, JSON.stringify(ready, null, 2));
1483
+ (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1437
1484
  } catch {}
1438
1485
  }
1439
1486
  function stampReadyExtensionId(extensionOutputPath, extensionId) {
@@ -1445,7 +1492,7 @@ var __webpack_modules__ = {
1445
1492
  const ready = JSON.parse(node_fs__rspack_import_0.readFileSync(readyPath, 'utf-8'));
1446
1493
  if (ready.extensionId === id) return;
1447
1494
  ready.extensionId = id;
1448
- node_fs__rspack_import_0.writeFileSync(readyPath, JSON.stringify(ready, null, 2));
1495
+ (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1449
1496
  } catch {}
1450
1497
  }
1451
1498
  function stampReadyExtensionLoadRefused(extensionOutputPath, reason) {
@@ -1460,7 +1507,7 @@ var __webpack_modules__ = {
1460
1507
  ready.message = `${browserLabel.charAt(0).toUpperCase() + browserLabel.slice(1)} refused to load the extension at ${extensionOutputPath}${reason ? `: ${reason}` : ''}`;
1461
1508
  ready.extensionLoadRefusedAt = new Date().toISOString();
1462
1509
  if (reason) ready.extensionLoadRefusedReason = reason;
1463
- node_fs__rspack_import_0.writeFileSync(readyPath, JSON.stringify(ready, null, 2));
1510
+ (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1464
1511
  } catch {}
1465
1512
  }
1466
1513
  function stampReadyProfileLocked(extensionOutputPath, details) {
@@ -1474,7 +1521,7 @@ var __webpack_modules__ = {
1474
1521
  ready.message = String(details?.message || '').trim() || 'the browser profile is already in use by another session';
1475
1522
  ready.profileLockedAt = new Date().toISOString();
1476
1523
  if (details?.owner) ready.profileLockOwner = details.owner;
1477
- node_fs__rspack_import_0.writeFileSync(readyPath, JSON.stringify(ready, null, 2));
1524
+ (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1478
1525
  } catch {}
1479
1526
  }
1480
1527
  function stampReadyBrowserExited(extensionOutputPath, code) {
@@ -1490,7 +1537,7 @@ var __webpack_modules__ = {
1490
1537
  ready.code = 'browser_exited';
1491
1538
  ready.message = `the ${ready.browser || 'browser'} process exited (code ${code ?? 'unknown'}); nothing is running`;
1492
1539
  }
1493
- node_fs__rspack_import_0.writeFileSync(readyPath, JSON.stringify(ready, null, 2));
1540
+ (0, _write_json_atomic__rspack_import_2.Z)(readyPath, ready);
1494
1541
  } catch {}
1495
1542
  }
1496
1543
  __webpack_require__.d(__webpack_exports__, {
@@ -1953,6 +2000,27 @@ var __webpack_modules__ = {
1953
2000
  yO: ()=>probeChromiumBinaryVersion
1954
2001
  });
1955
2002
  },
2003
+ "./browsers/browsers-lib/write-json-atomic.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
2004
+ var node_fs__rspack_import_0 = __webpack_require__("node:fs");
2005
+ function writeJsonAtomic(filePath, value) {
2006
+ const tmpPath = `${filePath}.tmp-${process.pid}`;
2007
+ try {
2008
+ node_fs__rspack_import_0.writeFileSync(tmpPath, JSON.stringify(value, null, 2), 'utf-8');
2009
+ node_fs__rspack_import_0.renameSync(tmpPath, filePath);
2010
+ return true;
2011
+ } catch {
2012
+ try {
2013
+ node_fs__rspack_import_0.rmSync(tmpPath, {
2014
+ force: true
2015
+ });
2016
+ } catch {}
2017
+ return false;
2018
+ }
2019
+ }
2020
+ __webpack_require__.d(__webpack_exports__, {
2021
+ Z: ()=>writeJsonAtomic
2022
+ });
2023
+ },
1956
2024
  "./browsers/browsers-lib/wsl-support.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1957
2025
  __webpack_require__.d(__webpack_exports__, {
1958
2026
  qc: ()=>external_wsl_support_namespaceObject.hasGuiDisplay,
@@ -2669,6 +2737,7 @@ var __webpack_modules__ = {
2669
2737
  '--enable-features=SidePanelUpdates',
2670
2738
  '--disable-features=DisableLoadExtensionCommandLineSwitch',
2671
2739
  '--disable-features=ExtensionDisableUnsupportedDeveloper',
2740
+ '--disable-features=SafetyHubExtensionsOffStoreTrigger',
2672
2741
  '--enable-unsafe-extension-debugging',
2673
2742
  '--silent-debugger-extension-api'
2674
2743
  ];
@@ -3497,7 +3566,7 @@ var __webpack_modules__ = {
3497
3566
  binaryProvenance
3498
3567
  };
3499
3568
  if (enableCdp) {
3500
- const mod = await __webpack_require__.e(84).then(__webpack_require__.bind(__webpack_require__, "./browsers/run-chromium/chromium-launch/setup-cdp-after-launch.ts"));
3569
+ const mod = await __webpack_require__.e(597).then(__webpack_require__.bind(__webpack_require__, "./browsers/run-chromium/chromium-launch/setup-cdp-after-launch.ts"));
3501
3570
  const CDP_SETUP_TIMEOUT_MS = 45000;
3502
3571
  await Promise.race([
3503
3572
  mod.setupCdpAfterLaunch(compilation, cdpConfig, chromiumConfig, pipeStreams),
@@ -3788,6 +3857,150 @@ var __webpack_modules__ = {
3788
3857
  var process_teardown = __webpack_require__("./browsers/browsers-lib/process-teardown.ts");
3789
3858
  var ready_message = __webpack_require__("./browsers/browsers-lib/ready-message.ts");
3790
3859
  var ready_stamp = __webpack_require__("./browsers/browsers-lib/ready-stamp.ts");
3860
+ var external_node_child_process_ = __webpack_require__("node:child_process");
3861
+ const PS_ROW = /^\s*(\d+)\s+(\d+)\s+(.*)$/;
3862
+ const HELPER_PROCESS = /plugin-container|(^|\s)-contentproc(\s|$)|(^|\s)-childID(\s|$)|--type=/;
3863
+ function runQuiet(bin, args) {
3864
+ try {
3865
+ const result = (0, external_node_child_process_.spawnSync)(bin, args, {
3866
+ encoding: 'utf-8',
3867
+ stdio: [
3868
+ 'ignore',
3869
+ 'pipe',
3870
+ 'ignore'
3871
+ ],
3872
+ windowsHide: true,
3873
+ maxBuffer: 67108864
3874
+ });
3875
+ if (result.error || 0 !== result.status) return null;
3876
+ return String(result.stdout || '');
3877
+ } catch {
3878
+ return null;
3879
+ }
3880
+ }
3881
+ function parseProcessRows(output) {
3882
+ const rows = [];
3883
+ for (const line of String(output || '').split(/\r?\n/)){
3884
+ const match = PS_ROW.exec(line.replace(/\r$/, ''));
3885
+ if (!match) continue;
3886
+ const pid = Number(match[1]);
3887
+ const ppid = Number(match[2]);
3888
+ if (Number.isFinite(pid) && Number.isFinite(ppid)) rows.push({
3889
+ pid,
3890
+ ppid,
3891
+ command: match[3].trim()
3892
+ });
3893
+ }
3894
+ return rows;
3895
+ }
3896
+ function appendLinuxProfileEnv(rows) {
3897
+ return rows.map((row)=>{
3898
+ try {
3899
+ const environ = external_node_fs_.readFileSync(`/proc/${row.pid}/environ`, 'utf-8');
3900
+ const entry = environ.split('\0').find((pair)=>pair.startsWith('XRE_PROFILE_PATH='));
3901
+ return entry ? {
3902
+ ...row,
3903
+ command: `${row.command} ${entry}`
3904
+ } : row;
3905
+ } catch {
3906
+ return row;
3907
+ }
3908
+ });
3909
+ }
3910
+ function listProcesses(platform = process.platform) {
3911
+ if ('win32' === platform) {
3912
+ const script = 'Get-CimInstance Win32_Process | ForEach-Object { "$($_.ProcessId) $($_.ParentProcessId) $($_.CommandLine)" }';
3913
+ const output = runQuiet('powershell.exe', [
3914
+ '-NoProfile',
3915
+ '-NonInteractive',
3916
+ '-Command',
3917
+ script
3918
+ ]);
3919
+ return output ? parseProcessRows(output) : [];
3920
+ }
3921
+ if ('darwin' === platform) {
3922
+ const output = runQuiet('ps', [
3923
+ '-axEo',
3924
+ 'pid=,ppid=,command='
3925
+ ]);
3926
+ return output ? parseProcessRows(output) : [];
3927
+ }
3928
+ const output = runQuiet('ps', [
3929
+ '-axo',
3930
+ 'pid=,ppid=,command='
3931
+ ]);
3932
+ const rows = output ? parseProcessRows(output) : [];
3933
+ return 'linux' === platform ? appendLinuxProfileEnv(rows) : rows;
3934
+ }
3935
+ function resolve_live_pid_normalizePath(value) {
3936
+ return String(value || '').replace(/\\/g, '/').toLowerCase();
3937
+ }
3938
+ function carriesProfile(command, profilePath) {
3939
+ const haystack = resolve_live_pid_normalizePath(command);
3940
+ const needle = resolve_live_pid_normalizePath(profilePath);
3941
+ let from = 0;
3942
+ for(;;){
3943
+ const at = haystack.indexOf(needle, from);
3944
+ if (at < 0) return false;
3945
+ const before = 0 === at ? ' ' : haystack[at - 1];
3946
+ const after = haystack[at + needle.length] ?? ' ';
3947
+ if (/[\s="']/.test(before) && /[\s"']/.test(after)) return true;
3948
+ from = at + 1;
3949
+ }
3950
+ }
3951
+ function executableOf(command) {
3952
+ const trimmed = resolve_live_pid_normalizePath(command).trim();
3953
+ if (trimmed.startsWith('"')) {
3954
+ const end = trimmed.indexOf('"', 1);
3955
+ return end > 0 ? trimmed.slice(1, end) : trimmed;
3956
+ }
3957
+ const cut = trimmed.search(/\s(-|[a-z_][a-z0-9_]*=)/);
3958
+ return cut > 0 ? trimmed.slice(0, cut) : trimmed;
3959
+ }
3960
+ function findLiveBrowserPid(input) {
3961
+ const profilePath = String(input.profilePath || '').trim();
3962
+ const binary = resolve_live_pid_normalizePath(input.binary).trim();
3963
+ if (!profilePath || !binary) return null;
3964
+ const candidates = input.rows.filter((row)=>executableOf(row.command) === binary && carriesProfile(row.command, profilePath) && !HELPER_PROCESS.test(row.command));
3965
+ if (0 === candidates.length) return null;
3966
+ const launcher = input.launcherPid ? candidates.find((row)=>row.pid === input.launcherPid) : void 0;
3967
+ if (launcher) {
3968
+ const twin = candidates.find((row)=>row.pid !== launcher.pid);
3969
+ return twin ? twin.pid : launcher.pid;
3970
+ }
3971
+ const pids = new Set(candidates.map((row)=>row.pid));
3972
+ const roots = candidates.filter((row)=>!pids.has(row.ppid));
3973
+ return (roots[0] || candidates[0]).pid;
3974
+ }
3975
+ function isPidAlive(pid) {
3976
+ if (!pid || !Number.isFinite(pid)) return false;
3977
+ try {
3978
+ process.kill(pid, 0);
3979
+ return true;
3980
+ } catch (error) {
3981
+ return error?.code === 'EPERM';
3982
+ }
3983
+ }
3984
+ async function resolveLiveBrowserPid(input) {
3985
+ const list = input.list || listProcesses;
3986
+ const attempts = Math.max(1, input.attempts ?? 6);
3987
+ const intervalMs = input.intervalMs ?? 500;
3988
+ const sleep = input.sleep || ((ms)=>new Promise((r)=>{
3989
+ setTimeout(r, ms).unref?.();
3990
+ }));
3991
+ let last = null;
3992
+ for(let attempt = 0; attempt < attempts; attempt += 1){
3993
+ last = findLiveBrowserPid({
3994
+ profilePath: input.profilePath,
3995
+ binary: input.binary,
3996
+ launcherPid: input.launcherPid,
3997
+ rows: list()
3998
+ });
3999
+ if (last && last !== input.launcherPid) break;
4000
+ if (attempt < attempts - 1) await sleep(intervalMs);
4001
+ }
4002
+ return last;
4003
+ }
3791
4004
  var runtime_options = __webpack_require__("./browsers/browsers-lib/runtime-options.ts");
3792
4005
  var shared_utils = __webpack_require__("./browsers/browsers-lib/shared-utils.ts");
3793
4006
  function parseFlatpakBinary(binary) {
@@ -4065,7 +4278,12 @@ var __webpack_modules__ = {
4065
4278
  for (const instance of activeInstances)attemptCleanup(instance);
4066
4279
  }
4067
4280
  function forceKillAllOnExit() {
4068
- for (const instance of activeInstances)(0, process_teardown.$Y)(instance.childRef(), instance.browser);
4281
+ for (const instance of activeInstances){
4282
+ const child = instance.childRef();
4283
+ const livePid = instance.livePidRef();
4284
+ (0, process_teardown.$Y)(child, instance.browser);
4285
+ if (livePid && livePid !== child?.pid) (0, process_teardown.Qx)(livePid, instance.browser);
4286
+ }
4069
4287
  }
4070
4288
  function firstBrowserLabel() {
4071
4289
  for (const instance of activeInstances)return instance.browser;
@@ -4097,10 +4315,11 @@ var __webpack_modules__ = {
4097
4315
  process.exit(1);
4098
4316
  });
4099
4317
  }
4100
- function setupFirefoxProcessHandlers(browser, childRef, cleanupInstance) {
4318
+ function setupFirefoxProcessHandlers(browser, childRef, cleanupInstance, livePidRef = ()=>null) {
4101
4319
  const instance = {
4102
4320
  browser,
4103
4321
  childRef,
4322
+ livePidRef,
4104
4323
  cleanupInstance,
4105
4324
  isCleaningUp: false
4106
4325
  };
@@ -5186,7 +5405,6 @@ var __webpack_modules__ = {
5186
5405
  } catch {}
5187
5406
  return controller;
5188
5407
  }
5189
- var external_node_child_process_ = __webpack_require__("node:child_process");
5190
5408
  var wsl_support = __webpack_require__("./browsers/browsers-lib/wsl-support.ts");
5191
5409
  const LINUX_FIREFOX_PATHS = [
5192
5410
  '/usr/bin/firefox',
@@ -5456,13 +5674,12 @@ var __webpack_modules__ = {
5456
5674
  browserPid: this.child?.pid,
5457
5675
  extensionId: this.extensionOutputPath ? (0, banner.MT)(this.extensionOutputPath) : void 0
5458
5676
  });
5459
- this.child.on('close', ()=>{
5460
- (0, shared_utils.sW)(profilePath);
5461
- });
5462
5677
  this.wireChildLifecycle();
5678
+ this.trackLiveBrowserPid();
5463
5679
  let ctrl;
5464
5680
  try {
5465
5681
  ctrl = await setupRdpAfterLaunch(this.host, compilation, debugPort);
5682
+ this.trackLiveBrowserPid(1);
5466
5683
  } catch (error) {
5467
5684
  const reason = error?.extensionLoadRefusedReason;
5468
5685
  if (!reason) {
@@ -5557,24 +5774,89 @@ var __webpack_modules__ = {
5557
5774
  if (process.env.VITEST || process.env.VITEST_WORKER_ID) throw new Error('Firefox startup timed out');
5558
5775
  process.exit(1);
5559
5776
  });
5560
- let disposeProcessHandlers;
5561
5777
  child.on('close', (code)=>{
5562
- if (this.watchTimeout) {
5563
- clearTimeout(this.watchTimeout);
5564
- this.watchTimeout = void 0;
5565
- }
5566
- if ((0, messaging._o)()) this.ctx.logger?.info?.(messages.Th(this.host.browser));
5567
- if (!(0, process_teardown.Op)(child)) {
5568
- this.ctx.logger?.error?.(`[browser] ${this.host.browser} exited (code ${code ?? 'unknown'}) without being asked to. The add-on may have been rejected or the browser crashed; the session cannot be driven.`);
5569
- (0, ready_stamp.Wi)(this.extensionOutputPath, code);
5570
- }
5571
- this.cleanupInstance().catch((err)=>{
5572
- if ((0, messaging._o)()) this.ctx.logger?.error?.(`[browser] Cleanup error on child close: ${err?.message || err}`);
5573
- });
5574
- disposeProcessHandlers?.();
5778
+ const expected = (0, process_teardown.Op)(child);
5779
+ if (!expected && this.adoptHandedOffBrowser()) return;
5780
+ this.onBrowserGone(code, expected);
5575
5781
  });
5576
5782
  this.pipeChildOutput(child);
5577
- disposeProcessHandlers = setupFirefoxProcessHandlers(this.host.browser, ()=>this.child, ()=>this.cleanupInstance());
5783
+ this.disposeProcessHandlers = setupFirefoxProcessHandlers(this.host.browser, ()=>this.child, ()=>this.cleanupInstance(), ()=>this.livePid);
5784
+ }
5785
+ onBrowserGone(code, expected) {
5786
+ if (this.browserGone) return;
5787
+ this.browserGone = true;
5788
+ if (this.watchTimeout) {
5789
+ clearTimeout(this.watchTimeout);
5790
+ this.watchTimeout = void 0;
5791
+ }
5792
+ if (this.liveExitWatcher) {
5793
+ clearInterval(this.liveExitWatcher);
5794
+ this.liveExitWatcher = void 0;
5795
+ }
5796
+ if (this.host.launchProfilePath) (0, shared_utils.sW)(this.host.launchProfilePath);
5797
+ if ((0, messaging._o)()) this.ctx.logger?.info?.(messages.Th(this.host.browser));
5798
+ if (!expected) {
5799
+ this.ctx.logger?.error?.(`[browser] ${this.host.browser} exited (code ${code ?? 'unknown'}) without being asked to. The add-on may have been rejected or the browser crashed; the session cannot be driven.`);
5800
+ (0, ready_stamp.Wi)(this.extensionOutputPath, code);
5801
+ }
5802
+ this.cleanupInstance().catch((err)=>{
5803
+ if ((0, messaging._o)()) this.ctx.logger?.error?.(`[browser] Cleanup error on child close: ${err?.message || err}`);
5804
+ });
5805
+ this.disposeProcessHandlers?.();
5806
+ this.disposeProcessHandlers = void 0;
5807
+ }
5808
+ async trackLiveBrowserPid(attempts) {
5809
+ const child = this.child;
5810
+ const profilePath = this.host.launchProfilePath;
5811
+ if (!child?.pid || !profilePath || this.browserGone) return;
5812
+ try {
5813
+ const pid = await resolveLiveBrowserPid({
5814
+ profilePath,
5815
+ binary: child.spawnfile,
5816
+ launcherPid: child.pid,
5817
+ attempts
5818
+ });
5819
+ if (pid && pid !== child.pid && this.child === child) this.adoptLivePid(pid);
5820
+ } catch {}
5821
+ }
5822
+ adoptHandedOffBrowser() {
5823
+ const profilePath = this.host.launchProfilePath;
5824
+ const child = this.child;
5825
+ if (!profilePath || !child || this.browserGone) return false;
5826
+ try {
5827
+ const pid = this.livePid || findLiveBrowserPid({
5828
+ profilePath,
5829
+ binary: child.spawnfile,
5830
+ launcherPid: child.pid,
5831
+ rows: listProcesses()
5832
+ });
5833
+ if (!pid || pid === this.child?.pid || !isPidAlive(pid)) return false;
5834
+ this.adoptLivePid(pid);
5835
+ return true;
5836
+ } catch {
5837
+ return false;
5838
+ }
5839
+ }
5840
+ adoptLivePid(pid) {
5841
+ if (this.livePid === pid) return;
5842
+ this.livePid = pid;
5843
+ (0, ready_stamp.M)(this.extensionOutputPath, {
5844
+ browserPid: pid,
5845
+ launcherPid: this.child?.pid
5846
+ });
5847
+ if ((0, messaging._o)()) this.ctx.logger?.info?.(`[browser] ${this.host.browser} handed the session to pid ${pid} (launcher pid ${this.child?.pid}).`);
5848
+ this.watchLivePidExit();
5849
+ }
5850
+ watchLivePidExit() {
5851
+ if (this.liveExitWatcher) clearInterval(this.liveExitWatcher);
5852
+ this.liveExitWatcher = setInterval(()=>{
5853
+ const pid = this.livePid;
5854
+ if (!pid || isPidAlive(pid)) return;
5855
+ clearInterval(this.liveExitWatcher);
5856
+ this.liveExitWatcher = void 0;
5857
+ this.onBrowserGone(null, (0, process_teardown.PU)(pid));
5858
+ }, 1000);
5859
+ this.liveExitWatcher.unref?.();
5578
5860
  }
5579
5861
  async retryAddonInstall(compilation, debugPort) {
5580
5862
  try {
@@ -5609,6 +5891,7 @@ var __webpack_modules__ = {
5609
5891
  }
5610
5892
  async cleanupInstance() {
5611
5893
  (0, process_teardown.Df)(this.child, this.host.browser);
5894
+ if (this.livePid && this.livePid !== this.child?.pid) (0, process_teardown._T)(this.livePid, this.host.browser);
5612
5895
  }
5613
5896
  scheduleWatchTimeout() {
5614
5897
  if (this.watchTimeout) return;
@@ -5643,6 +5926,10 @@ var __webpack_modules__ = {
5643
5926
  firefox_launch_define_property(this, "child", null);
5644
5927
  firefox_launch_define_property(this, "watchTimeout", void 0);
5645
5928
  firefox_launch_define_property(this, "extensionOutputPath", void 0);
5929
+ firefox_launch_define_property(this, "livePid", null);
5930
+ firefox_launch_define_property(this, "liveExitWatcher", void 0);
5931
+ firefox_launch_define_property(this, "browserGone", false);
5932
+ firefox_launch_define_property(this, "disposeProcessHandlers", void 0);
5646
5933
  this.host = host;
5647
5934
  this.ctx = ctx;
5648
5935
  }
@@ -5816,7 +6103,6 @@ var __webpack_modules__ = {
5816
6103
  QW: ()=>safariBuildPreflight,
5817
6104
  iF: ()=>safariPreflightError
5818
6105
  });
5819
- var external_node_child_process_ = __webpack_require__("node:child_process");
5820
6106
  var external_node_fs_ = __webpack_require__("node:fs");
5821
6107
  var messaging = __webpack_require__("./helpers/messaging.ts");
5822
6108
  var banner = __webpack_require__("./browsers/browsers-lib/banner.ts");
@@ -5830,6 +6116,7 @@ var __webpack_modules__ = {
5830
6116
  (0, messaging._w)(messages.Aj(xcodebuildCmd));
5831
6117
  }
5832
6118
  var safari_config = __webpack_require__("./browsers/run-safari/safari-launch/safari-config.ts");
6119
+ var external_node_child_process_ = __webpack_require__("node:child_process");
5833
6120
  function isMacOS() {
5834
6121
  return 'darwin' === process.platform;
5835
6122
  }
@@ -5887,20 +6174,6 @@ var __webpack_modules__ = {
5887
6174
  ok: Boolean(converter && xcodebuild)
5888
6175
  };
5889
6176
  }
5890
- function fallbackLogger() {
5891
- return {
5892
- info: (...a)=>(0, messaging._w)(...a),
5893
- warn: (...a)=>(0, messaging.mR)(...a),
5894
- error: (...a)=>(0, messaging.Gg)(...a),
5895
- debug: (...a)=>console?.debug?.(...a)
5896
- };
5897
- }
5898
- function isTestEnv() {
5899
- return Boolean(process.env.VITEST || process.env.VITEST_WORKER_ID);
5900
- }
5901
- function delay(ms) {
5902
- return new Promise((resolve)=>setTimeout(resolve, ms));
5903
- }
5904
6177
  const TOOL_TAIL_LINES = 50;
5905
6178
  const TOOL_TAIL_BYTES = 8192;
5906
6179
  function toolOutputTail(output) {
@@ -5939,6 +6212,60 @@ var __webpack_modules__ = {
5939
6212
  }));
5940
6213
  });
5941
6214
  }
6215
+ async function resolvePidForBundle(bundleId) {
6216
+ for(let attempt = 0; attempt < 10; attempt += 1){
6217
+ const pid = await new Promise((resolve)=>{
6218
+ const child = (0, external_node_child_process_.spawn)("osascript", [
6219
+ '-e',
6220
+ `tell application "System Events" to get unix id of first process whose bundle identifier is "${bundleId}"`
6221
+ ]);
6222
+ let out = '';
6223
+ child.stdout.on('data', (d)=>out += String(d));
6224
+ child.on('error', ()=>resolve(null));
6225
+ child.on('close', ()=>{
6226
+ const n = Number(String(out).trim());
6227
+ resolve(Number.isFinite(n) && n > 0 ? n : null);
6228
+ });
6229
+ });
6230
+ if (pid) return pid;
6231
+ await new Promise((r)=>setTimeout(r, 500));
6232
+ }
6233
+ return null;
6234
+ }
6235
+ function createSafariTools() {
6236
+ return {
6237
+ detectToolchain: ()=>detectSafariToolchain(),
6238
+ runConverter: (args)=>runTool('xcrun', args),
6239
+ runXcodebuild: (args)=>runTool('xcodebuild', args),
6240
+ openApp: (target)=>runTool('open', [
6241
+ target
6242
+ ]),
6243
+ openSafari: (binary)=>runTool('open', [
6244
+ '-a',
6245
+ binary
6246
+ ]),
6247
+ resolvePid: (bundleId)=>resolvePidForBundle(bundleId),
6248
+ pluginkitList: async ()=>{
6249
+ const { ok, output } = await runTool('pluginkit', [
6250
+ '-m'
6251
+ ], {
6252
+ quiet: true
6253
+ });
6254
+ return ok ? output : '';
6255
+ }
6256
+ };
6257
+ }
6258
+ function fallbackLogger() {
6259
+ return {
6260
+ info: (...a)=>(0, messaging._w)(...a),
6261
+ warn: (...a)=>(0, messaging.mR)(...a),
6262
+ error: (...a)=>(0, messaging.Gg)(...a),
6263
+ debug: (...a)=>console?.debug?.(...a)
6264
+ };
6265
+ }
6266
+ function delay(ms) {
6267
+ return new Promise((resolve)=>setTimeout(resolve, ms));
6268
+ }
5942
6269
  function converterWarnings(output) {
5943
6270
  const lines = output.split(/\r?\n/);
5944
6271
  const collected = [];
@@ -5959,15 +6286,11 @@ var __webpack_modules__ = {
5959
6286
  }
5960
6287
  return collected;
5961
6288
  }
5962
- async function confirmRegisteredWithSafari(bundleIdentifier) {
6289
+ async function confirmRegisteredWithSafari(tools, bundleIdentifier) {
5963
6290
  const needle = `${bundleIdentifier}.Extension`;
5964
6291
  for(let attempt = 0; attempt < 6; attempt += 1){
5965
- const { ok, output } = await runTool('pluginkit', [
5966
- '-m'
5967
- ], {
5968
- quiet: true
5969
- });
5970
- if (ok && output.includes(needle)) return true;
6292
+ const listing = await tools.pluginkitList();
6293
+ if (listing.includes(needle)) return true;
5971
6294
  await delay(800);
5972
6295
  }
5973
6296
  return false;
@@ -5982,6 +6305,10 @@ var __webpack_modules__ = {
5982
6305
  macOsOnly: config.macOsOnly
5983
6306
  };
5984
6307
  }
6308
+ function completePackage(config, logger, mode) {
6309
+ if ('full' === mode && config.bundleIdDerived) logger.info?.(messages.$q(config.bundleIdentifier));
6310
+ return describePackage(config);
6311
+ }
5985
6312
  function safariPreflightError() {
5986
6313
  const tc = detectSafariToolchain();
5987
6314
  if (!tc.platformOk) return messages.G3(process.platform);
@@ -6005,26 +6332,6 @@ var __webpack_modules__ = {
6005
6332
  severity: 'ok'
6006
6333
  };
6007
6334
  }
6008
- async function resolvePidForBundle(bundleId) {
6009
- for(let attempt = 0; attempt < 10; attempt += 1){
6010
- const pid = await new Promise((resolve)=>{
6011
- const child = (0, external_node_child_process_.spawn)("osascript", [
6012
- '-e',
6013
- `tell application "System Events" to get unix id of first process whose bundle identifier is "${bundleId}"`
6014
- ]);
6015
- let out = '';
6016
- child.stdout.on('data', (d)=>out += String(d));
6017
- child.on('error', ()=>resolve(null));
6018
- child.on('close', ()=>{
6019
- const n = Number(String(out).trim());
6020
- resolve(Number.isFinite(n) && n > 0 ? n : null);
6021
- });
6022
- });
6023
- if (pid) return pid;
6024
- await new Promise((r)=>setTimeout(r, 500));
6025
- }
6026
- return null;
6027
- }
6028
6335
  async function announceSafariDevSession(host, config, appPath) {
6029
6336
  try {
6030
6337
  await (0, banner.ai)({
@@ -6040,16 +6347,16 @@ var __webpack_modules__ = {
6040
6347
  } catch {}
6041
6348
  }
6042
6349
  async function runSafariPipeline(compilation, host, logger, mode) {
6350
+ const tools = host.tools || createSafariTools();
6043
6351
  const config = (0, safari_config.F7)(compilation, host);
6044
6352
  const converterArgs = (0, safari_config.w7)(config);
6045
6353
  const xcodebuildArgs = (0, safari_config.vx)(config);
6046
6354
  const isSigned = Boolean(config.developmentTeam);
6047
- if ('full' === mode && config.bundleIdDerived) logger.warn?.(messages.$q(config.bundleIdentifier));
6048
- if (host.dryRun || isTestEnv()) {
6355
+ if (host.dryRun) {
6049
6356
  logSafariDryRun(`xcrun ${converterArgs.join(' ')}`, `xcodebuild ${xcodebuildArgs.join(' ')}`);
6050
- return describePackage(config);
6357
+ return completePackage(config, logger, mode);
6051
6358
  }
6052
- const toolchain = detectSafariToolchain();
6359
+ const toolchain = tools.detectToolchain();
6053
6360
  if (!toolchain.platformOk) {
6054
6361
  logger.warn?.(messages.G3(process.platform));
6055
6362
  return describePackage(config);
@@ -6073,7 +6380,7 @@ var __webpack_modules__ = {
6073
6380
  }
6074
6381
  const { saved, restore } = (0, safari_config._D)(config);
6075
6382
  logger.info?.(messages.uK(config.extensionDir));
6076
- const converted = await runTool('xcrun', converterArgs);
6383
+ const converted = await tools.runConverter(converterArgs);
6077
6384
  if (!converted.ok) {
6078
6385
  const tail = toolOutputTail(converted.output);
6079
6386
  logger.error?.(messages.A('safari-web-extension-converter', converted.code, tail));
@@ -6090,7 +6397,7 @@ var __webpack_modules__ = {
6090
6397
  logger.info?.(messages.l_(config.projectLocation));
6091
6398
  } else if ('full' === mode) logger.info?.(messages.oM());
6092
6399
  if ('full' === mode) logger.info?.(messages.jR((0, safari_config.aD)(config)));
6093
- const built = await runTool('xcodebuild', xcodebuildArgs);
6400
+ const built = await tools.runXcodebuild(xcodebuildArgs);
6094
6401
  if (!built.ok) {
6095
6402
  const tail = toolOutputTail(built.output);
6096
6403
  logger.error?.(messages.A('xcodebuild', built.code, tail));
@@ -6105,30 +6412,26 @@ var __webpack_modules__ = {
6105
6412
  if (!config.open) {
6106
6413
  logger.info?.(messages.aO(appPath, config.appName));
6107
6414
  if (host.announceDevReady) await announceSafariDevSession(host, config, appPath);
6108
- return describePackage(config);
6415
+ return completePackage(config, logger, mode);
6109
6416
  }
6110
6417
  const target = external_node_fs_.existsSync(appPath) ? appPath : (0, safari_config.Gi)(config);
6111
6418
  logger.info?.(messages.fw(target));
6112
- await runTool('open', [
6113
- target
6114
- ]);
6115
- if (config.safariBinary) await runTool('open', [
6116
- '-a',
6117
- config.safariBinary
6118
- ]);
6419
+ await tools.openApp(target);
6420
+ if (config.safariBinary) await tools.openSafari(config.safariBinary);
6119
6421
  const raisedBundleId = config.safariBinary ? 'com.apple.Safari' : config.bundleIdentifier;
6120
- const browserPid = await resolvePidForBundle(raisedBundleId);
6121
- if (browserPid) (0, ready_stamp.M)(config.extensionDir, {
6122
- browserPid,
6422
+ const browserPid = await tools.resolvePid(raisedBundleId);
6423
+ (0, ready_stamp.M)(config.extensionDir, {
6424
+ browserPid: browserPid || void 0,
6123
6425
  binary: config.safariBinary || appPath,
6124
6426
  binaryProvenance: config.safariBinary ? 'pinned' : 'system',
6125
6427
  extensionId: `${config.bundleIdentifier}.Extension`
6126
6428
  });
6429
+ if (!browserPid) logger.warn?.(messages.jn(config.appName));
6127
6430
  logger.info?.(messages.fO(config.appName, isSigned));
6128
- if (await confirmRegisteredWithSafari(config.bundleIdentifier)) logger.info?.(messages.fd(config.appName));
6431
+ if (await confirmRegisteredWithSafari(tools, config.bundleIdentifier)) logger.info?.(messages.fd(config.appName));
6129
6432
  else logger.info?.(messages.qY(config.appName));
6130
6433
  if (host.announceDevReady) await announceSafariDevSession(host, config, appPath);
6131
- return describePackage(config);
6434
+ return completePackage(config, logger, mode);
6132
6435
  }
6133
6436
  async function packageSafariExtension(host, outputPath, logger, mode = 'full') {
6134
6437
  const compilation = {
@@ -6248,9 +6551,10 @@ var __webpack_modules__ = {
6248
6551
  function manifestFingerprintPath(config) {
6249
6552
  return node_path__rspack_import_1.join(config.projectLocation, '.manifest-fingerprint');
6250
6553
  }
6554
+ const HOT_UPDATE_DIR = 'hot';
6251
6555
  function topLevelEntries(extensionDir) {
6252
6556
  try {
6253
- return node_fs__rspack_import_0.readdirSync(extensionDir).sort();
6557
+ return node_fs__rspack_import_0.readdirSync(extensionDir).filter((entry)=>entry !== HOT_UPDATE_DIR).sort();
6254
6558
  } catch {
6255
6559
  return [];
6256
6560
  }
@@ -6379,7 +6683,7 @@ var __webpack_modules__ = {
6379
6683
  return Object.fromEntries(Object.entries(input).filter(([, value])=>void 0 !== value));
6380
6684
  }
6381
6685
  function createSafariPackager(options = {}) {
6382
- const { browser = 'safari', noOpen = true, dryRun = false, logger, ...identity } = options;
6686
+ const { browser = 'safari', noOpen = true, dryRun = false, logger, tools, ...identity } = options;
6383
6687
  return async (distPath, mode = 'full', overrides)=>await (0, _safari_launch__rspack_import_0.Ah)({
6384
6688
  extension: [
6385
6689
  distPath
@@ -6387,6 +6691,7 @@ var __webpack_modules__ = {
6387
6691
  browser,
6388
6692
  noOpen,
6389
6693
  dryRun,
6694
+ tools,
6390
6695
  ...withoutUndefined(identity),
6391
6696
  ...withoutUndefined(overrides)
6392
6697
  }, distPath, logger, mode);