dev-cockpit 0.2.4 → 0.2.6

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.
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EACX,OAAO,EAGP,MAAM,kBAAkB,CAAC;AAoB1B,MAAM,WAAW,iBAAiB;IACjC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+S5E"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EACX,OAAO,EAGP,MAAM,kBAAkB,CAAC;AAoB1B,MAAM,WAAW,iBAAiB;IACjC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuU5E"}
@@ -1 +1 @@
1
- {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/commands/mount.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAwBvD,MAAM,WAAW,mBAAmB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,WAAW,CAC1B,YAAY,EAAE,SAAS,KAAK,EAAE,EAC9B,cAAc,EAAE,SAAS,KAAK,EAAE,GAC9B,KAAK,EAAE,CAKT;AA0GD,wBAAsB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqEhF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkEtF;AAED,wBAAsB,iBAAiB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCrF"}
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/commands/mount.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAwBvD,MAAM,WAAW,mBAAmB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,WAAW,CAC1B,YAAY,EAAE,SAAS,KAAK,EAAE,EAC9B,cAAc,EAAE,SAAS,KAAK,EAAE,GAC9B,KAAK,EAAE,CAKT;AA0GD,wBAAsB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EhF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkEtF;AAED,wBAAsB,iBAAiB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCrF"}
@@ -234,7 +234,7 @@ export declare const BaseCockpitConfigSchema: z.ZodObject<{
234
234
  /** Which pane the cockpit lands on when it boots. Profile may override. */
235
235
  defaultPane: z.ZodDefault<z.ZodOptional<z.ZodEnum<["repos", "output", "health", "help"]>>>;
236
236
  /** Named keystroke-bound shell commands surfaced via the `:` palette. */
237
- actions: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
237
+ actions: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodObject<{
238
238
  id: z.ZodString;
239
239
  label: z.ZodString;
240
240
  command: z.ZodString;
@@ -255,6 +255,20 @@ export declare const BaseCockpitConfigSchema: z.ZodObject<{
255
255
  cwd?: string | undefined;
256
256
  key?: string | undefined;
257
257
  scope?: string | undefined;
258
+ }>, {
259
+ id: string;
260
+ label: string;
261
+ command: string;
262
+ cwd?: string | undefined;
263
+ key?: string | undefined;
264
+ scope?: string | undefined;
265
+ }, {
266
+ id: string;
267
+ label: string;
268
+ command: string;
269
+ cwd?: string | undefined;
270
+ key?: string | undefined;
271
+ scope?: string | undefined;
258
272
  }>, "many">>>;
259
273
  /**
260
274
  * Profile-specific config namespace. Each profile owns one key under here
@@ -276,12 +290,12 @@ export declare const BaseCockpitConfigSchema: z.ZodObject<{
276
290
  onTransitionTo?: string[] | undefined;
277
291
  } | undefined;
278
292
  }[];
279
- appName: string;
280
293
  repos: {
281
294
  path: string;
282
295
  id: string;
283
296
  label?: string | undefined;
284
297
  }[];
298
+ appName: string;
285
299
  highlights: {
286
300
  pattern: string;
287
301
  severity: "info" | "warn" | "error";
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,mFAAmF;AACnF,eAAO,MAAM,cAAc,IAAI,CAAC;AAmHhC,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAdlC;;;;;;WAMG;;QAEH,iDAAiD;;;;;;;;;IAwBjD,2EAA2E;;IAE3E,yEAAyE;;;;;;;;;;;;;;;;;;;;;;;IAEzE;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE,qBAAa,kBAAmB,SAAQ,KAAK;aAEzB,QAAQ,EAAE,MAAM;aAChB,KAAK,EAAE,OAAO;aACd,SAAS,EAAE,MAAM;gBAFjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM;CAOpC;AAED,qBAAa,qBAAsB,SAAQ,KAAK;aAE5B,QAAQ,EAAE,MAAM;aAChB,KAAK,EAAE,OAAO;gBADd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO;CAKjC;AAID,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC7C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,iBAAsB,GAC3B,iBAAiB,CA0CnB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,mFAAmF;AACnF,eAAO,MAAM,cAAc,IAAI,CAAC;AA+HhC,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAdlC;;;;;;WAMG;;QAEH,iDAAiD;;;;;;;;;IAwBjD,2EAA2E;;IAE3E,yEAAyE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEzE;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE,qBAAa,kBAAmB,SAAQ,KAAK;aAEzB,QAAQ,EAAE,MAAM;aAChB,KAAK,EAAE,OAAO;aACd,SAAS,EAAE,MAAM;gBAFjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM;CAOpC;AAED,qBAAa,qBAAsB,SAAQ,KAAK;aAE5B,QAAQ,EAAE,MAAM;aAChB,KAAK,EAAE,OAAO;gBADd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO;CAKjC;AAID,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC7C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,iBAAsB,GAC3B,iBAAiB,CA0CnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"subprocess.d.ts","sourceRoot":"","sources":["../../src/core/subprocess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IACxC,KAAK,EAAE,UAAU,CAAC;CACnB;AAaD,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE,YAAiB,GACtB,aAAa,CAiDf;AAED,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEvE;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,SAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAkB3F;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,cAAc,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBzE"}
1
+ {"version":3,"file":"subprocess.d.ts","sourceRoot":"","sources":["../../src/core/subprocess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AA6B/C,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IACxC,KAAK,EAAE,UAAU,CAAC;CACnB;AAaD,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE,YAAiB,GACtB,aAAa,CAyDf;AAED,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEvE;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,SAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAkB3F;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,cAAc,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBzE"}
package/dist/index.js CHANGED
@@ -79616,6 +79616,17 @@ var {
79616
79616
  } = getIpcExport();
79617
79617
 
79618
79618
  // src/core/subprocess.ts
79619
+ function killGroup(pid, signal) {
79620
+ if (pid === void 0) return;
79621
+ try {
79622
+ process.kill(-pid, signal);
79623
+ } catch {
79624
+ try {
79625
+ process.kill(pid, signal);
79626
+ } catch {
79627
+ }
79628
+ }
79629
+ }
79619
79630
  var ACTIVE = /* @__PURE__ */ new Set();
79620
79631
  var BY_TAG = /* @__PURE__ */ new Map();
79621
79632
  function spawnStream(cmd, args, opts = {}) {
@@ -79627,7 +79638,12 @@ function spawnStream(cmd, args, opts = {}) {
79627
79638
  reject: false,
79628
79639
  stdout: "pipe",
79629
79640
  stderr: "pipe",
79630
- ...opts.stdin ? { stdin: opts.stdin } : {}
79641
+ ...opts.stdin ? { stdin: opts.stdin } : {},
79642
+ // Detached → child gets its own process group (pgid === pid). Lets
79643
+ // killGroup() reap the whole subtree, including grandchildren a shell
79644
+ // wrapper forked. We still keep stdio piped above, so the child can't
79645
+ // outlive its streams when the parent exits cleanly via killAllSpawned().
79646
+ detached: true
79631
79647
  });
79632
79648
  if (opts.onStdout && child.stdout) {
79633
79649
  child.stdout.on("data", (chunk) => {
@@ -79649,7 +79665,7 @@ function spawnStream(cmd, args, opts = {}) {
79649
79665
  const handle = {
79650
79666
  exitCode,
79651
79667
  kill: (signal = "SIGTERM") => {
79652
- child.kill(signal);
79668
+ killGroup(child.pid, signal);
79653
79669
  },
79654
79670
  child
79655
79671
  };
@@ -79704,6 +79720,17 @@ async function killAllSpawned(sigkillAfterMs = 1500) {
79704
79720
  if (timer) clearTimeout(timer);
79705
79721
  await Promise.all(reaps);
79706
79722
  }
79723
+ var exitHookInstalled = false;
79724
+ function installExitHook() {
79725
+ if (exitHookInstalled) return;
79726
+ exitHookInstalled = true;
79727
+ process.once("exit", () => {
79728
+ for (const h2 of ACTIVE) {
79729
+ killGroup(h2.child.pid, "SIGKILL");
79730
+ }
79731
+ });
79732
+ }
79733
+ installExitHook();
79707
79734
 
79708
79735
  // src/core/notifier.ts
79709
79736
  function detectTransitions(prev, next) {
@@ -83953,6 +83980,9 @@ var ActionSchema = external_exports.object({
83953
83980
  cwd: external_exports.string().optional(),
83954
83981
  scope: external_exports.string().regex(/^(global|repos(:[\w-]+)?)$/, 'scope must be "global", "repos", or "repos:<id>"').optional(),
83955
83982
  key: external_exports.string().min(1).max(1).optional()
83983
+ }).refine((a2) => !(a2.scope?.startsWith("repos") && !a2.key), {
83984
+ message: "actions with scope 'repos' or 'repos:<id>' require a single-character `key` (the action panel can't surface them without one)",
83985
+ path: ["key"]
83956
83986
  });
83957
83987
  var MountSettingsSchema = external_exports.object({
83958
83988
  /**
@@ -91066,6 +91096,26 @@ async function devCommand(opts = {}) {
91066
91096
  for (const proc of config.processes) {
91067
91097
  spawnProcessById(proc.id);
91068
91098
  }
91099
+ let teardownStarted = false;
91100
+ const teardown = async (sig) => {
91101
+ if (teardownStarted) return;
91102
+ teardownStarted = true;
91103
+ try {
91104
+ if (dockerTailer) await dockerTailer.stop();
91105
+ if (bootResult.cleanup) await bootResult.cleanup();
91106
+ await killAllSpawned();
91107
+ } catch (err) {
91108
+ process.stderr.write(`dev-cockpit: cleanup error on ${sig}: ${String(err)}
91109
+ `);
91110
+ }
91111
+ process.exit(sig === "SIGTERM" ? 143 : sig === "SIGHUP" ? 129 : 130);
91112
+ };
91113
+ process.once("SIGTERM", () => {
91114
+ void teardown("SIGTERM");
91115
+ });
91116
+ process.once("SIGHUP", () => {
91117
+ void teardown("SIGHUP");
91118
+ });
91069
91119
  const dockerServices = (config.docker?.services ?? []).filter((s) => s.tail !== false);
91070
91120
  let dockerTailer = null;
91071
91121
  if (dockerServices.length > 0) {
@@ -92330,10 +92380,11 @@ function resolveOverlayPath(opts) {
92330
92380
  import fs14 from "node:fs";
92331
92381
  import path19 from "node:path";
92332
92382
  function applyManagedSymlinks(workspaceRoot, mounts, strategy) {
92333
- const report = { created: [], skipped: [] };
92383
+ const report = { created: [], replaced: [], skipped: [] };
92334
92384
  for (const m of mounts) {
92335
92385
  const linkPath = strategy.linkPath(m, workspaceRoot);
92336
92386
  if (!linkPath) continue;
92387
+ let preExistingRealDir = false;
92337
92388
  try {
92338
92389
  const lstat3 = fs14.lstatSync(linkPath);
92339
92390
  if (lstat3.isSymbolicLink()) {
@@ -92344,8 +92395,8 @@ function applyManagedSymlinks(workspaceRoot, mounts, strategy) {
92344
92395
  }
92345
92396
  fs14.unlinkSync(linkPath);
92346
92397
  } else if (lstat3.isDirectory()) {
92347
- report.skipped.push(linkPath);
92348
- continue;
92398
+ preExistingRealDir = true;
92399
+ fs14.rmSync(linkPath, { recursive: true, force: true });
92349
92400
  } else {
92350
92401
  fs14.unlinkSync(linkPath);
92351
92402
  }
@@ -92353,7 +92404,8 @@ function applyManagedSymlinks(workspaceRoot, mounts, strategy) {
92353
92404
  }
92354
92405
  fs14.mkdirSync(path19.dirname(linkPath), { recursive: true });
92355
92406
  fs14.symlinkSync(m.hostPath, linkPath);
92356
- report.created.push(linkPath);
92407
+ if (preExistingRealDir) report.replaced.push(linkPath);
92408
+ else report.created.push(linkPath);
92357
92409
  }
92358
92410
  return report;
92359
92411
  }
@@ -92556,7 +92608,14 @@ async function mountCommand(opts = {}) {
92556
92608
  const report = applyManagedSymlinks(workspaceRoot, selected, profile.mountSymlinks);
92557
92609
  for (const p of report.created) process.stdout.write(`dev-cockpit mount: symlink \u2192 ${p}
92558
92610
  `);
92559
- for (const p of report.skipped) process.stdout.write(`dev-cockpit mount: skipped (real dir) \u2192 ${p}
92611
+ for (const p of report.replaced) {
92612
+ process.stdout.write(
92613
+ `dev-cockpit mount: replaced real dir with symlink \u2192 ${p}
92614
+ (previous contents discarded; run \`mount clear\` to restore via composer/npm install)
92615
+ `
92616
+ );
92617
+ }
92618
+ for (const p of report.skipped) process.stdout.write(`dev-cockpit mount: skipped (could not replace) \u2192 ${p}
92560
92619
  `);
92561
92620
  }
92562
92621
  if (profile?.onMountApply) {