@wrongstack/plugins 0.308.1 → 0.308.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -14270,14 +14270,19 @@ function stripLauncherAtBoundary(command, launcher, valueTaking) {
14270
14270
  }
14271
14271
  return `${command.slice(0, match.index)}${boundary}${after.slice(consumed).replace(/^\s+/, "")}`;
14272
14272
  }
14273
+ var XARGS_OPTIONS = String.raw`(?:\s+(?:(?:-[InLsPjeE]|--(?:arg-file|replace|max-args|max-lines|max-chars|max-procs))\s+[^\s]+|-[^\s]+))*`;
14274
+ var COMMAND_BOUNDARY = String.raw`(?:^|[;&|\r\n]\s*|\{\s*|(?<![$(])\(\s*|\bxargs${XARGS_OPTIONS}\s+)`;
14273
14275
  function commandRecursivelyDeletes(command) {
14274
14276
  const stripped = stripTransparentLaunchers(maskNonExecutingHeredocBodies(command));
14275
- if (/(?:^|[;&|\r\n]\s*|\$\(\s*|\(\s*|`\s*)find\b[^;&|)`]*(?:-delete\b|-exec(?:dir)?\s+(?:[^\s;&|]+[\\/])?(?:rm|rmdir)\b)/i.test(
14277
+ if (/(?:^|[;&|\r\n]\s*|\{\s*|\$\(\s*|\(\s*|`\s*)find\b[^;&|)`]*(?:-delete\b|-exec(?:dir)?\s+(?:[^\s;&|]+[\\/])?(?:rm|rmdir)\b)/i.test(
14276
14278
  stripped
14277
14279
  )) {
14278
14280
  return true;
14279
14281
  }
14280
- const destructive = /(?:^|[;&|\r\n]\s*|\{\s*|\(\s*|\bxargs(?:\s+-[^\s]+)*\s+)(rm|rmdir|del|rd|Remove-Item)\s+((?:"[^"]*"|'[^']*'|\\.|\{[^}]*\}|\([^()]*\)|[^;&|\r\n}])+)/gi;
14282
+ const destructive = new RegExp(
14283
+ String.raw`${COMMAND_BOUNDARY}(rm|rmdir|del|rd|Remove-Item)\s+((?:"[^"]*"|'[^']*'|\\.|\{[^}]*\}|\([^()]*\)|[^;&|\r\n}])+)`,
14284
+ "gi"
14285
+ );
14281
14286
  let match = destructive.exec(stripped);
14282
14287
  while (match !== null) {
14283
14288
  const tool = match[1]?.toLowerCase();
@@ -14494,6 +14499,27 @@ ${remainingCommand}`;
14494
14499
  if (heredoc !== null) maskBody(heredoc.bodyStart, lines.length, heredoc.quoted);
14495
14500
  return lines.join("");
14496
14501
  }
14502
+ function stripSubshellClosers(raw) {
14503
+ let result = raw.trimEnd();
14504
+ while (result.endsWith(")")) {
14505
+ if (quoteIsEscaped(result, result.length - 1)) break;
14506
+ let quote = null;
14507
+ let depth = 0;
14508
+ for (let index = 0; index < result.length - 1; index += 1) {
14509
+ const char = result[index];
14510
+ if (isQuoteBoundary(result, index, quote)) {
14511
+ quote = quote === char ? null : char === "'" ? "'" : '"';
14512
+ continue;
14513
+ }
14514
+ if (quote !== null) continue;
14515
+ if (char === "(" && !quoteIsEscaped(result, index)) depth += 1;
14516
+ else if (char === ")" && !quoteIsEscaped(result, index)) depth -= 1;
14517
+ }
14518
+ if (depth > 0) break;
14519
+ result = result.slice(0, -1).trimEnd();
14520
+ }
14521
+ return result;
14522
+ }
14497
14523
  function destructiveTargets(command) {
14498
14524
  return destructiveTargetsAtDepth(command, 0);
14499
14525
  }
@@ -14540,20 +14566,26 @@ function destructiveTargetsAtDepth(command, depth) {
14540
14566
  }
14541
14567
  targets.push(...destructiveTargetsAtDepth(executableBody, depth + 1));
14542
14568
  }
14543
- const destructive = /(?:^|[;&|\r\n]\s*|\{\s*|(?<![$(])\(\s*|\bxargs(?:\s+-[^\s]+)*\s+)(?:sudo\s+)?(rm|rmdir|del|rd|Remove-Item|unlink|truncate|shred|mv)\s+((?:"[^"]*"|'[^']*'|\\.|\{[^}]*\}|\([^()]*\)|[^;&|\r\n}])+)/gi;
14569
+ const destructive = new RegExp(
14570
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(rm|rmdir|del|rd|Remove-Item|unlink|truncate|shred|mv)\s+((?:"[^"]*"|'[^']*'|\\.|\{[^}]*\}|\([^()]*\)|[^;&|\r\n}])+)`,
14571
+ "gi"
14572
+ );
14544
14573
  let m = destructive.exec(normalizedCommand);
14545
14574
  while (m !== null) {
14546
14575
  if (!tokenIsQuoted(m, m[1] ?? "")) targets.push(...shellArgs(m[2] ?? ""));
14547
14576
  m = destructive.exec(normalizedCommand);
14548
14577
  }
14549
- const copy = /(?:^|[;&|\r\n]\s*)(?:sudo\s+)?(cp|install)\s+([^;&|\r\n]+)/gi;
14578
+ const copy = new RegExp(
14579
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(cp|install)\s+([^;&|\r\n]+)`,
14580
+ "gi"
14581
+ );
14550
14582
  let c = copy.exec(normalizedCommand);
14551
14583
  while (c !== null) {
14552
14584
  if (tokenIsQuoted(c, c[1] ?? "")) {
14553
14585
  c = copy.exec(normalizedCommand);
14554
14586
  continue;
14555
14587
  }
14556
- const tokens = shellTokens(c[2] ?? "");
14588
+ const tokens = shellTokens(stripSubshellClosers(c[2] ?? ""));
14557
14589
  let destination;
14558
14590
  for (let index = 0; index < tokens.length; index += 1) {
14559
14591
  const token = tokens[index];
@@ -14570,23 +14602,32 @@ function destructiveTargetsAtDepth(command, depth) {
14570
14602
  if (destination) targets.push(destination);
14571
14603
  c = copy.exec(normalizedCommand);
14572
14604
  }
14573
- const tee = /(?:^|[;&|\r\n]\s*)(?:sudo\s+)?(tee)\s+([^;&|\r\n]+)/gi;
14605
+ const tee = new RegExp(
14606
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(tee)\s+([^;&|\r\n]+)`,
14607
+ "gi"
14608
+ );
14574
14609
  let t = tee.exec(normalizedCommand);
14575
14610
  while (t !== null) {
14576
14611
  if (!tokenIsQuoted(t, t[1] ?? "")) targets.push(...shellArgs(t[2] ?? ""));
14577
14612
  t = tee.exec(normalizedCommand);
14578
14613
  }
14579
- const dd = /(?:^|[;&|\r\n]\s*)(?:sudo\s+)?(dd)\s+([^;&|\r\n]+)/gi;
14614
+ const dd = new RegExp(
14615
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(dd)\s+([^;&|\r\n]+)`,
14616
+ "gi"
14617
+ );
14580
14618
  let d = dd.exec(normalizedCommand);
14581
14619
  while (d !== null) {
14582
14620
  if (!tokenIsQuoted(d, d[1] ?? "")) {
14583
14621
  const outputMatch = /(?:^|\s)of=("[^"]*"|'[^']*'|[^\s]+)/i.exec(d[2] ?? "");
14584
- const output = outputMatch?.[1]?.replace(/^['"]|['"]$/g, "");
14622
+ const output = outputMatch?.[1] ? stripSubshellClosers(outputMatch[1]).replace(/^['"]|['"]$/g, "") : void 0;
14585
14623
  if (output) targets.push(output);
14586
14624
  }
14587
14625
  d = dd.exec(normalizedCommand);
14588
14626
  }
14589
- const overwrite = /(?:^|[;&|\r\n]\s*)(?:sudo\s+)?(sed|ln)\s+([^;&|\r\n]+)/gi;
14627
+ const overwrite = new RegExp(
14628
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(sed|ln)\s+([^;&|\r\n]+)`,
14629
+ "gi"
14630
+ );
14590
14631
  let o = overwrite.exec(normalizedCommand);
14591
14632
  while (o !== null) {
14592
14633
  const rawArgs = o[2] ?? "";
@@ -14604,7 +14645,10 @@ function destructiveTargetsAtDepth(command, depth) {
14604
14645
  }
14605
14646
  o = overwrite.exec(normalizedCommand);
14606
14647
  }
14607
- const xargsPipeline = /\b(?:echo|printf)\s+([^|]+)\|\s*xargs(?:\s+-[^\s]+)*\s+(?:sudo\s+)?(?:rm|rmdir|del|unlink|truncate|shred)\b/gi;
14648
+ const xargsPipeline = new RegExp(
14649
+ String.raw`\b(?:echo|printf)\s+([^|]+)\|\s*xargs${XARGS_OPTIONS}\s+(?:sudo\s+)?(?:rm|rmdir|del|unlink|truncate|shred)\b`,
14650
+ "gi"
14651
+ );
14608
14652
  let x = xargsPipeline.exec(normalizedCommand);
14609
14653
  while (x !== null) {
14610
14654
  if (!tokenIsQuoted(x, "xargs")) targets.push(...shellArgs(x[1] ?? ""));
@@ -14721,7 +14765,7 @@ function destructiveTargetsAtDepth(command, depth) {
14721
14765
  targets.push(gitTarget("."));
14722
14766
  }
14723
14767
  }
14724
- const findDelete = /(?:^|[;&|\r\n]\s*|\$\(\s*|\(\s*|`\s*)find\b([^;&|)`]*(?:\s-delete(?:\s|$)|\s-exec(?:dir)?\s+(?:[^\s;&|]+[\\/])?(?:rm|rmdir)\b)[^;&|)`]*)/gi;
14768
+ const findDelete = /(?:^|[;&|\r\n]\s*|\{\s*|\$\(\s*|\(\s*|`\s*)find\b([^;&|)`]*(?:\s-delete(?:[\s;})]|$)|\s-exec(?:dir)?\s+(?:[^\s;&|]+[\\/])?(?:rm|rmdir)\b)[^;&|)`]*)/gi;
14725
14769
  let f = findDelete.exec(normalizedCommand);
14726
14770
  while (f !== null) {
14727
14771
  const tokens = shellTokens(f[1] ?? "");
@@ -15154,10 +15198,19 @@ var plugin39 = {
15154
15198
  const ti = input.toolInput ?? {};
15155
15199
  const command = typeof ti["command"] === "string" ? ti["command"] : "";
15156
15200
  const commandArgs = Array.isArray(ti["args"]) ? ti["args"].filter((arg) => typeof arg === "string") : [];
15157
- const commandForInspection = [
15158
- command,
15159
- ...commandArgs.map((arg) => /^[\w./:@%+=,-]+$/.test(arg) ? arg : JSON.stringify(arg))
15160
- ].join(" ");
15201
+ const serializeArgForInspection = (arg) => {
15202
+ if (/^[\w./:@%+=,-]+$/.test(arg)) return arg;
15203
+ const assignment = /^([A-Za-z_]\w*)=(.+)$/.exec(arg);
15204
+ const key = assignment?.[1];
15205
+ const value = assignment?.[2];
15206
+ if (key !== void 0 && value !== void 0) {
15207
+ return `${key}="${value.replaceAll('"', "")}"`;
15208
+ }
15209
+ return JSON.stringify(arg);
15210
+ };
15211
+ const commandForInspection = [command, ...commandArgs.map(serializeArgForInspection)].join(
15212
+ " "
15213
+ );
15161
15214
  if (command && executesShell({
15162
15215
  toolName: input.toolName,
15163
15216
  toolInput: ti,
@@ -562,14 +562,19 @@ function stripLauncherAtBoundary(command, launcher, valueTaking) {
562
562
  }
563
563
  return `${command.slice(0, match.index)}${boundary}${after.slice(consumed).replace(/^\s+/, "")}`;
564
564
  }
565
+ var XARGS_OPTIONS = String.raw`(?:\s+(?:(?:-[InLsPjeE]|--(?:arg-file|replace|max-args|max-lines|max-chars|max-procs))\s+[^\s]+|-[^\s]+))*`;
566
+ var COMMAND_BOUNDARY = String.raw`(?:^|[;&|\r\n]\s*|\{\s*|(?<![$(])\(\s*|\bxargs${XARGS_OPTIONS}\s+)`;
565
567
  function commandRecursivelyDeletes(command) {
566
568
  const stripped = stripTransparentLaunchers(maskNonExecutingHeredocBodies(command));
567
- if (/(?:^|[;&|\r\n]\s*|\$\(\s*|\(\s*|`\s*)find\b[^;&|)`]*(?:-delete\b|-exec(?:dir)?\s+(?:[^\s;&|]+[\\/])?(?:rm|rmdir)\b)/i.test(
569
+ if (/(?:^|[;&|\r\n]\s*|\{\s*|\$\(\s*|\(\s*|`\s*)find\b[^;&|)`]*(?:-delete\b|-exec(?:dir)?\s+(?:[^\s;&|]+[\\/])?(?:rm|rmdir)\b)/i.test(
568
570
  stripped
569
571
  )) {
570
572
  return true;
571
573
  }
572
- const destructive = /(?:^|[;&|\r\n]\s*|\{\s*|\(\s*|\bxargs(?:\s+-[^\s]+)*\s+)(rm|rmdir|del|rd|Remove-Item)\s+((?:"[^"]*"|'[^']*'|\\.|\{[^}]*\}|\([^()]*\)|[^;&|\r\n}])+)/gi;
574
+ const destructive = new RegExp(
575
+ String.raw`${COMMAND_BOUNDARY}(rm|rmdir|del|rd|Remove-Item)\s+((?:"[^"]*"|'[^']*'|\\.|\{[^}]*\}|\([^()]*\)|[^;&|\r\n}])+)`,
576
+ "gi"
577
+ );
573
578
  let match = destructive.exec(stripped);
574
579
  while (match !== null) {
575
580
  const tool = match[1]?.toLowerCase();
@@ -786,6 +791,27 @@ ${remainingCommand}`;
786
791
  if (heredoc !== null) maskBody(heredoc.bodyStart, lines.length, heredoc.quoted);
787
792
  return lines.join("");
788
793
  }
794
+ function stripSubshellClosers(raw) {
795
+ let result = raw.trimEnd();
796
+ while (result.endsWith(")")) {
797
+ if (quoteIsEscaped(result, result.length - 1)) break;
798
+ let quote = null;
799
+ let depth = 0;
800
+ for (let index = 0; index < result.length - 1; index += 1) {
801
+ const char = result[index];
802
+ if (isQuoteBoundary(result, index, quote)) {
803
+ quote = quote === char ? null : char === "'" ? "'" : '"';
804
+ continue;
805
+ }
806
+ if (quote !== null) continue;
807
+ if (char === "(" && !quoteIsEscaped(result, index)) depth += 1;
808
+ else if (char === ")" && !quoteIsEscaped(result, index)) depth -= 1;
809
+ }
810
+ if (depth > 0) break;
811
+ result = result.slice(0, -1).trimEnd();
812
+ }
813
+ return result;
814
+ }
789
815
  function destructiveTargets(command) {
790
816
  return destructiveTargetsAtDepth(command, 0);
791
817
  }
@@ -832,20 +858,26 @@ function destructiveTargetsAtDepth(command, depth) {
832
858
  }
833
859
  targets.push(...destructiveTargetsAtDepth(executableBody, depth + 1));
834
860
  }
835
- const destructive = /(?:^|[;&|\r\n]\s*|\{\s*|(?<![$(])\(\s*|\bxargs(?:\s+-[^\s]+)*\s+)(?:sudo\s+)?(rm|rmdir|del|rd|Remove-Item|unlink|truncate|shred|mv)\s+((?:"[^"]*"|'[^']*'|\\.|\{[^}]*\}|\([^()]*\)|[^;&|\r\n}])+)/gi;
861
+ const destructive = new RegExp(
862
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(rm|rmdir|del|rd|Remove-Item|unlink|truncate|shred|mv)\s+((?:"[^"]*"|'[^']*'|\\.|\{[^}]*\}|\([^()]*\)|[^;&|\r\n}])+)`,
863
+ "gi"
864
+ );
836
865
  let m = destructive.exec(normalizedCommand);
837
866
  while (m !== null) {
838
867
  if (!tokenIsQuoted(m, m[1] ?? "")) targets.push(...shellArgs(m[2] ?? ""));
839
868
  m = destructive.exec(normalizedCommand);
840
869
  }
841
- const copy = /(?:^|[;&|\r\n]\s*)(?:sudo\s+)?(cp|install)\s+([^;&|\r\n]+)/gi;
870
+ const copy = new RegExp(
871
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(cp|install)\s+([^;&|\r\n]+)`,
872
+ "gi"
873
+ );
842
874
  let c = copy.exec(normalizedCommand);
843
875
  while (c !== null) {
844
876
  if (tokenIsQuoted(c, c[1] ?? "")) {
845
877
  c = copy.exec(normalizedCommand);
846
878
  continue;
847
879
  }
848
- const tokens = shellTokens(c[2] ?? "");
880
+ const tokens = shellTokens(stripSubshellClosers(c[2] ?? ""));
849
881
  let destination;
850
882
  for (let index = 0; index < tokens.length; index += 1) {
851
883
  const token = tokens[index];
@@ -862,23 +894,32 @@ function destructiveTargetsAtDepth(command, depth) {
862
894
  if (destination) targets.push(destination);
863
895
  c = copy.exec(normalizedCommand);
864
896
  }
865
- const tee = /(?:^|[;&|\r\n]\s*)(?:sudo\s+)?(tee)\s+([^;&|\r\n]+)/gi;
897
+ const tee = new RegExp(
898
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(tee)\s+([^;&|\r\n]+)`,
899
+ "gi"
900
+ );
866
901
  let t = tee.exec(normalizedCommand);
867
902
  while (t !== null) {
868
903
  if (!tokenIsQuoted(t, t[1] ?? "")) targets.push(...shellArgs(t[2] ?? ""));
869
904
  t = tee.exec(normalizedCommand);
870
905
  }
871
- const dd = /(?:^|[;&|\r\n]\s*)(?:sudo\s+)?(dd)\s+([^;&|\r\n]+)/gi;
906
+ const dd = new RegExp(
907
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(dd)\s+([^;&|\r\n]+)`,
908
+ "gi"
909
+ );
872
910
  let d = dd.exec(normalizedCommand);
873
911
  while (d !== null) {
874
912
  if (!tokenIsQuoted(d, d[1] ?? "")) {
875
913
  const outputMatch = /(?:^|\s)of=("[^"]*"|'[^']*'|[^\s]+)/i.exec(d[2] ?? "");
876
- const output = outputMatch?.[1]?.replace(/^['"]|['"]$/g, "");
914
+ const output = outputMatch?.[1] ? stripSubshellClosers(outputMatch[1]).replace(/^['"]|['"]$/g, "") : void 0;
877
915
  if (output) targets.push(output);
878
916
  }
879
917
  d = dd.exec(normalizedCommand);
880
918
  }
881
- const overwrite = /(?:^|[;&|\r\n]\s*)(?:sudo\s+)?(sed|ln)\s+([^;&|\r\n]+)/gi;
919
+ const overwrite = new RegExp(
920
+ String.raw`${COMMAND_BOUNDARY}(?:sudo\s+)?(sed|ln)\s+([^;&|\r\n]+)`,
921
+ "gi"
922
+ );
882
923
  let o = overwrite.exec(normalizedCommand);
883
924
  while (o !== null) {
884
925
  const rawArgs = o[2] ?? "";
@@ -896,7 +937,10 @@ function destructiveTargetsAtDepth(command, depth) {
896
937
  }
897
938
  o = overwrite.exec(normalizedCommand);
898
939
  }
899
- const xargsPipeline = /\b(?:echo|printf)\s+([^|]+)\|\s*xargs(?:\s+-[^\s]+)*\s+(?:sudo\s+)?(?:rm|rmdir|del|unlink|truncate|shred)\b/gi;
940
+ const xargsPipeline = new RegExp(
941
+ String.raw`\b(?:echo|printf)\s+([^|]+)\|\s*xargs${XARGS_OPTIONS}\s+(?:sudo\s+)?(?:rm|rmdir|del|unlink|truncate|shred)\b`,
942
+ "gi"
943
+ );
900
944
  let x = xargsPipeline.exec(normalizedCommand);
901
945
  while (x !== null) {
902
946
  if (!tokenIsQuoted(x, "xargs")) targets.push(...shellArgs(x[1] ?? ""));
@@ -1013,7 +1057,7 @@ function destructiveTargetsAtDepth(command, depth) {
1013
1057
  targets.push(gitTarget("."));
1014
1058
  }
1015
1059
  }
1016
- const findDelete = /(?:^|[;&|\r\n]\s*|\$\(\s*|\(\s*|`\s*)find\b([^;&|)`]*(?:\s-delete(?:\s|$)|\s-exec(?:dir)?\s+(?:[^\s;&|]+[\\/])?(?:rm|rmdir)\b)[^;&|)`]*)/gi;
1060
+ const findDelete = /(?:^|[;&|\r\n]\s*|\{\s*|\$\(\s*|\(\s*|`\s*)find\b([^;&|)`]*(?:\s-delete(?:[\s;})]|$)|\s-exec(?:dir)?\s+(?:[^\s;&|]+[\\/])?(?:rm|rmdir)\b)[^;&|)`]*)/gi;
1017
1061
  let f = findDelete.exec(normalizedCommand);
1018
1062
  while (f !== null) {
1019
1063
  const tokens = shellTokens(f[1] ?? "");
@@ -1471,10 +1515,19 @@ var plugin = {
1471
1515
  const ti = input.toolInput ?? {};
1472
1516
  const command = typeof ti["command"] === "string" ? ti["command"] : "";
1473
1517
  const commandArgs = Array.isArray(ti["args"]) ? ti["args"].filter((arg) => typeof arg === "string") : [];
1474
- const commandForInspection = [
1475
- command,
1476
- ...commandArgs.map((arg) => /^[\w./:@%+=,-]+$/.test(arg) ? arg : JSON.stringify(arg))
1477
- ].join(" ");
1518
+ const serializeArgForInspection = (arg) => {
1519
+ if (/^[\w./:@%+=,-]+$/.test(arg)) return arg;
1520
+ const assignment = /^([A-Za-z_]\w*)=(.+)$/.exec(arg);
1521
+ const key = assignment?.[1];
1522
+ const value = assignment?.[2];
1523
+ if (key !== void 0 && value !== void 0) {
1524
+ return `${key}="${value.replaceAll('"', "")}"`;
1525
+ }
1526
+ return JSON.stringify(arg);
1527
+ };
1528
+ const commandForInspection = [command, ...commandArgs.map(serializeArgForInspection)].join(
1529
+ " "
1530
+ );
1478
1531
  if (command && executesShell({
1479
1532
  toolName: input.toolName,
1480
1533
  toolInput: ti,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/plugins",
3
- "version": "0.308.1",
3
+ "version": "0.308.2",
4
4
  "description": "Official WrongStack collection of focused plugins for code quality, security, observability, planning, and agent coordination",
5
5
  "license": "MIT",
6
6
  "author": "ECOSTACK TECHNOLOGY OÜ",
@@ -303,8 +303,8 @@
303
303
  "vitest": "^4.1.10"
304
304
  },
305
305
  "dependencies": {
306
- "@wrongstack/core": "0.308.1",
307
- "@wrongstack/tools": "0.308.1"
306
+ "@wrongstack/core": "0.308.2",
307
+ "@wrongstack/tools": "0.308.2"
308
308
  },
309
309
  "scripts": {
310
310
  "build": "node ../../scripts/build-package.mjs",