extension-develop 4.1.31 → 4.1.32

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 (88) hide show
  1. package/README.md +2 -0
  2. package/dist/105~0.mjs +1 -1
  3. package/dist/177~0.mjs +87 -19
  4. package/dist/273~0.mjs +13 -3
  5. package/dist/363~0.mjs +1874 -0
  6. package/dist/{896~0.mjs → 469~0.mjs} +116 -586
  7. package/dist/519~0.mjs +21 -8
  8. package/dist/616~0.mjs +1 -1
  9. package/dist/771~0.mjs +103 -0
  10. package/dist/832~0.mjs +229 -463
  11. package/dist/840~0.mjs +1189 -54
  12. package/dist/846~0.mjs +453 -0
  13. package/dist/852~0.mjs +8 -6
  14. package/dist/bridge.mjs +3 -2
  15. package/dist/command-preview.d.ts +1 -0
  16. package/dist/contract/codes.json +39 -29
  17. package/dist/contract/envelope.schema.json +16 -0
  18. package/dist/contract/golden.build.compile.json +20 -3
  19. package/dist/contract/golden.eval.csp-blocks-eval.page.json +15 -0
  20. package/dist/css-parse-guard-loader.mjs +3 -1
  21. package/dist/dead-css-url-loader.mjs +129 -13
  22. package/dist/dev-server/cleanup.d.ts +1 -1
  23. package/dist/dev-server/lifecycle-stream.d.ts +14 -3
  24. package/dist/dev-server/session-start-prune.d.ts +13 -0
  25. package/dist/dev-server~0.mjs +91 -14
  26. package/dist/ensure-hmr-for-scripts.js +4 -8
  27. package/dist/ensure-hmr-for-scripts.mjs +4 -8
  28. package/dist/extension-js-devtools/build-stamp.json +2 -2
  29. package/dist/extension-js-theme/build-stamp.json +2 -2
  30. package/dist/feature-scripts-content-script-wrapper.js +7 -4
  31. package/dist/feature-scripts-content-script-wrapper.mjs +7 -4
  32. package/dist/lib/build-summary.d.ts +4 -1
  33. package/dist/lib/coded-warnings.d.ts +3 -0
  34. package/dist/lib/compilation-diagnostics.d.ts +23 -0
  35. package/dist/lib/config-loader.d.ts +2 -2
  36. package/dist/lib/config-resolved-plugin.d.ts +3 -2
  37. package/dist/lib/corepack-registry.d.ts +3 -0
  38. package/dist/lib/diagnostic-code.d.ts +6 -0
  39. package/dist/lib/merge-options.d.ts +1 -0
  40. package/dist/lib/messages.d.ts +4 -1
  41. package/dist/lib/messaging.d.ts +12 -4
  42. package/dist/lib/output-files.d.ts +11 -0
  43. package/dist/lib/package-manager.d.ts +2 -2
  44. package/dist/module.mjs +2 -1
  45. package/dist/plugin-browsers/index.d.ts +1 -0
  46. package/dist/plugin-compatibility/compatibility-lib/free-browser-references.d.ts +9 -0
  47. package/dist/plugin-css/css-lib/dead-url-refs.d.ts +5 -1
  48. package/dist/plugin-css/css-lib/inline-content-script-css.d.ts +4 -2
  49. package/dist/plugin-css/css-lib/line-rewrite-source-map.d.ts +8 -0
  50. package/dist/plugin-css/dead-css-url-loader.d.ts +0 -2
  51. package/dist/plugin-css/public-css-url-loader.d.ts +8 -3
  52. package/dist/plugin-playwright/index.d.ts +9 -4
  53. package/dist/plugin-reload/classify-reload.d.ts +2 -0
  54. package/dist/plugin-reload/messages.d.ts +1 -0
  55. package/dist/plugin-reload/reload-lib/dev-content-scripts.d.ts +4 -0
  56. package/dist/plugin-reload/steps/prune-unreachable-chunks.d.ts +5 -0
  57. package/dist/plugin-special-folders/messages.d.ts +1 -1
  58. package/dist/plugin-special-folders/prune-removed-public-files.d.ts +7 -0
  59. package/dist/plugin-static-assets/check-namespace-imports.d.ts +4 -0
  60. package/dist/plugin-static-assets/static-assets-lib/asset-output-name.d.ts +8 -0
  61. package/dist/plugin-static-assets/static-assets-lib/messages.d.ts +1 -0
  62. package/dist/plugin-web-extension/feature-html/html-lib/utils.d.ts +2 -1
  63. package/dist/plugin-web-extension/feature-icons/messages.d.ts +1 -4
  64. package/dist/plugin-web-extension/feature-locales/get-locales.d.ts +2 -0
  65. package/dist/plugin-web-extension/feature-locales/messages.d.ts +3 -1
  66. package/dist/plugin-web-extension/feature-locales/validation.d.ts +1 -0
  67. package/dist/plugin-web-extension/feature-manifest/manifest-lib/filter-keys-safari.d.ts +1 -0
  68. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/common/content_scripts.d.ts +1 -0
  69. package/dist/plugin-web-extension/feature-manifest/messages.d.ts +1 -0
  70. package/dist/plugin-web-extension/feature-scripts/index.d.ts +2 -0
  71. package/dist/plugin-web-extension/feature-scripts/messages.d.ts +4 -3
  72. package/dist/plugin-web-extension/feature-scripts/scripts-lib/load-time-constants.d.ts +11 -0
  73. package/dist/plugin-web-extension/feature-scripts/steps/trace-runtime-loaded-files.d.ts +4 -0
  74. package/dist/plugin-web-extension/feature-scripts/steps/warn-missing-build-constants.d.ts +24 -0
  75. package/dist/plugin-web-extension/feature-web-resources/web-resources-lib/declared-pages.d.ts +2 -0
  76. package/dist/plugin-web-extension/feature-web-resources/web-resources-lib/resolve-war.d.ts +5 -0
  77. package/dist/plugin-web-extension/index.d.ts +1 -0
  78. package/dist/plugin-web-extension/shared/classic-concat.d.ts +1 -0
  79. package/dist/plugin-web-extension/shared/compilation-issues.d.ts +1 -1
  80. package/dist/preprocessor-passthrough-loader.mjs +3 -1
  81. package/dist/public-css-url-loader.mjs +1 -1
  82. package/dist/rspack-config~0.mjs +4925 -5885
  83. package/dist/stats-handler~0.mjs +12 -4
  84. package/dist/types.d.ts +19 -2
  85. package/dist/zip~0.mjs +20 -2
  86. package/package.json +4 -4
  87. package/dist/300~0.mjs +0 -394
  88. package/dist/747~0.mjs +0 -90
@@ -1,13 +1,11 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
- import { createRequire } from "node:module";
3
2
  import pintor from "pintor";
4
- import { spawnSync } from "node:child_process";
5
3
  import { findNearestDenoConfigSync, validateDenoConfig, PROJECT_MANIFEST_FILENAMES, readProjectDependencies } from "./731~0.mjs";
6
4
  import { isEmulatorLaneEnabled, isEmulatorBrowser, parseJsonSafe } from "./937~0.mjs";
7
- import { browserRowValue, stripChannelPrefix, ENVELOPE, CODES, artifactNoun, prefix as messaging_prefix, card, fmt, isDebug, isMachineOutput, hasChannelPrefix } from "./852~0.mjs";
5
+ import { stripChannelPrefix, artifactNoun, prefix as messaging_prefix, CODES, humanLine, fmt, isDebug, hasChannelPrefix } from "./852~0.mjs";
8
6
  import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
9
- import * as __rspack_external_node_path_806ed179 from "node:path";
10
7
  import * as __rspack_external_node_os_4f3c9d58 from "node:os";
8
+ import * as __rspack_external_node_path_806ed179 from "node:path";
11
9
  function asAbsolute(p) {
12
10
  return __rspack_external_node_path_806ed179.isAbsolute(p) ? p : __rspack_external_node_path_806ed179.resolve(p);
13
11
  }
@@ -192,424 +190,42 @@ function devtoolsEngineFor(browser) {
192
190
  return 'chrome';
193
191
  }
194
192
  }
195
- const cjsRequire = createRequire(import.meta.url);
196
- function getLoggingPrefix(type) {
197
- return messaging_prefix(type);
198
- }
199
- function messages_ready(mode, browser) {
200
- const noun = artifactNoun(browser);
201
- const state = pintor.green(`ready for ${mode}`);
202
- const watching = 'development' === mode ? ' Watching for file changes.' : '';
203
- return `${getLoggingPrefix('success')} ${noun} ${state}.${watching}`;
204
- }
205
- function readJsonRecord(filePath) {
206
- try {
207
- return JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(filePath, 'utf8'));
208
- } catch {
209
- return null;
210
- }
211
- }
212
- function capitalizeToken(value) {
213
- if ('chromium-emulator' === value) return 'Emulated Chromium';
214
- return value.split('-').filter(Boolean).map((token)=>token.charAt(0).toUpperCase() + token.slice(1)).join('-');
215
- }
216
- function getExtensionVersion() {
217
- return process.env.EXTENSION_DEVELOP_VERSION || process.env.EXTENSION_CLI_VERSION || (()=>{
193
+ function listOutputFiles(outputPath) {
194
+ const files = [];
195
+ const pending = [
196
+ ''
197
+ ];
198
+ while(pending.length){
199
+ const relativeDir = pending.pop();
200
+ let entries = [];
218
201
  try {
219
- return cjsRequire('../package.json').version;
202
+ entries = __rspack_external_node_fs_1b05aee1.readdirSync(__rspack_external_node_path_806ed179.join(outputPath, relativeDir), {
203
+ withFileTypes: true
204
+ });
220
205
  } catch {
221
- return 'unknown';
206
+ continue;
222
207
  }
223
- })();
224
- }
225
- function browserRunnerDisabled(args) {
226
- const manifest = readJsonRecord(args.manifestPath);
227
- const ready = readJsonRecord(args.readyPath);
228
- const browserLabel = capitalizeToken(String(args.browser || 'unknown'));
229
- const runId = String(ready?.runId || '').trim();
230
- const pid = Number.isInteger(ready?.pid) ? String(ready?.pid) : '';
231
- const runLabel = runId ? `${runId}${pid ? ` · PID ${pid}` : ''}` : pid ? `PID ${pid}` : '';
232
- const extensionName = String(manifest?.name || 'Extension');
233
- const extensionVersion = String(manifest?.version || '').trim();
234
- const extensionLabel = extensionVersion ? `${extensionName} ${extensionVersion}` : extensionName;
235
- const extensionJsVersion = getExtensionVersion();
236
- const updateSuffix = process.env.EXTENSION_CLI_UPDATE_SUFFIX || '';
237
- if (updateSuffix) delete process.env.EXTENSION_CLI_UPDATE_SUFFIX;
238
- return card({
239
- version: extensionJsVersion,
240
- suffix: updateSuffix,
241
- rows: [
242
- {
243
- label: 'Browser',
244
- value: browserRowValue(String(args.browser || 'unknown'), `${browserLabel} (no-browser mode)`)
245
- },
246
- {
247
- label: 'Extension',
248
- value: extensionLabel
249
- },
250
- {
251
- label: 'Run ID',
252
- value: runLabel
253
- },
254
- {
255
- label: 'Output',
256
- value: collapseHomeDir(String(args.distPath || '').trim())
257
- }
258
- ]
259
- });
260
- }
261
- function shouldWarnPortConflict(requested, actual) {
262
- const requestedPort = Number(requested);
263
- return Number.isFinite(requestedPort) && 0 !== requestedPort && requestedPort !== actual;
264
- }
265
- function emulatorViewerUrl(url) {
266
- return `${getLoggingPrefix('info')} Emulated Chromium runs in a web page. Open this address to load your extension:\n${pintor.underline(url)}`;
267
- }
268
- function portInUse(requestedPort, newPort) {
269
- return `${getLoggingPrefix('warn')} Port ${requestedPort} is in use.\nThe dev server listens on port ${newPort} instead.`;
270
- }
271
- function devServerHostRefused(host) {
272
- const name = host || 'an empty Host header';
273
- return `${getLoggingPrefix('warn')} The dev server refused a request for the host ${pintor.yellow(name)}.\nAllow it with ${pintor.blue(`--allowed-hosts ${host || '<host>'}`)} or ${pintor.blue('commands.dev.allowedHosts')} in extension.config.js. Both take more than one host, comma-separated on the flag.`;
274
- }
275
- function controlBridgeUnavailable(reason) {
276
- return `${getLoggingPrefix('error')} Extension.js couldn't open the control port.\n${pintor.red(reason)}\nSaves will compile but nothing reloads in the browser. Restart the dev session, and if you passed --host make sure it is an address this machine can listen on.`;
277
- }
278
- function extensionJsRunnerError(error) {
279
- return `${getLoggingPrefix('error')} Extension.js couldn't start the runner.\n${pintor.red(String(error))}`;
280
- }
281
- function autoExitModeEnabled(ms) {
282
- return `${getLoggingPrefix('info')} Auto-exit is enabled.\nThe process exits after ${ms} ms of idle time.`;
283
- }
284
- function autoExitTriggered(ms) {
285
- return `${getLoggingPrefix('info')} Auto-exit triggered after ${ms} ms.\nThe process cleans up and exits now.`;
286
- }
287
- function autoExitForceKill(ms) {
288
- return `${getLoggingPrefix('warn')} The process didn't exit within ${ms} ms, so it exits forcibly now.`;
289
- }
290
- function devServerStartTimeout(ms) {
291
- return [
292
- `${getLoggingPrefix('warn')} The dev server didn't start within ${ms} ms.`,
293
- "The bundler may have hit an error before emitting the first build.",
294
- `If nothing else prints, set ${pintor.blue('EXTENSION_VERBOSE=1')} to see more logs.`
295
- ].join('\n');
296
- }
297
- function manifestGoneDuringSession(manifestPath, projectDirGone) {
298
- const what = projectDirGone ? 'The project directory disappeared during the session.' : 'The manifest.json file disappeared during the session.';
299
- const where = projectDirGone ? __rspack_external_node_path_806ed179.dirname(manifestPath) : manifestPath;
300
- return `${getLoggingPrefix('error')} ${what}\n${pintor.gray('NOT FOUND')} ${pintor.underline(collapseHomeDir(where))}\nThe last good build stays loaded. Restore it to keep working, or stop and run ${pintor.blue('extension dev')} again with the right path.`;
301
- }
302
- function bundlerFatalError(error) {
303
- const text = error instanceof Error ? error.stack || error.message : String(error);
304
- return `${getLoggingPrefix('error')} The build failed to start.\n${pintor.red(text)}`;
305
- }
306
- function devServerRestarting(request) {
307
- const what = 'icons' === request.reason ? 'a manifest icon' : 'html' === request.reason ? 'an HTML entrypoint' : 'json' === request.reason ? 'a manifest JSON entry' : 'env' === request.reason ? 'an environment file' : "a manifest script entry";
308
- const lines = [
309
- `${getLoggingPrefix('info')} Restarting the dev server to pick up ${what} change…`
310
- ];
311
- if (request.pathChanged) lines.push(`${pintor.gray('CHANGED')} ${pintor.underline(displayPath(request.pathChanged))}`);
312
- if (request.pathBefore) lines.push(`${pintor.gray('BEFORE')} ${pintor.underline(request.pathBefore)}`);
313
- if (request.pathAfter) lines.push(`${pintor.gray('AFTER')} ${pintor.underline(request.pathAfter)}`);
314
- return lines.join('\n');
315
- }
316
- function bundlerRecompiling() {
317
- return `${getLoggingPrefix('info')} Recompiling due to file changes…`;
318
- }
319
- function noEntrypointsDetected(port) {
320
- return [
321
- `${getLoggingPrefix('warn')} The first compilation produced no entrypoints or assets.`,
322
- `The dev server is running on 127.0.0.1:${port}, but nothing is being built.`,
323
- "Possible causes:",
324
- "- Empty or missing entry configuration.",
325
- "- Extension plugins are disabled, so entries aren't derived from the manifest.",
326
- "- All sources are ignored or excluded.",
327
- `Set ${pintor.blue('EXTENSION_VERBOSE=1')} to see verbose logs, or review your extension config.`
328
- ].join('\n');
329
- }
330
- function spacerLine() {
331
- return ' ';
332
- }
333
- function runnerCleanupError(error) {
334
- return `${messaging_prefix('error')} The dev server could not shut down cleanly: ${String(error?.message || error)}`;
335
- }
336
- function runnerUncaughtException(error) {
337
- return `${messaging_prefix('error')} Uncaught exception in the dev server: ${String(error?.message || error)}`;
338
- }
339
- function runnerUnhandledRejection(reason) {
340
- return `${messaging_prefix('error')} Unhandled rejection in the dev server: ${String(reason?.message || reason)}`;
341
- }
342
- const MAX_OUTPUT_CHARS = 2000;
343
- const ANSI_PATTERN = /\u001b\[[0-9;]*m/g;
344
- function isLifecycleStreamEnabled() {
345
- return isMachineOutput();
346
- }
347
- function humanLine(line) {
348
- if (isMachineOutput()) return void process.stderr.write(`${line}\n`);
349
- console.log(line);
350
- }
351
- function stripAnsi(input) {
352
- return String(input || '').replace(ANSI_PATTERN, '');
353
- }
354
- function readReadyContract(readyPath) {
355
- if (!readyPath) return null;
356
- try {
357
- const parsed = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(readyPath, 'utf-8'));
358
- return parsed && 'object' == typeof parsed ? parsed : null;
359
- } catch {
360
- return null;
361
- }
362
- }
363
- function isProfileLocked(ready) {
364
- if (!ready) return false;
365
- const code = String(ready.code ?? '').trim().toLowerCase();
366
- if ('profile_locked' === code || 'profile-locked' === code) return true;
367
- if (true === ready.profileLocked) return true;
368
- const message = String(ready.message ?? '');
369
- return /profile\s+is\s+locked|singletonlock/i.test(message);
370
- }
371
- function toFiniteNumber(value) {
372
- if ('number' == typeof value && Number.isFinite(value)) return value;
373
- if ('string' == typeof value) {
374
- const parsed = Number.parseInt(value, 10);
375
- return Number.isFinite(parsed) ? parsed : null;
376
- }
377
- return null;
378
- }
379
- class LifecycleStream {
380
- options;
381
- writeLine;
382
- successfulCompiles = 0;
383
- compileAttempts = 0;
384
- readyEmitted = false;
385
- readyErrorEmitted = false;
386
- browserExitEmitted = false;
387
- boundPort = null;
388
- exitWatcher;
389
- launchFailureWatcher;
390
- constructor(options){
391
- this.options = options;
392
- this.writeLine = options.write || ((line)=>process.stdout.write(line));
393
- }
394
- get enabled() {
395
- return isLifecycleStreamEnabled();
396
- }
397
- emit(frame) {
398
- if (!this.enabled) return null;
399
- this.writeLine(`${JSON.stringify(frame)}\n`);
400
- return frame;
401
- }
402
- sessionValue(extra = {}) {
403
- const ready = readReadyContract(this.options.readyPath);
404
- const port = toFiniteNumber(ready?.port) ?? this.boundPort;
405
- return {
406
- command: this.options.command,
407
- browser: this.options.browser,
408
- distPath: this.options.distPath,
409
- pid: process.pid,
410
- port,
411
- ...this.options.readyPath ? {
412
- readyPath: this.options.readyPath
413
- } : {},
414
- ...this.options.eventsPath ? {
415
- eventsPath: this.options.eventsPath
416
- } : {},
417
- ...'string' == typeof ready?.runId ? {
418
- runId: ready.runId
419
- } : {},
420
- ...'string' == typeof ready?.instanceId ? {
421
- instanceId: ready.instanceId
422
- } : {},
423
- ...'string' == typeof ready?.toolchainVersion ? {
424
- toolchainVersion: ready.toolchainVersion
425
- } : {},
426
- ...extra
427
- };
428
- }
429
- starting(args) {
430
- const requestedPort = toFiniteNumber(args.requestedPort);
431
- const port = toFiniteNumber(args.port);
432
- this.boundPort = port;
433
- const reassigned = null !== port && shouldWarnPortConflict(requestedPort, port);
434
- return this.emit(ENVELOPE.ok(this.options.command, 'starting', this.sessionValue({
435
- requestedPort,
436
- port
437
- }), {
438
- warnings: reassigned ? [
439
- `${CODES.E_PORT_IN_USE}: port ${requestedPort} was taken, so the dev server listens on port ${port}`
440
- ] : []
441
- }));
442
- }
443
- compiled(args) {
444
- this.compileAttempts += 1;
445
- this.successfulCompiles += 1;
446
- const status = 1 === this.successfulCompiles ? 'compiled' : 'recompiled';
447
- return this.emit(ENVELOPE.ok(this.options.command, status, this.sessionValue({
448
- assets: toFiniteNumber(args.assets) ?? 0,
449
- durationMs: toFiniteNumber(args.durationMs) ?? 0
450
- })));
451
- }
452
- compileFailed(args) {
453
- this.compileAttempts += 1;
454
- const isFirst = 1 === this.compileAttempts;
455
- const code = isFirst ? CODES.E_FIRST_COMPILE : CODES.E_COMPILE;
456
- const raw = stripAnsi(String(args.output || ''));
457
- const truncated = raw.length > MAX_OUTPUT_CHARS;
458
- const output = truncated ? `${raw.slice(0, MAX_OUTPUT_CHARS)}…` : raw;
459
- const message = args.message || (isFirst ? 'The first compilation failed.' : 'A recompilation failed after a change.');
460
- const frame = ENVELOPE.fail(this.options.command, 'compile-failed', {
461
- code,
462
- message
463
- }, {
464
- truncated
465
- });
466
- frame.value = this.sessionValue({
467
- output,
468
- durationMs: toFiniteNumber(args.durationMs) ?? 0
469
- });
470
- return this.emit(frame);
471
- }
472
- ready(args = {}) {
473
- if (this.readyEmitted) return null;
474
- if (null != args.port) this.boundPort = toFiniteNumber(args.port);
475
- const ready = readReadyContract(this.options.readyPath);
476
- if (ready && 'error' === ready.status) {
477
- if (this.readyErrorEmitted) return null;
478
- this.readyErrorEmitted = true;
479
- const badPin = 'browser_launch_failed' === ready.code && ready.browserLaunchFailedCode === CODES.E_BROWSER_BINARY_INVALID;
480
- const frame = ENVELOPE.fail(this.options.command, badPin ? 'usage' : 'failed', {
481
- code: badPin ? CODES.E_BROWSER_BINARY_INVALID : CODES.E_READY_ERROR_STATUS,
482
- message: String(ready.message || '') || 'The ready contract reports an error for this session.'
483
- });
484
- frame.value = this.sessionValue({
485
- ...'string' == typeof ready.code ? {
486
- readyCode: ready.code
487
- } : {}
208
+ for (const entry of entries)try {
209
+ const name = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
210
+ if (entry.isDirectory()) pending.push(name);
211
+ else if (entry.isFile()) files.push({
212
+ name,
213
+ size: __rspack_external_node_fs_1b05aee1.statSync(__rspack_external_node_path_806ed179.join(outputPath, name)).size
488
214
  });
489
- return this.emit(frame);
490
- }
491
- this.readyEmitted = true;
492
- return this.emit(ENVELOPE.ok(this.options.command, 'ready', this.sessionValue()));
493
- }
494
- browserExited(args = {}) {
495
- if (this.browserExitEmitted) return null;
496
- this.browserExitEmitted = true;
497
- const ready = readReadyContract(this.options.readyPath);
498
- const locked = isProfileLocked(ready);
499
- const code = locked ? CODES.E_PROFILE_LOCKED : CODES.E_BROWSER_LAUNCH;
500
- const message = args.message || String(ready?.message || '') || (locked ? 'The browser profile is locked by another session.' : 'The browser exited before the session ended.');
501
- const frame = ENVELOPE.fail(this.options.command, 'browser-exited', {
502
- code,
503
- message
504
- });
505
- frame.value = this.sessionValue({
506
- exitCode: toFiniteNumber(args.exitCode) ?? toFiniteNumber(ready?.browserExitCode),
507
- ...'string' == typeof ready?.browserExitSignal ? {
508
- exitSignal: ready.browserExitSignal
509
- } : {},
510
- ...'string' == typeof ready?.browserExitedAt ? {
511
- browserExitedAt: ready.browserExitedAt
512
- } : {}
513
- });
514
- return this.emit(frame);
515
- }
516
- failed(message) {
517
- const frame = ENVELOPE.fail(this.options.command, 'failed', {
518
- code: CODES.E_DEV_SERVER_START,
519
- message: stripAnsi(message)
520
- });
521
- frame.value = this.sessionValue();
522
- return this.emit(frame);
523
- }
524
- watchBrowserExit(intervalMs = 1000, onExit) {
525
- const stop = ()=>{
526
- if (this.exitWatcher) clearInterval(this.exitWatcher);
527
- this.exitWatcher = void 0;
528
- };
529
- if (!this.options.readyPath) return stop;
530
- if (!this.enabled && !onExit) return stop;
531
- if (this.exitWatcher) return stop;
532
- this.exitWatcher = setInterval(()=>{
533
- const ready = readReadyContract(this.options.readyPath);
534
- if ('string' != typeof ready?.browserExitedAt) return;
535
- onExit?.(ready);
536
- this.browserExited();
537
- stop();
538
- }, intervalMs);
539
- this.exitWatcher.unref?.();
540
- return stop;
541
- }
542
- watchBrowserLaunchFailure(intervalMs = 1000, onFailure) {
543
- const stop = ()=>{
544
- if (this.launchFailureWatcher) clearInterval(this.launchFailureWatcher);
545
- this.launchFailureWatcher = void 0;
546
- };
547
- if (!this.options.readyPath) return stop;
548
- if (this.launchFailureWatcher) return stop;
549
- this.launchFailureWatcher = setInterval(()=>{
550
- const ready = readReadyContract(this.options.readyPath);
551
- if ('string' != typeof ready?.browserLaunchFailedAt) return;
552
- onFailure(ready);
553
- stop();
554
- }, intervalMs);
555
- this.launchFailureWatcher.unref?.();
556
- return stop;
557
- }
558
- }
559
- function createLifecycleStream(options) {
560
- return new LifecycleStream(options);
561
- }
562
- function assetCount(stats) {
563
- const compilation = stats?.compilation;
564
- try {
565
- const assets = compilation?.getAssets?.();
566
- if (Array.isArray(assets)) return assets.length;
567
- } catch {}
568
- return Object.keys(compilation?.assets || {}).length;
569
- }
570
- function compileDuration(stats) {
571
- const compilation = stats?.compilation;
572
- const start = Number(compilation?.startTime || 0);
573
- const end = Number(compilation?.endTime || 0);
574
- const duration = end - start;
575
- return Number.isFinite(duration) && duration > 0 ? duration : 0;
576
- }
577
- function errorText(stats) {
578
- try {
579
- return String(stats?.toString?.({
580
- all: false,
581
- errors: true,
582
- colors: false
583
- }) || '');
584
- } catch {
585
- return '';
215
+ } catch {}
586
216
  }
217
+ return files.sort((a, b)=>a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
587
218
  }
588
- function attachLifecycleStream(compiler, stream) {
589
- const hooks = compiler?.hooks;
590
- hooks?.done?.tap('extension.js:lifecycle-stream', (stats)=>{
591
- try {
592
- if (stats?.hasErrors?.()) return void stream.compileFailed({
593
- output: errorText(stats),
594
- durationMs: compileDuration(stats)
595
- });
596
- stream.compiled({
597
- assets: assetCount(stats),
598
- durationMs: compileDuration(stats)
599
- });
600
- stream.ready();
601
- } catch {}
602
- });
603
- hooks?.failed?.tap('extension.js:lifecycle-stream', (error)=>{
604
- try {
605
- stream.compileFailed({
606
- output: error instanceof Error ? error.stack || error.message : String(error),
607
- message: error instanceof Error ? error.message : String(error)
608
- });
609
- } catch {}
610
- });
219
+ function foldOutputFiles(files, listedNames) {
220
+ const listed = new Set(listedNames);
221
+ const folded = files.filter((file)=>!listed.has(file.name));
222
+ return {
223
+ count: folded.length,
224
+ bytes: folded.reduce((total, file)=>total + file.size, 0),
225
+ sourceMapsOnly: folded.every((file)=>file.name.endsWith('.map'))
226
+ };
611
227
  }
612
- function messages_getLoggingPrefix(type) {
228
+ function getLoggingPrefix(type) {
613
229
  return messaging_prefix(type);
614
230
  }
615
231
  function isPathLike(input) {
@@ -619,27 +235,27 @@ function resolvedWorkspaceManifest(projectPath, manifestPath) {
619
235
  const manifestDir = __rspack_external_node_path_806ed179.dirname(manifestPath);
620
236
  const packageDir = 'src' === __rspack_external_node_path_806ed179.basename(manifestDir) ? __rspack_external_node_path_806ed179.dirname(manifestDir) : manifestDir;
621
237
  const display = __rspack_external_node_path_806ed179.relative(projectPath, packageDir) || packageDir;
622
- return `${messages_getLoggingPrefix('info')} ${pintor.gray('Workspace root detected.')}\n${pintor.gray('PACKAGE')} ${pintor.underline(display)}`;
238
+ return `${getLoggingPrefix('info')} ${pintor.gray('Workspace root detected.')}\n${pintor.gray('PACKAGE')} ${pintor.underline(display)}`;
623
239
  }
624
240
  function declinedProjectRoot(projectManifestPath, manifestPath) {
625
241
  const manifestDir = __rspack_external_node_path_806ed179.dirname(manifestPath);
626
- return `${messages_getLoggingPrefix('info')} ${pintor.gray(`Using ${__rspack_external_node_path_806ed179.basename(manifestDir)}/ as the project root.`)}\n${pintor.gray('IGNORED')} ${pintor.underline(projectManifestPath)}\n${pintor.gray('That project does not depend on Extension.js, so its dist, its special folders and its dependencies stay out of this build. Add a package.json next to your manifest, or depend on Extension.js there, to use it as the project root.')}`;
242
+ return `${getLoggingPrefix('info')} ${pintor.gray(`Using ${__rspack_external_node_path_806ed179.basename(manifestDir)}/ as the project root.`)}\n${pintor.gray('IGNORED')} ${pintor.underline(projectManifestPath)}\n${pintor.gray('That project does not depend on Extension.js, so its dist, its special folders and its dependencies stay out of this build. Add a package.json next to your manifest, or depend on Extension.js there, to use it as the project root.')}`;
627
243
  }
628
244
  function remoteFetchTimedOut(target, ms) {
629
- return `${messages_getLoggingPrefix('error')} Timed out after ${Math.round(ms / 1000)} s fetching the remote file.\n${pintor.gray('URL')} ${pintor.underline(target)}\nCheck your network, or set ${pintor.blue('EXTENSION_FETCH_TIMEOUT_MS')} to allow more time.`;
245
+ return `${getLoggingPrefix('error')} Timed out after ${Math.round(ms / 1000)} s fetching the remote file.\n${pintor.gray('URL')} ${pintor.underline(target)}\nCheck your network, or set ${pintor.blue('EXTENSION_FETCH_TIMEOUT_MS')} to allow more time.`;
630
246
  }
631
247
  function manifestInvalidJson(manifestPath, error) {
632
248
  const detail = error instanceof Error ? error.message : String(error);
633
- return `${messages_getLoggingPrefix('error')} Couldn't parse manifest.json as JSON.\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}\n${pintor.gray('REASON')} ${pintor.red(detail)}\nFix the syntax error, then run the command again.`;
249
+ return `${getLoggingPrefix('error')} Couldn't parse manifest.json as JSON.\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}\n${pintor.gray('REASON')} ${pintor.red(detail)}\nFix the syntax error, then run the command again.`;
634
250
  }
635
251
  function notAnExtensionManifestError(manifestPath) {
636
- return `${messages_getLoggingPrefix('error')} manifest.json isn't a browser extension manifest.\nIt has no ${pintor.blue('manifest_version')} field, so it looks like a PWA web-app manifest.\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}\nPoint Extension.js at the directory that contains your extension manifest.`;
252
+ return `${getLoggingPrefix('error')} manifest.json isn't a browser extension manifest.\nIt has no ${pintor.blue('manifest_version')} field, so it looks like a PWA web-app manifest.\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}\nPoint Extension.js at the directory that contains your extension manifest.`;
637
253
  }
638
254
  function previewHasNothingToRun(manifestAtOutput) {
639
- return `${messages_getLoggingPrefix('error')} Preview is run-only and does not compile.\n${pintor.gray('NOT FOUND')} ${pintor.underline(manifestAtOutput)}\nRun ${pintor.blue('extension build')} first, or pass ${pintor.blue('--output-path')} an unpacked extension directory.`;
255
+ return `${getLoggingPrefix('error')} Preview is run-only and does not compile.\n${pintor.gray('NOT FOUND')} ${pintor.underline(manifestAtOutput)}\nRun ${pintor.blue('extension build')} first, or pass ${pintor.blue('--output-path')} an unpacked extension directory.`;
640
256
  }
641
257
  function manifestNotFoundError(manifestPath, candidates = []) {
642
- const base = `${messages_getLoggingPrefix('error')} Manifest file not found.\n${pintor.gray('NOT FOUND')} ${pintor.underline(manifestPath)}\nEnsure the path to your extension exists, then try again.`;
258
+ const base = `${getLoggingPrefix('error')} Manifest file not found.\n${pintor.gray('NOT FOUND')} ${pintor.underline(manifestPath)}\nEnsure the path to your extension exists, then try again.`;
643
259
  if (!candidates.length) return base;
644
260
  const projectRoot = __rspack_external_node_path_806ed179.dirname(manifestPath);
645
261
  const hint = 1 === candidates.length ? "Did you mean to point at this workspace package?" : "Did you mean to point at one of these workspace packages?";
@@ -655,63 +271,72 @@ function companionManifestNotProjectError(manifestPath, companionManifestPath) {
655
271
  const projectRoot = __rspack_external_node_path_806ed179.dirname(manifestPath);
656
272
  const companionDir = __rspack_external_node_path_806ed179.dirname(companionManifestPath);
657
273
  const display = __rspack_external_node_path_806ed179.relative(projectRoot, companionDir) || companionDir;
658
- return `${messages_getLoggingPrefix('error')} Manifest file not found.\n${pintor.gray('NOT FOUND')} ${pintor.underline(manifestPath)}\nThe only manifest.json here belongs to a companion extension under ${pintor.blue('extensions/')}.\nCompanions load next to your extension and never stand in for it.\n${pintor.gray('COMPANION')} ${pintor.underline(display)}\nAdd a manifest.json at the project root or in ${pintor.blue('src/')}, or point Extension.js at your extension's directory.`;
274
+ return `${getLoggingPrefix('error')} Manifest file not found.\n${pintor.gray('NOT FOUND')} ${pintor.underline(manifestPath)}\nThe only manifest.json here belongs to a companion extension under ${pintor.blue('extensions/')}.\nCompanions load next to your extension and never stand in for it.\n${pintor.gray('COMPANION')} ${pintor.underline(display)}\nAdd a manifest.json at the project root or in ${pintor.blue('src/')}, or point Extension.js at your extension's directory.`;
659
275
  }
660
276
  function sessionStateIgnoreAdded(gitignorePath) {
661
- return `${messages_getLoggingPrefix('info')} Added .extension-js to ${gitignorePath} so the local session state stays out of commits.`;
277
+ return `${getLoggingPrefix('info')} Added .extension-js to ${gitignorePath} so the local session state stays out of commits.`;
662
278
  }
663
279
  function previewingSourceFallback(browser, distDir) {
664
- return `${messages_getLoggingPrefix('warn')} No production build found at ${distDir}, previewing the source manifest directory instead.\nRun \`extension build --browser ${String(browser)}\` first to preview the built output.`;
280
+ return `${getLoggingPrefix('warn')} No production build found at ${distDir}, previewing the source manifest directory instead.\nRun \`extension build --browser ${String(browser)}\` first to preview the built output.`;
665
281
  }
666
282
  function previewing(browser, noBrowser) {
667
283
  const suffix = noBrowser ? ' (no-browser mode)' : '';
668
- return `${messages_getLoggingPrefix('info')} Previewing on ${capitalizedBrowserName(browser)}${suffix}.`;
284
+ return `${getLoggingPrefix('info')} Previewing on ${capitalizedBrowserName(browser)}${suffix}.`;
669
285
  }
670
286
  function starting(browser, noBrowser) {
671
287
  const suffix = noBrowser ? ' (no-browser mode)' : '';
672
- return `${messages_getLoggingPrefix('info')} Starting on ${capitalizedBrowserName(browser)}${suffix}.`;
288
+ return `${getLoggingPrefix('info')} Starting on ${capitalizedBrowserName(browser)}${suffix}.`;
673
289
  }
674
290
  function extensionLoadRecovered() {
675
- return `${messages_getLoggingPrefix('success')} The browser accepted the extension.\nIt's running now.`;
291
+ return `${getLoggingPrefix('success')} The browser accepted the extension.\nIt's running now.`;
676
292
  }
677
293
  function extensionLoadStillRefused(reason) {
678
- return `${messages_getLoggingPrefix('error')} The browser still refuses to load this extension.\n${pintor.gray('REASON')} ${pintor.red(reason)}`;
294
+ return `${getLoggingPrefix('error')} The browser still refuses to load this extension.\n${pintor.gray('REASON')} ${pintor.red(reason)}`;
679
295
  }
680
296
  function browserLaunchFailed(browser, reason) {
681
- return `${messages_getLoggingPrefix('error')} ${capitalizedBrowserName(browser)} couldn't start, so the extension isn't running.\n${hasChannelPrefix(reason) ? stripChannelPrefix(reason) : reason}\nThe dev server keeps watching, but nothing will load until this is fixed.`;
297
+ return `${getLoggingPrefix('error')} ${capitalizedBrowserName(browser)} couldn't start, so the extension isn't running.\n${hasChannelPrefix(reason) ? stripChannelPrefix(reason) : reason}\nThe dev server keeps watching, but nothing will load until this is fixed.`;
682
298
  }
683
299
  function authorInstallNotice(target) {
684
300
  return `${messaging_prefix('debug')} install target=${target}`;
685
301
  }
686
302
  function projectInstallInWorkspaceRoot(workspaceRoot) {
687
- return `${messages_getLoggingPrefix('info')} This project is a pnpm workspace member, installing from the workspace root at ${pintor.blue(workspaceRoot)}.`;
303
+ return `${getLoggingPrefix('info')} This project is a pnpm workspace member, installing from the workspace root at ${pintor.blue(workspaceRoot)}.`;
688
304
  }
689
305
  function projectInstallFallbackToNpm(pmName) {
690
- return `${messages_getLoggingPrefix('warn')} Dependency install with ${pmName} failed.\nExtension.js retries once with npm so the build can continue.`;
306
+ return `${getLoggingPrefix('warn')} Dependency install with ${pmName} failed.\nExtension.js retries once with npm so the build can continue.`;
691
307
  }
692
308
  function projectInstallScriptsDisabled(pmName) {
693
- return `${messages_getLoggingPrefix('info')} Installing the project dependencies with ${pmName}…\nLifecycle scripts are disabled for safety.\nSet ${pintor.blue('EXTENSION_ALLOW_INSTALL_SCRIPTS=true')} to run them.`;
309
+ return `${getLoggingPrefix('info')} Installing the project dependencies with ${pmName}…\nLifecycle scripts are disabled for safety.\nSet ${pintor.blue('EXTENSION_ALLOW_INSTALL_SCRIPTS=true')} to run them.`;
694
310
  }
695
311
  function anotherDevSessionActive(browser, pid, runId) {
696
312
  const run = runId ? `, run ${runId}` : '';
697
- return `${messages_getLoggingPrefix('warn')} Another dev session is already writing dist/${browser} (PID ${pid}${run}).\nBoth sessions rebuild the same output, so the last compile wins.\nStop the other session, or pass ${fmt.code('--instance-id')} to run them side by side.`;
313
+ return `${getLoggingPrefix('warn')} Another dev session is already writing dist/${browser} (PID ${pid}${run}).\nBoth sessions rebuild the same output, so the last compile wins.\nStop the other session. A distinct ${fmt.code('EXTENSION_INSTANCE_ID')} keeps the ports apart, but ready.json and the eval token hold one session per browser.`;
698
314
  }
699
- function buildAssetsTree(stats) {
315
+ function anotherDevSessionRefused(browser, pid, port) {
316
+ const where = port ? ` on port ${port}` : '';
317
+ return `${getLoggingPrefix('error')} Another dev session already owns dist/${browser} (PID ${pid}${where}).\nA second session would overwrite its eval token and leave its contract pointing at the wrong one.\nStop that session first. One dev session per browser owns dist/${browser}, whatever its ${fmt.code('EXTENSION_INSTANCE_ID')}.`;
318
+ }
319
+ function buildAssetsTree(stats, outputFiles) {
700
320
  const statsJson = stats?.toJson?.({
701
321
  all: false,
702
322
  assets: true
703
323
  });
704
324
  const assets = statsJson?.assets || [];
705
- return getAssetsTree(assets);
325
+ const tree = getAssetsTree(assets);
326
+ if (!tree || !outputFiles?.length) return tree;
327
+ const folded = foldOutputFiles(outputFiles, assets.map((asset)=>asset?.name));
328
+ if (0 === folded.count) return tree;
329
+ const noun = folded.sourceMapsOnly ? 'source map' : 'file';
330
+ return tree + pintor.gray(`+ ${pluralize(folded.count, noun)} not shown (${getFileSize(folded.bytes)})`) + '\n';
706
331
  }
707
332
  function buildComplete(browser, distDisplayPath, totalBytes, mode) {
708
333
  const noun = artifactNoun(String(browser));
709
334
  const builtFor = 'development' === mode ? 'built for development in' : 'none' === mode ? 'built in' : 'built for production in';
710
335
  const size = 'number' == typeof totalBytes && totalBytes > 0 ? ` (${getHumanSize(totalBytes)})` : '';
711
- return `${messages_getLoggingPrefix('success')} ${noun} ${builtFor} ${pintor.underline(distDisplayPath)}${size}.`;
336
+ return `${getLoggingPrefix('success')} ${noun} ${builtFor} ${pintor.underline(distDisplayPath)}${size}.`;
712
337
  }
713
338
  function operaBuildUnminified() {
714
- return `${messages_getLoggingPrefix('info')} Opera Add-ons reviews readable source, so this build does not minify first-party code. Pass ${pintor.blue('--minify')} to minify it anyway.`;
339
+ return `${getLoggingPrefix('info')} Opera Add-ons reviews readable source, so this build does not minify first-party code. Pass ${pintor.blue('--minify')} to minify it anyway.`;
715
340
  }
716
341
  function platformDocsUrl() {
717
342
  return String(process.env.EXTENSION_DEV_DOCS_URL || '').trim().replace(/\/+$/, '');
@@ -723,10 +348,10 @@ function addonLintSummary(errorCount, warningCount, distDisplay) {
723
348
  const parts = [];
724
349
  if (errorCount > 0) parts.push(pluralize(errorCount, 'error'));
725
350
  if (warningCount > 0) parts.push(pluralize(warningCount, 'warning'));
726
- return `${messages_getLoggingPrefix('warn')} Store check for addons.mozilla.org: addons-linter found ${parts.join(' and ')} in ${pintor.underline(distDisplay)}`;
351
+ return `${getLoggingPrefix('warn')} Store check for addons.mozilla.org: addons-linter found ${parts.join(' and ')} in ${pintor.underline(distDisplay)}`;
727
352
  }
728
353
  function addonLintFinding(level, code, message, location, attribution) {
729
- const glyph = messages_getLoggingPrefix('error' === level ? 'warn' : 'info');
354
+ const glyph = getLoggingPrefix('error' === level ? 'warn' : 'info');
730
355
  const where = location ? ` ${pintor.gray(`(${location})`)}` : '';
731
356
  const from = attribution ? ` ${pintor.gray(attribution)}` : '';
732
357
  return `${glyph} AMO ${level} ${pintor.yellow(code)}: ${message}${where}${from}`;
@@ -738,26 +363,26 @@ function addonLintDependencyAttribution(packages, onlyDependencies) {
738
363
  return onlyDependencies ? `- this file is bundled dependency code (${named}${rest}), not yours` : `- this file also bundles ${named}${rest}, so the finding may be theirs`;
739
364
  }
740
365
  function addonLintMore(hiddenCount, distDisplay) {
741
- return `${messages_getLoggingPrefix('info')} ${pluralize(hiddenCount, 'more finding')} not shown. Run ${pintor.blue(`npx addons-linter ${distDisplay}`)} for the full report.`;
366
+ return `${getLoggingPrefix('info')} ${pluralize(hiddenCount, 'more finding')} not shown. Run ${pintor.blue(`npx addons-linter ${distDisplay}`)} for the full report.`;
742
367
  }
743
368
  function addonLintNotInstalled(installHint) {
744
- return `${messages_getLoggingPrefix('info')} Skipped the addons.mozilla.org lint: addons-linter is not installed. Install it with: ${pintor.blue(installHint)} or pass ${pintor.blue('--no-addon-lint')} to silence this.`;
369
+ return `${getLoggingPrefix('info')} Skipped the addons.mozilla.org lint: addons-linter is not installed. Install it with: ${pintor.blue(installHint)} or pass ${pintor.blue('--no-addon-lint')} to silence this.`;
745
370
  }
746
371
  function addonLintFailed(reason, distDisplay) {
747
- return `${messages_getLoggingPrefix('warn')} Store check for addons.mozilla.org did not finish: ${reason}. The build is complete, run ${pintor.blue(`npx addons-linter ${distDisplay}`)} to see what AMO would flag.`;
372
+ return `${getLoggingPrefix('warn')} Store check for addons.mozilla.org did not finish: ${reason}. The build is complete, run ${pintor.blue(`npx addons-linter ${distDisplay}`)} to see what AMO would flag.`;
748
373
  }
749
374
  function addonLintFailedDebug(reason) {
750
- return `${messages_getLoggingPrefix('debug')} addon-lint failed=true reason="${reason}"`;
375
+ return `${getLoggingPrefix('debug')} addon-lint failed=true reason="${reason}"`;
751
376
  }
752
377
  function buildShareHint() {
753
378
  const docs = platformDocsUrl();
754
379
  if (!docs) return '';
755
- return `${messages_getLoggingPrefix('info')} Send this build to someone for review: ` + pintor.underline(`${docs}/share/unpublished-build-for-review?utm_source=cli-build`);
380
+ return `${getLoggingPrefix('info')} Send this build to someone for review: ` + pintor.underline(`${docs}/share/unpublished-build-for-review?utm_source=cli-build`);
756
381
  }
757
382
  function buildFailed(errorCount) {
758
383
  const count = Math.max(1, Math.floor(errorCount || 1));
759
384
  const noun = 1 === count ? 'error' : 'errors';
760
- return `${messages_getLoggingPrefix('error')} Build failed with ${count} ${noun}.`;
385
+ return `${getLoggingPrefix('error')} Build failed with ${count} ${noun}.`;
761
386
  }
762
387
  function stripModuleWarningWrapper(message) {
763
388
  return message.replace(/^Module (?:Warning|Error) \(from [^)]*\):\s*/, '');
@@ -828,45 +453,45 @@ function buildWarningsDetails(warnings) {
828
453
  const artifact = getWarningArtifact(warning);
829
454
  const category = classifyWarning(message, source);
830
455
  const hint = suggestedHintForWarning(category);
831
- if (!message) return void blocks.push(`${messages_getLoggingPrefix('warn')} Warning ${index + 1}: details were suppressed by tool output.\n${formatWarningLabelLine('Source', pintor.gray(source))}\n${formatWarningLabelLine('Hint', 'Re-run with EXTENSION_VERBOSE=1 to inspect full warning messages.')}`);
456
+ if (!message) return void blocks.push(`${getLoggingPrefix('warn')} Warning ${index + 1}: details were suppressed by tool output.\n${formatWarningLabelLine('Source', pintor.gray(source))}\n${formatWarningLabelLine('Hint', 'Re-run with EXTENSION_VERBOSE=1 to inspect full warning messages.')}`);
832
457
  const performanceWarning = parsePerformanceWarning(warning, source, artifact);
833
458
  if (performanceWarning) return void blocks.push(performanceWarning);
834
459
  if (hasChannelPrefix(message)) return void blocks.push(message);
835
- const explained = message.includes('\n');
836
- const oneLine = message.replace(/\s+/g, ' ').trim();
460
+ const [headline, ...body] = message.split('\n').map((line)=>line.replace(/\s+/g, ' ').trim()).filter(Boolean);
461
+ const explained = body.length > 0;
837
462
  const artifactSuffix = artifact ? ` ${pintor.gray(`(${artifact})`)}` : '';
838
- blocks.push(`${messages_getLoggingPrefix('warn')} ${category}: ${oneLine}${artifactSuffix}\n` + formatWarningLabelLine('Source', pintor.gray(source)) + (explained ? '' : `\n${formatWarningLabelLine('Hint', hint)}`));
463
+ blocks.push(`${getLoggingPrefix('warn')} ${category}: ${headline}${artifactSuffix}\n` + body.map((line)=>`${line}\n`).join('') + formatWarningLabelLine('Source', pintor.gray(source)) + (explained ? '' : `\n${formatWarningLabelLine('Hint', hint)}`));
839
464
  });
840
465
  return blocks.join('\n\n');
841
466
  }
842
467
  function downloadingProjectPath(projectName, url) {
843
468
  const formatted = isPathLike(projectName) ? pintor.underline(projectName) : projectName;
844
- return `${messages_getLoggingPrefix('info')} Downloading ${formatted}…\n${pintor.gray('URL')} ${fmt.val(url)}`;
469
+ return `${getLoggingPrefix('info')} Downloading ${formatted}…\n${pintor.gray('URL')} ${fmt.val(url)}`;
845
470
  }
846
471
  function creatingProjectPath() {
847
- return `${messages_getLoggingPrefix('info')} Creating a new browser extension…`;
472
+ return `${getLoggingPrefix('info')} Creating a new browser extension…`;
848
473
  }
849
474
  function reusingDownloadedProject(destinationPath, url) {
850
- return `${messages_getLoggingPrefix('info')} Using the extension already downloaded here…\n${pintor.gray('PATH')} ${pintor.underline(destinationPath)}\n${pintor.gray('URL')} ${fmt.val(url)}\nDelete that folder to download it again.`;
475
+ return `${getLoggingPrefix('info')} Using the extension already downloaded here…\n${pintor.gray('PATH')} ${pintor.underline(destinationPath)}\n${pintor.gray('URL')} ${fmt.val(url)}\nDelete that folder to download it again.`;
851
476
  }
852
477
  function remoteSourceDestinationTaken(destinationPath, source) {
853
478
  const isUrl = /^https?:\/\//i.test(source);
854
- return `${messages_getLoggingPrefix('error')} ` + (isUrl ? `A folder is already here, and it isn't a download from this URL.\n` : `A folder is already here, and it wasn't extracted from this ZIP file.\n`) + `${pintor.gray('PATH')} ${pintor.underline(destinationPath)}\n` + `${pintor.gray(isUrl ? 'URL' : 'ZIP')} ${fmt.val(source)}\n` + "Rename or remove that folder, or run the command from another folder.";
479
+ return `${getLoggingPrefix('error')} ` + (isUrl ? `A folder is already here, and it isn't a download from this URL.\n` : `A folder is already here, and it wasn't extracted from this ZIP file.\n`) + `${pintor.gray('PATH')} ${pintor.underline(destinationPath)}\n` + `${pintor.gray(isUrl ? 'URL' : 'ZIP')} ${fmt.val(source)}\n` + "Rename or remove that folder, or run the command from another folder.";
855
480
  }
856
481
  function downloadedProjectFolderNotFound(cwd, candidates) {
857
- return `${messages_getLoggingPrefix('error')} Downloaded project folder not found.\n${pintor.gray('PATH')} ${pintor.underline(cwd)}\n${pintor.gray('NOT FOUND')} ${pintor.underline(candidates.join(', '))}`;
482
+ return `${getLoggingPrefix('error')} Downloaded project folder not found.\n${pintor.gray('PATH')} ${pintor.underline(cwd)}\n${pintor.gray('NOT FOUND')} ${pintor.underline(candidates.join(', '))}`;
858
483
  }
859
484
  function packagingSourceFiles(zipPath) {
860
485
  return `${messaging_prefix('debug')} zip pack=source gitignore=excluded path=${zipPath}`;
861
486
  }
862
487
  function zipSkippedSymlinks(links) {
863
- return `${messages_getLoggingPrefix('warn')} The source zip skipped ${1 === links.length ? 'a symlink' : `${links.length} symlinks`}, because an archive stores files.\n${pintor.gray('SKIPPED')} ${links.join(', ')}\nCopy what the link points at into the project if the archive needs it.`;
488
+ return `${getLoggingPrefix('warn')} The source zip skipped ${1 === links.length ? 'a symlink' : `${links.length} symlinks`}, because an archive stores files.\n${pintor.gray('SKIPPED')} ${links.join(', ')}\nCopy what the link points at into the project if the archive needs it.`;
864
489
  }
865
490
  function zipArtifactNotCreated(kind, zipPath, reason) {
866
- return `${messages_getLoggingPrefix('error')} The ${'source' === kind ? 'source' : 'distribution'} zip was requested and not created.\n${pintor.gray('PATH')} ${pintor.underline(zipPath)}\n${pintor.red(reason)}`;
491
+ return `${getLoggingPrefix('error')} The ${'source' === kind ? 'source' : 'distribution'} zip was requested and not created.\n${pintor.gray('PATH')} ${pintor.underline(zipPath)}\n${pintor.red(reason)}`;
867
492
  }
868
493
  function zipArtifactReady(zipPath, sizeInBytes) {
869
- return `${messages_getLoggingPrefix('success')} Packaged ${pintor.underline(zipPath)} (${getHumanSize(sizeInBytes)}).`;
494
+ return `${getLoggingPrefix('success')} Packaged ${pintor.underline(zipPath)} (${getHumanSize(sizeInBytes)}).`;
870
495
  }
871
496
  function packagingDistributionFiles(zipPath) {
872
497
  return `${messaging_prefix('debug')} zip pack=dist path=${zipPath}`;
@@ -881,47 +506,50 @@ function treeWithSourceFiles(name, ext, browser, zipPath) {
881
506
  return `${messaging_prefix('debug')} zip name=${name}-source.${ext} browser=${String(browser)} source=${zipPath}`;
882
507
  }
883
508
  function writingTypeDefinitions(manifest) {
884
- return `${messages_getLoggingPrefix('info')} Writing the type definitions for ${manifest.name || 'the extension'}…`;
509
+ return `${getLoggingPrefix('info')} Writing the type definitions for ${manifest.name || 'the extension'}…`;
510
+ }
511
+ function updatingTypeDefinitions(filePath) {
512
+ return `${getLoggingPrefix('info')} Updating the type definitions in ${filePath} to match this version.`;
885
513
  }
886
514
  function writingTypeDefinitionsError(error) {
887
- return `${messages_getLoggingPrefix('error')} Couldn't write the extension type definitions.\n${pintor.gray('REASON')} ${pintor.red(String(error))}\nCheck the file permissions, then try again.`;
515
+ return `${getLoggingPrefix('error')} Couldn't write the extension type definitions.\n${pintor.gray('REASON')} ${pintor.red(String(error))}\nCheck the file permissions, then try again.`;
888
516
  }
889
517
  function downloadingText(url) {
890
- return `${messages_getLoggingPrefix('info')} Downloading the browser extension…\n${pintor.gray('URL')} ${fmt.val(url)}`;
518
+ return `${getLoggingPrefix('info')} Downloading the browser extension…\n${pintor.gray('URL')} ${fmt.val(url)}`;
891
519
  }
892
520
  function unpackagingExtension(zipFilePath) {
893
- return `${messages_getLoggingPrefix('info')} Unpackaging the browser extension…\n${pintor.gray('PATH')} ${pintor.underline(zipFilePath)}`;
521
+ return `${getLoggingPrefix('info')} Unpackaging the browser extension…\n${pintor.gray('PATH')} ${pintor.underline(zipFilePath)}`;
894
522
  }
895
523
  function unpackagedSuccessfully() {
896
- return `${messages_getLoggingPrefix('success')} Extension unpackaged.`;
524
+ return `${getLoggingPrefix('success')} Extension unpackaged.`;
897
525
  }
898
526
  function failedToDownloadOrWriteZIPFileError(error) {
899
- return `${messages_getLoggingPrefix('error')} Couldn't download the ZIP file or write it to disk.\n${pintor.gray('REASON')} ${pintor.red(String(error))}\nCheck the URL, your network and that the destination is writable, then try again.`;
527
+ return `${getLoggingPrefix('error')} Couldn't download the ZIP file or write it to disk.\n${pintor.gray('REASON')} ${pintor.red(String(error))}\nCheck the URL, your network and that the destination is writable, then try again.`;
900
528
  }
901
529
  function failedToWriteZIPFileError(error) {
902
- return `${messages_getLoggingPrefix('error')} Couldn't write the unpacked ZIP file to disk.\n${pintor.gray('REASON')} ${pintor.red(String(error))}\nCheck that the destination is writable, then try again.`;
530
+ return `${getLoggingPrefix('error')} Couldn't write the unpacked ZIP file to disk.\n${pintor.gray('REASON')} ${pintor.red(String(error))}\nCheck that the destination is writable, then try again.`;
903
531
  }
904
532
  function invalidRemoteZip(url, contentType) {
905
- return `${messages_getLoggingPrefix('error')} The remote URL doesn't point to a ZIP archive.\n${pintor.gray('URL')} ${pintor.underline(url)}\n${pintor.gray('GOT')} ${pintor.underline(contentType || 'unknown')}\nUse a direct-download URL, or download the file and pass the local path.`;
533
+ return `${getLoggingPrefix('error')} The remote URL doesn't point to a ZIP archive.\n${pintor.gray('URL')} ${pintor.underline(url)}\n${pintor.gray('GOT')} ${pintor.underline(contentType || 'unknown')}\nUse a direct-download URL, or download the file and pass the local path.`;
906
534
  }
907
535
  function notAZipArchive(source, contentType) {
908
- return `${messages_getLoggingPrefix('error')} The downloaded content isn't a ZIP archive.\n${pintor.gray('SOURCE')} ${pintor.underline(source)}\n` + (contentType ? `${pintor.gray('GOT')} ${pintor.underline(contentType)}\n` : '') + `The URL likely requires authentication and returned an HTML login page instead of the file.\n` + `This happens with Slack, Google Drive, and Dropbox file pages.\n` + "Download the ZIP in the browser and pass the local path, or use a direct-download URL.";
536
+ return `${getLoggingPrefix('error')} The downloaded content isn't a ZIP archive.\n${pintor.gray('SOURCE')} ${pintor.underline(source)}\n` + (contentType ? `${pintor.gray('GOT')} ${pintor.underline(contentType)}\n` : '') + `The URL likely requires authentication and returned an HTML login page instead of the file.\n` + `This happens with Slack, Google Drive, and Dropbox file pages.\n` + "Download the ZIP in the browser and pass the local path, or use a direct-download URL.";
909
537
  }
910
538
  function remoteZipDamaged(url, cause) {
911
539
  const detail = cause instanceof Error ? cause.message : String(cause);
912
- return `${messages_getLoggingPrefix('error')} The ZIP archive at the remote URL is damaged.\n${pintor.gray('URL')} ${pintor.underline(url)}\n${pintor.gray('REASON')} ${pintor.red(detail)}\nTry again, or download a good copy of the archive and pass the local path.`;
540
+ return `${getLoggingPrefix('error')} The ZIP archive at the remote URL is damaged.\n${pintor.gray('URL')} ${pintor.underline(url)}\n${pintor.gray('REASON')} ${pintor.red(detail)}\nTry again, or download a good copy of the archive and pass the local path.`;
913
541
  }
914
542
  function zipEntryOutsideFolder(source, entry) {
915
543
  const where = 'url' in source ? 'The ZIP archive at the remote URL' : 'The ZIP file';
916
544
  const row = 'url' in source ? `${pintor.gray('URL')} ${pintor.underline(source.url)}` : `${pintor.gray('PATH')} ${pintor.underline(source.path)}`;
917
- return `${messages_getLoggingPrefix('error')} ${where} contains a path outside its folder, so it was refused. Nothing was written.\n${row}\n${pintor.gray('ENTRY')} ${pintor.red(entry)}\nUse an archive whose entries all stay inside its folder.`;
545
+ return `${getLoggingPrefix('error')} ${where} contains a path outside its folder, so it was refused. Nothing was written.\n${row}\n${pintor.gray('ENTRY')} ${pintor.red(entry)}\nUse an archive whose entries all stay inside its folder.`;
918
546
  }
919
547
  function localZipUnreadable(zipFilePath, cause) {
920
548
  const detail = cause instanceof Error ? cause.message : String(cause ?? '');
921
- return `${messages_getLoggingPrefix('error')} The file isn't a ZIP archive that can be unpacked.\n${pintor.gray('PATH')} ${pintor.underline(zipFilePath)}\n` + (detail ? `${pintor.gray('REASON')} ${pintor.red(detail)}\n` : '') + "Check that the file opens as a ZIP, then try again.";
549
+ return `${getLoggingPrefix('error')} The file isn't a ZIP archive that can be unpacked.\n${pintor.gray('PATH')} ${pintor.underline(zipFilePath)}\n` + (detail ? `${pintor.gray('REASON')} ${pintor.red(detail)}\n` : '') + "Check that the file opens as a ZIP, then try again.";
922
550
  }
923
551
  function localZipNotFound(zipFilePath) {
924
- return `${messages_getLoggingPrefix('error')} ZIP file not found.\n${pintor.gray('NOT FOUND')} ${pintor.underline(zipFilePath)}\nCheck the path, then try again.`;
552
+ return `${getLoggingPrefix('error')} ZIP file not found.\n${pintor.gray('NOT FOUND')} ${pintor.underline(zipFilePath)}\nCheck the path, then try again.`;
925
553
  }
926
554
  function capitalizedBrowserName(browser) {
927
555
  const b = String(browser || '');
@@ -992,7 +620,7 @@ function parsePerformanceWarning(warning, source, _artifact) {
992
620
  }
993
621
  function formatPerformanceWarningBlock(options) {
994
622
  const lines = [
995
- `${messages_getLoggingPrefix('warn')} Performance: ${options.title}`
623
+ `${getLoggingPrefix('warn')} Performance: ${options.title}`
996
624
  ];
997
625
  if (options.threshold) lines.push(formatWarningLabelLine('Threshold', options.threshold));
998
626
  lines.push(formatWarningLabelLine('Impact', options.impact));
@@ -1025,17 +653,17 @@ function debugSplitChunksNarrowed(optionPaths) {
1025
653
  }
1026
654
  function runtimeChunkKeptInline(runtimeChunk) {
1027
655
  const setting = 'string' == typeof runtimeChunk ? `'${runtimeChunk}'` : 'object' == typeof runtimeChunk ? 'an object' : String(runtimeChunk);
1028
- return `${messages_getLoggingPrefix('warn')} optimization.runtimeChunk is set to ${setting}, kept at false.\nThe background and the content scripts load one file each, so a separate runtime file never reaches them and the entry never starts. Pages already share code through the shared/ files.`;
656
+ return `${getLoggingPrefix('warn')} optimization.runtimeChunk is set to ${setting}, kept at false.\nThe background and the content scripts load one file each, so a separate runtime file never reaches them and the entry never starts. Pages already share code through the shared/ files.`;
1029
657
  }
1030
658
  function configResolvedChangeIgnored(keys) {
1031
659
  const many = keys.length > 1;
1032
- return `${messages_getLoggingPrefix('warn')} configResolved changed ${keys.join(', ')}, which the hook cannot change. The change is ignored, set ${many ? 'them' : 'it'} in config instead.`;
660
+ return `${getLoggingPrefix('warn')} configResolved changed ${keys.join(', ')}, which the hook cannot change. The change is ignored, set ${many ? 'them' : 'it'} in config instead.`;
1033
661
  }
1034
662
  function debugOutputPath(pathValue) {
1035
663
  return `${messaging_prefix('debug')} output path=${pathValue}`;
1036
664
  }
1037
665
  function previewingCustomOutput(browser, outputPath, distPath) {
1038
- return `${messages_getLoggingPrefix('info')} Previewing ${String(browser)} from ${outputPath}.\nThis is not the build folder ${distPath}. The run record describes the folder loaded.`;
666
+ return `${getLoggingPrefix('info')} Previewing ${String(browser)} from ${outputPath}.\nThis is not the build folder ${distPath}. The run record describes the folder loaded.`;
1039
667
  }
1040
668
  function debugPreviewOutput(outputPath, distPath) {
1041
669
  return `${messaging_prefix('debug')} preview output=${outputPath} dist=${distPath}`;
@@ -1047,7 +675,7 @@ function debugExtensionsToLoad(extensions) {
1047
675
  return `${messaging_prefix('debug')} extensions count=${extensions.length} paths=${extensions.join(',')}`;
1048
676
  }
1049
677
  function noCompanionExtensionsResolved() {
1050
- return `${messages_getLoggingPrefix('warn')} No companion extensions resolved from the ${pintor.blue('extensions')} config.\nPoint each entry at an unpacked extension directory that contains a manifest.json, for example ./extensions/<name>/manifest.json.`;
678
+ return `${getLoggingPrefix('warn')} No companion extensions resolved from the ${pintor.blue('extensions')} config.\nPoint each entry at an unpacked extension directory that contains a manifest.json, for example ./extensions/<name>/manifest.json.`;
1051
679
  }
1052
680
  function describeThrown(error) {
1053
681
  if (error instanceof Error) return error.message || error.name || 'Error';
@@ -1064,21 +692,21 @@ function shapeOf(value) {
1064
692
  }
1065
693
  function configWrongShape(configPath, value) {
1066
694
  const functionHint = 'function' == typeof value ? `\nTo change the bundler config, export it as ${pintor.blue('export default {config: (config) => config}')}.` : '';
1067
- return `${messages_getLoggingPrefix('error')} ${pintor.blue('extension.config.js')} must export an object, found ${shapeOf(value)}.\n${fmt.label('PATH')} ${fmt.val(configPath)}${functionHint}`;
695
+ return `${getLoggingPrefix('error')} ${pintor.blue('extension.config.js')} must export an object, found ${shapeOf(value)}.\n${fmt.label('PATH')} ${fmt.val(configPath)}${functionHint}`;
1068
696
  }
1069
697
  function configUnknownKeys(configPath, keys, accepted) {
1070
- return `${messages_getLoggingPrefix('warn')} ${pintor.blue('extension.config.js')} declares ${1 === keys.length ? 'a key' : 'keys'} nothing reads: ${pintor.yellow(keys.join(', '))}.\n${fmt.label('PATH')} ${fmt.val(configPath)}\nAccepted keys are ${pintor.blue(accepted.join(', '))}.`;
698
+ return `${getLoggingPrefix('warn')} ${pintor.blue('extension.config.js')} declares ${1 === keys.length ? 'a key' : 'keys'} nothing reads: ${pintor.yellow(keys.join(', '))}.\n${fmt.label('PATH')} ${fmt.val(configPath)}\nAccepted keys are ${pintor.blue(accepted.join(', '))}.`;
1071
699
  }
1072
700
  function configLoadingError(configPath, error) {
1073
- return `${messages_getLoggingPrefix('error')} Couldn't load ${pintor.blue('extension.config.js')}.\n${fmt.label('PATH')} ${fmt.val(configPath)}\n${pintor.red(describeThrown(error))}\nFix the config file, then run the command again.`;
701
+ return `${getLoggingPrefix('error')} Couldn't load ${pintor.blue('extension.config.js')}.\n${fmt.label('PATH')} ${fmt.val(configPath)}\n${pintor.red(describeThrown(error))}\nFix the config file, then run the command again.`;
1074
702
  }
1075
703
  function buildCommandFailed(error) {
1076
704
  const message = (()=>{
1077
705
  if (error instanceof Error && error.message) return error.message;
1078
706
  return String(error || 'Unknown error');
1079
707
  })();
1080
- if (message.includes(messages_getLoggingPrefix('error'))) return message;
1081
- return `${messages_getLoggingPrefix('error')} ${pintor.red(fmt.truncate(message, 1200))}`;
708
+ if (message.includes(getLoggingPrefix('error'))) return message;
709
+ return `${getLoggingPrefix('error')} ${pintor.red(fmt.truncate(message, 1200))}`;
1082
710
  }
1083
711
  function devCommandFailed(error) {
1084
712
  const message = (()=>{
@@ -1086,17 +714,17 @@ function devCommandFailed(error) {
1086
714
  return String(error || 'Unknown error');
1087
715
  })();
1088
716
  const detail = hasChannelPrefix(message) ? stripChannelPrefix(message) : message;
1089
- return `${messages_getLoggingPrefix('error')} Dev mode failed.\n${pintor.red(fmt.truncate(detail, 1200))}`;
717
+ return `${getLoggingPrefix('error')} Dev mode failed.\n${pintor.red(fmt.truncate(detail, 1200))}`;
1090
718
  }
1091
719
  function safariInvalidBundleId(bundleId) {
1092
- return `${messages_getLoggingPrefix('error')} Can't use ${fmt.code(bundleId)} as a bundle identifier.\nUse letters, digits, hyphens and periods, with no empty segment (e.g. ${fmt.code('com.example.my-extension')}).`;
720
+ return `${getLoggingPrefix('error')} Can't use ${fmt.code(bundleId)} as a bundle identifier.\nUse letters, digits, hyphens and periods, with no empty segment (e.g. ${fmt.code('com.example.my-extension')}).`;
1093
721
  }
1094
722
  function safariBuildOutputNotFound(outputPath) {
1095
- return `${messages_getLoggingPrefix('error')} No build output to package for Safari.\n${pintor.gray('NOT FOUND')} ${pintor.underline(outputPath)}\nThe bundler emitted nothing there, so there is no extension to convert into an app.`;
723
+ return `${getLoggingPrefix('error')} No build output to package for Safari.\n${pintor.gray('NOT FOUND')} ${pintor.underline(outputPath)}\nThe bundler emitted nothing there, so there is no extension to convert into an app.`;
1096
724
  }
1097
725
  function managedDependencyCopyWarning(duplicates, configPath) {
1098
726
  const list = duplicates.map((d)=>`- ${pintor.yellow(d.name)} (Extension.js ships ${d.shipped})`).join('\n');
1099
- return `${messages_getLoggingPrefix('warn')} ${pintor.blue(__rspack_external_node_path_806ed179.basename(configPath))} loads its own copy of ${1 === duplicates.length ? 'a package' : 'packages'} Extension.js already ships.\n${list}\n${fmt.label('PATH')} ${fmt.val(configPath)}\nBoth copies take part in one build, and when their versions differ the build can break or behave differently.\nThe build goes on. If it misbehaves, install the version shown or drop the import.`;
727
+ return `${getLoggingPrefix('warn')} ${pintor.blue(__rspack_external_node_path_806ed179.basename(configPath))} loads its own copy of ${1 === duplicates.length ? 'a package' : 'packages'} Extension.js already ships.\n${list}\n${fmt.label('PATH')} ${fmt.val(configPath)}\nBoth copies take part in one build, and when their versions differ the build can break or behave differently.\nThe build goes on. If it misbehaves, install the version shown or drop the import.`;
1100
728
  }
1101
729
  function codedError(code, message) {
1102
730
  const error = new Error(message);
@@ -1312,7 +940,7 @@ async function importUrlSourceFromGithub(pathOrRemoteUrl, text) {
1312
940
  if (!candidate.subdir) return repoRoot;
1313
941
  const withSubdir = __rspack_external_node_path_806ed179.join(repoRoot, candidate.subdir);
1314
942
  if (__rspack_external_node_fs_1b05aee1.existsSync(withSubdir)) return withSubdir;
1315
- throw new Error(downloadedProjectFolderNotFound(repoRoot, [
943
+ throw codedError(CODES.E_PROJECT_DOWNLOAD_EMPTY, downloadedProjectFolderNotFound(repoRoot, [
1316
944
  candidate.subdir
1317
945
  ]));
1318
946
  } catch (error) {
@@ -1344,7 +972,7 @@ async function importUrlSourceFromGithub(pathOrRemoteUrl, text) {
1344
972
  const ghRoot = appeared.find((name)=>/-main$|-master$/.test(name));
1345
973
  return ghRoot ? __rspack_external_node_path_806ed179.join(cwd, ghRoot) : void 0;
1346
974
  })();
1347
- if (!landed) throw new Error(downloadedProjectFolderNotFound(cwd, candidates));
975
+ if (!landed) throw codedError(CODES.E_PROJECT_DOWNLOAD_EMPTY, downloadedProjectFolderNotFound(cwd, candidates));
1348
976
  writeRemoteSource(landed, pathOrRemoteUrl);
1349
977
  return {
1350
978
  projectPath: landed,
@@ -1565,102 +1193,4 @@ function resolveProjectStructureSync(projectPath, options = {}) {
1565
1193
  } : {}
1566
1194
  };
1567
1195
  }
1568
- function sessionStateDir(projectPath) {
1569
- return __rspack_external_node_path_806ed179.resolve(projectPath, '.extension-js');
1570
- }
1571
- function controlPortFilePath(projectPath, browser) {
1572
- return __rspack_external_node_path_806ed179.join(sessionStateDir(projectPath), `control-port-${browser}`);
1573
- }
1574
- function legacyControlPortFilePath(projectPath, browser) {
1575
- return __rspack_external_node_path_806ed179.join(browserArtifactsDir(projectPath, browser), 'control-port');
1576
- }
1577
- const CONTROL_TOKEN_FILE_PREFIX = 'control-token-';
1578
- function controlTokenPath(projectPath, browser) {
1579
- return __rspack_external_node_path_806ed179.join(sessionStateDir(projectPath), `${CONTROL_TOKEN_FILE_PREFIX}${browser}`);
1580
- }
1581
- function legacyControlTokenPath(projectPath) {
1582
- return __rspack_external_node_path_806ed179.join(sessionStateDir(projectPath), 'control.token');
1583
- }
1584
- function sessionArtifactsRootDir(projectPath) {
1585
- return __rspack_external_node_path_806ed179.resolve(projectPath, 'dist', 'extension-js');
1586
- }
1587
- const SESSION_ARTIFACTS_IGNORE_CONTENT = "# Extension.js session state: managed browser profiles (cookies, history,\n# logins), session logs and machine contracts. Personal data lives here:\n# this directory must never be committed or shipped.\n*\n";
1588
- function sessionArtifactsIgnoreFilePath(projectPath) {
1589
- return __rspack_external_node_path_806ed179.join(sessionArtifactsRootDir(projectPath), '.gitignore');
1590
- }
1591
- const PROJECT_ROOT_MARKERS = [
1592
- 'package.json',
1593
- 'deno.jsonc',
1594
- 'deno.json',
1595
- 'manifest.json'
1596
- ];
1597
- function holdsProjectRootMarker(projectPath) {
1598
- return PROJECT_ROOT_MARKERS.some((marker)=>__rspack_external_node_fs_1b05aee1.existsSync(__rspack_external_node_path_806ed179.join(projectPath, marker)));
1599
- }
1600
- function ensureSessionArtifactsIgnoreFile(projectPath) {
1601
- try {
1602
- if (!holdsProjectRootMarker(projectPath)) return;
1603
- const ignoreFile = sessionArtifactsIgnoreFilePath(projectPath);
1604
- if (__rspack_external_node_fs_1b05aee1.existsSync(ignoreFile)) return;
1605
- __rspack_external_node_fs_1b05aee1.mkdirSync(__rspack_external_node_path_806ed179.dirname(ignoreFile), {
1606
- recursive: true
1607
- });
1608
- __rspack_external_node_fs_1b05aee1.writeFileSync(ignoreFile, SESSION_ARTIFACTS_IGNORE_CONTENT);
1609
- } catch {}
1610
- }
1611
- function isAlreadyIgnoredByGit(projectPath) {
1612
- try {
1613
- const result = spawnSync('git', [
1614
- 'check-ignore',
1615
- '-q',
1616
- '--',
1617
- '.extension-js/'
1618
- ], {
1619
- cwd: projectPath,
1620
- stdio: 'ignore'
1621
- });
1622
- return 0 === result.status;
1623
- } catch {
1624
- return false;
1625
- }
1626
- }
1627
- function ensureSessionStateInProjectGitignore(projectPath) {
1628
- try {
1629
- const gitignorePath = __rspack_external_node_path_806ed179.resolve(projectPath, '.gitignore');
1630
- if (!__rspack_external_node_fs_1b05aee1.existsSync(gitignorePath)) return;
1631
- const content = __rspack_external_node_fs_1b05aee1.readFileSync(gitignorePath, 'utf8');
1632
- const lines = content.split(/\r?\n/).map((line)=>line.trim());
1633
- if (lines.includes('.extension-js') || lines.includes('.extension-js/')) return;
1634
- if (isAlreadyIgnoredByGit(projectPath)) return;
1635
- const prefix = content.length > 0 && !content.endsWith('\n') ? '\n' : '';
1636
- __rspack_external_node_fs_1b05aee1.appendFileSync(gitignorePath, `${prefix}\n# Extension.js local session state\n.extension-js\n`);
1637
- const notice = sessionStateIgnoreAdded(gitignorePath);
1638
- if (isMachineOutput()) console.error(notice);
1639
- else console.log(notice);
1640
- } catch {}
1641
- }
1642
- function browserArtifactsDir(projectPath, browser) {
1643
- return __rspack_external_node_path_806ed179.join(sessionArtifactsRootDir(projectPath), browser);
1644
- }
1645
- function browserProfileRootDir(projectPath, browser) {
1646
- return __rspack_external_node_path_806ed179.join(sessionArtifactsRootDir(projectPath), 'profiles', `${browser}-profile`);
1647
- }
1648
- function browserDistDir(projectPath, browser) {
1649
- return __rspack_external_node_path_806ed179.resolve(projectPath, 'dist', browser);
1650
- }
1651
- function readyContractPath(projectPath, browser) {
1652
- return __rspack_external_node_path_806ed179.join(browserArtifactsDir(projectPath, browser), 'ready.json');
1653
- }
1654
- function eventsPath(projectPath, browser) {
1655
- return __rspack_external_node_path_806ed179.join(browserArtifactsDir(projectPath, browser), 'events.ndjson');
1656
- }
1657
- function logsPath(projectPath, browser) {
1658
- return __rspack_external_node_path_806ed179.join(browserArtifactsDir(projectPath, browser), 'logs.ndjson');
1659
- }
1660
- function actionsPath(projectPath, browser) {
1661
- return __rspack_external_node_path_806ed179.join(browserArtifactsDir(projectPath, browser), 'actions.ndjson');
1662
- }
1663
- function buildSummaryPath(projectPath, browser) {
1664
- return __rspack_external_node_path_806ed179.join(browserArtifactsDir(projectPath, browser), 'build-summary.json');
1665
- }
1666
- export { CONTROL_TOKEN_FILE_PREFIX, actionsPath, addonLintDependencyAttribution, addonLintFailed, addonLintFailedDebug, addonLintFinding, addonLintMore, addonLintNotInstalled, addonLintSummary, anotherDevSessionActive, asAbsolute, attachLifecycleStream, authorInstallNotice, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserArtifactsDir, browserDistDir, browserLaunchFailed, browserProfileRootDir, browserRunnerDisabled, buildAssetsTree, buildCommandFailed, buildComplete, buildFailed, buildShareHint, buildSummaryPath, buildWarningsDetails, bundlerFatalError, bundlerRecompiling, codedError, collapseHomeDir, computePreviewOutputPath, configBrowserOrThrow, configLoadingError, configResolvedChangeIgnored, configUnknownKeys, configWrongShape, controlBridgeUnavailable, controlPortFilePath, controlTokenPath, createLifecycleStream, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, debugPreviewOutput, debugSplitChunksNarrowed, devCommandFailed, devServerHostRefused, devServerRestarting, devServerStartTimeout, devtoolsEngineFor, displayPath, downloadingText, emulatorViewerUrl, ensureSessionArtifactsIgnoreFile, ensureSessionStateInProjectGitignore, eventsPath, extensionJsRunnerError, extensionLoadRecovered, extensionLoadStillRefused, failedToDownloadOrWriteZIPFileError, failedToWriteZIPFileError, getDirs, getDistPath, getProjectStructure, humanLine, invalidRemoteZip, isUsingExperimentalConfig, legacyControlPortFilePath, legacyControlTokenPath, localZipNotFound, localZipUnreadable, logsPath, managedDependencyCopyWarning, manifestGoneDuringSession, manifestInvalidJson, messages_ready, needsInstall, noCompanionExtensionsResolved, noEntrypointsDetected, normalizeBrowser, notAZipArchive, operaBuildUnminified, packagingDistributionFiles, packagingSourceFiles, portInUse, previewHasNothingToRun, previewing, previewingCustomOutput, previewingSourceFallback, projectInstallFallbackToNpm, projectInstallInWorkspaceRoot, projectInstallScriptsDisabled, readyContractPath, relativeToDir, remoteSourceDestinationTaken, remoteZipDamaged, resolveProjectStructureSync, runnerCleanupError, runnerUncaughtException, runnerUnhandledRejection, runtimeChunkKeptInline, safariBuildOutputNotFound, safariInvalidBundleId, sessionArtifactsRootDir, sessionStateDir, shouldWarnPortConflict, spacerLine, starting, stripAnsi, toPosixPath, treeWithDistFilesBrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError, zipArtifactNotCreated, zipArtifactReady, zipEntryOutsideFolder, zipSkippedSymlinks };
1196
+ export { addonLintDependencyAttribution, addonLintFailed, addonLintFailedDebug, addonLintFinding, addonLintMore, addonLintNotInstalled, addonLintSummary, anotherDevSessionActive, anotherDevSessionRefused, asAbsolute, authorInstallNotice, browserLaunchFailed, buildAssetsTree, buildCommandFailed, buildComplete, buildFailed, buildShareHint, buildWarningsDetails, codedError, collapseHomeDir, computePreviewOutputPath, configBrowserOrThrow, configLoadingError, configResolvedChangeIgnored, configUnknownKeys, configWrongShape, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, debugPreviewOutput, debugSplitChunksNarrowed, devCommandFailed, devtoolsEngineFor, displayPath, downloadingText, extensionLoadRecovered, extensionLoadStillRefused, failedToDownloadOrWriteZIPFileError, failedToWriteZIPFileError, getDirs, getDistPath, getProjectStructure, invalidRemoteZip, isUsingExperimentalConfig, listOutputFiles, localZipNotFound, localZipUnreadable, managedDependencyCopyWarning, manifestInvalidJson, needsInstall, noCompanionExtensionsResolved, normalizeBrowser, notAZipArchive, operaBuildUnminified, packagingDistributionFiles, packagingSourceFiles, previewHasNothingToRun, previewing, previewingCustomOutput, previewingSourceFallback, projectInstallFallbackToNpm, projectInstallInWorkspaceRoot, projectInstallScriptsDisabled, relativeToDir, remoteSourceDestinationTaken, remoteZipDamaged, resolveProjectStructureSync, runtimeChunkKeptInline, safariBuildOutputNotFound, safariInvalidBundleId, sessionStateIgnoreAdded, starting, toPosixPath, treeWithDistFilesBrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, updatingTypeDefinitions, writingTypeDefinitions, writingTypeDefinitionsError, zipArtifactNotCreated, zipArtifactReady, zipEntryOutsideFolder, zipSkippedSymlinks };