autoremediator 0.13.0 → 0.14.0

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,5 +1,5 @@
1
1
  // src/api/options-schema.ts
2
- var PACKAGE_MANAGER_VALUES = ["npm", "pnpm", "yarn"];
2
+ var PACKAGE_MANAGER_VALUES = ["npm", "pnpm", "yarn", "bun", "deno"];
3
3
  var LLM_PROVIDER_VALUES = ["remote", "local"];
4
4
  var PROVENANCE_SOURCE_VALUES = ["cli", "sdk", "mcp", "openapi", "unknown"];
5
5
  var OPTION_DESCRIPTIONS = {
@@ -296,21 +296,26 @@ function createUpdateOutdatedOptionSchemaProperties() {
296
296
  // src/api/patches/inspection.ts
297
297
  import { existsSync as existsSync4 } from "fs";
298
298
  import { readdir, readFile as readFile2, stat } from "fs/promises";
299
- import { join as join3 } from "path";
299
+ import { join as join4 } from "path";
300
300
 
301
301
  // src/remediation/strategies/patch-utils.ts
302
- import { existsSync as existsSync2, mkdirSync, writeFileSync, readFileSync } from "fs";
303
- import { join as join2 } from "path";
302
+ import { existsSync as existsSync2, mkdirSync, writeFileSync, readFileSync as readFileSync2 } from "fs";
303
+ import { join as join3 } from "path";
304
304
  import { execa as execa2 } from "execa";
305
305
 
306
306
  // src/platform/package-manager/index.ts
307
307
  import { existsSync } from "fs";
308
- import { join } from "path";
308
+ import { join as join2 } from "path";
309
309
  import { execa } from "execa";
310
310
 
311
311
  // src/platform/package-manager/list-parser.ts
312
+ import { readFileSync } from "fs";
313
+ import { join } from "path";
312
314
  function parsePackageManagerListOutput(pm, stdout) {
313
315
  const versions = /* @__PURE__ */ new Map();
316
+ if (pm === "bun") {
317
+ return parseBunListOutput(stdout, versions);
318
+ }
314
319
  if (!stdout.trim()) return versions;
315
320
  if (pm === "yarn") {
316
321
  return parseYarnListOutput(stdout, versions);
@@ -360,6 +365,61 @@ function collectDependencyTree(tree, versions) {
360
365
  collectDependencyTree(entry.dependencies, versions);
361
366
  }
362
367
  }
368
+ function parseBunListOutput(stdout, versions) {
369
+ const lines = stdout.split("\n").map((line) => line.replace(/^[\s│├└─]+/, "").trim()).filter(Boolean);
370
+ for (const line of lines) {
371
+ const at = line.lastIndexOf("@");
372
+ if (at <= 0) continue;
373
+ const name = line.slice(0, at);
374
+ const version = line.slice(at + 1);
375
+ if (name && version) {
376
+ versions.set(name, version);
377
+ }
378
+ }
379
+ return versions;
380
+ }
381
+ function resolveDenoInventory(cwd) {
382
+ const versions = /* @__PURE__ */ new Map();
383
+ let raw;
384
+ try {
385
+ raw = readFileSync(join(cwd, "deno.lock"), "utf8");
386
+ } catch {
387
+ return versions;
388
+ }
389
+ let lock;
390
+ try {
391
+ lock = JSON.parse(raw);
392
+ } catch {
393
+ return versions;
394
+ }
395
+ if (!lock || typeof lock !== "object") return versions;
396
+ const lockObj = lock;
397
+ const packages = lockObj["packages"];
398
+ if (packages && typeof packages === "object") {
399
+ const pkgsObj = packages;
400
+ const npmMap = pkgsObj["npm"];
401
+ if (npmMap && typeof npmMap === "object") {
402
+ for (const key of Object.keys(npmMap)) {
403
+ extractNameVersion(key, versions);
404
+ }
405
+ return versions;
406
+ }
407
+ for (const key of Object.keys(pkgsObj)) {
408
+ const stripped = key.startsWith("npm:") ? key.slice(4) : key;
409
+ extractNameVersion(stripped, versions);
410
+ }
411
+ }
412
+ return versions;
413
+ }
414
+ function extractNameVersion(spec, versions) {
415
+ const at = spec.lastIndexOf("@");
416
+ if (at <= 0) return;
417
+ const name = spec.slice(0, at);
418
+ const version = spec.slice(at + 1);
419
+ if (name && version) {
420
+ versions.set(name, version);
421
+ }
422
+ }
363
423
 
364
424
  // src/platform/package-manager/index.ts
365
425
  async function getYarnMajorVersion(cwd) {
@@ -372,8 +432,10 @@ async function getYarnMajorVersion(cwd) {
372
432
  }
373
433
  }
374
434
  function detectPackageManager(cwd) {
375
- if (existsSync(join(cwd, "pnpm-lock.yaml"))) return "pnpm";
376
- if (existsSync(join(cwd, "yarn.lock"))) return "yarn";
435
+ if (existsSync(join2(cwd, "pnpm-lock.yaml"))) return "pnpm";
436
+ if (existsSync(join2(cwd, "yarn.lock"))) return "yarn";
437
+ if (existsSync(join2(cwd, "bun.lockb")) || existsSync(join2(cwd, "bun.lock"))) return "bun";
438
+ if (existsSync(join2(cwd, "deno.lock"))) return "deno";
377
439
  return "npm";
378
440
  }
379
441
  function withWorkspace(command, pm, workspace) {
@@ -390,6 +452,20 @@ function resolveInstallCommand(pm, constraints, yarnMajor) {
390
452
  const installMode = constraints?.installMode ?? "deterministic";
391
453
  const preferOfflineOverride = constraints?.installPreferOffline;
392
454
  const frozenOverride = constraints?.enforceFrozenLockfile;
455
+ if (pm === "bun") {
456
+ const frozen = frozenOverride ?? installMode === "deterministic";
457
+ const command2 = ["bun", "install"];
458
+ if (frozen) command2.push("--frozen-lockfile");
459
+ return withWorkspace(command2, pm, constraints?.workspace);
460
+ }
461
+ if (pm === "deno") {
462
+ const frozen = frozenOverride ?? installMode === "deterministic";
463
+ const preferOffline = preferOfflineOverride ?? installMode === "prefer-offline";
464
+ const command2 = ["deno", "install"];
465
+ if (frozen) command2.push("--frozen");
466
+ if (preferOffline && !frozen) command2.push("--cache-only");
467
+ return withWorkspace(command2, pm, constraints?.workspace);
468
+ }
393
469
  const includePreferOffline = pm !== "yarn" && (preferOfflineOverride ?? installMode !== "standard");
394
470
  let includeFrozenLockfile = pm !== "npm" && (frozenOverride ?? installMode === "deterministic");
395
471
  if (frozenOverride === false) {
@@ -410,22 +486,36 @@ function resolveInstallCommand(pm, constraints, yarnMajor) {
410
486
  return withWorkspace(command, pm, constraints?.workspace);
411
487
  }
412
488
  function resolveListCommand(pm, constraints) {
413
- const base = pm === "pnpm" ? ["pnpm", "list", "--json", "--depth", "99"] : pm === "yarn" ? ["yarn", "list", "--json"] : ["npm", "list", "--json", "--all"];
489
+ if (pm === "deno") {
490
+ return [];
491
+ }
492
+ const base = pm === "pnpm" ? ["pnpm", "list", "--json", "--depth", "99"] : pm === "yarn" ? ["yarn", "list", "--json"] : pm === "bun" ? ["bun", "pm", "ls", "--all"] : ["npm", "list", "--json", "--all"];
414
493
  return withWorkspace(base, pm, constraints?.workspace);
415
494
  }
416
495
  function resolveTestCommand(pm, constraints) {
417
- const base = pm === "pnpm" ? ["pnpm", "test"] : pm === "yarn" ? ["yarn", "test"] : ["npm", "test"];
496
+ const base = pm === "pnpm" ? ["pnpm", "test"] : pm === "yarn" ? ["yarn", "test"] : pm === "bun" ? ["bun", "test"] : pm === "deno" ? ["deno", "test"] : ["npm", "test"];
418
497
  return withWorkspace(base, pm, constraints?.workspace);
419
498
  }
420
499
  function resolveAuditCommand(pm, constraints) {
500
+ if (pm === "deno") {
501
+ throw new Error(
502
+ "Deno does not support a native audit command. Use --input with a SARIF or npm-audit scan file instead."
503
+ );
504
+ }
421
505
  const base = pm === "yarn" ? ["yarn", "audit", "--json"] : [pm, "audit", "--json"];
422
506
  return withWorkspace(base, pm, constraints?.workspace);
423
507
  }
424
508
  function resolveWhyCommand(pm, packageName, constraints) {
509
+ if (pm === "deno") return [];
510
+ if (pm === "bun") {
511
+ const base2 = ["bun", "pm", "why", packageName];
512
+ return withWorkspace(base2, pm, constraints?.workspace);
513
+ }
425
514
  const base = pm === "npm" ? ["npm", "explain", packageName] : [pm, "why", packageName];
426
515
  return withWorkspace(base, pm, constraints?.workspace);
427
516
  }
428
517
  function resolveDedupeCommand(pm, constraints) {
518
+ if (pm === "bun" || pm === "deno") return [];
429
519
  const base = [pm, "dedupe"];
430
520
  return withWorkspace(base, pm, constraints?.workspace);
431
521
  }
@@ -452,6 +542,28 @@ function getPackageManagerCommands(pm) {
452
542
  lockfileName: "yarn.lock"
453
543
  };
454
544
  }
545
+ if (pm === "bun") {
546
+ return {
547
+ install: ["bun", "install"],
548
+ installPreferOffline: ["bun", "install"],
549
+ installDeterministic: resolveInstallCommand("bun", { installMode: "deterministic" }),
550
+ installDev: (pkg) => ["bun", "add", "-d", pkg],
551
+ test: ["bun", "test"],
552
+ list: ["bun", "pm", "ls", "--all"],
553
+ lockfileName: "bun.lockb"
554
+ };
555
+ }
556
+ if (pm === "deno") {
557
+ return {
558
+ install: ["deno", "install"],
559
+ installPreferOffline: ["deno", "install", "--cache-only"],
560
+ installDeterministic: resolveInstallCommand("deno", { installMode: "deterministic" }),
561
+ installDev: (pkg) => ["deno", "add", pkg],
562
+ test: ["deno", "test"],
563
+ list: [],
564
+ lockfileName: "deno.lock"
565
+ };
566
+ }
455
567
  return {
456
568
  install: ["npm", "install"],
457
569
  installPreferOffline: ["npm", "install", "--prefer-offline"],
@@ -555,7 +667,7 @@ async function listPatchArtifacts(options = {}) {
555
667
  return [];
556
668
  }
557
669
  const entries = await readdir(patchesDirPath, { withFileTypes: true });
558
- const patchFiles = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".patch")).map((entry) => join3(patchesDirPath, entry.name)).sort((left, right) => left.localeCompare(right));
670
+ const patchFiles = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".patch")).map((entry) => join4(patchesDirPath, entry.name)).sort((left, right) => left.localeCompare(right));
559
671
  const summaries = await Promise.all(
560
672
  patchFiles.map(async (patchFilePath) => {
561
673
  const inspection = await inspectPatchArtifact(patchFilePath, options);
@@ -616,13 +728,13 @@ function defineTool(config) {
616
728
 
617
729
  // src/remediation/tools/check-inventory.ts
618
730
  import { z } from "zod";
619
- import { readFileSync as readFileSync3 } from "fs";
620
- import { join as join5 } from "path";
731
+ import { readFileSync as readFileSync4 } from "fs";
732
+ import { join as join6 } from "path";
621
733
  import { execa as execa3 } from "execa";
622
734
 
623
735
  // src/platform/policy.ts
624
- import { existsSync as existsSync5, readFileSync as readFileSync2 } from "fs";
625
- import { join as join4 } from "path";
736
+ import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
737
+ import { join as join5 } from "path";
626
738
  import { parse as yamlParse } from "yaml";
627
739
  var DEFAULT_POLICY = {
628
740
  allowMajorBumps: false,
@@ -653,10 +765,10 @@ var DEFAULT_POLICY = {
653
765
  escalationGraph: void 0
654
766
  };
655
767
  function loadPolicy(cwd, explicitPath) {
656
- const candidate = explicitPath ?? join4(cwd, ".github", "autoremediator.yml");
768
+ const candidate = explicitPath ?? join5(cwd, ".github", "autoremediator.yml");
657
769
  if (!existsSync5(candidate)) return DEFAULT_POLICY;
658
770
  try {
659
- const parsed = yamlParse(readFileSync2(candidate, "utf8"));
771
+ const parsed = yamlParse(readFileSync3(candidate, "utf8"));
660
772
  return {
661
773
  allowMajorBumps: parsed.allowMajorBumps ?? DEFAULT_POLICY.allowMajorBumps,
662
774
  denyPackages: parsed.denyPackages ?? DEFAULT_POLICY.denyPackages,
@@ -717,7 +829,7 @@ function isActiveSuppression(suppression) {
717
829
  }
718
830
  function loadSuppressionsFile(filePath) {
719
831
  try {
720
- const content = readFileSync2(filePath, "utf8");
832
+ const content = readFileSync3(filePath, "utf8");
721
833
  const parsed = yamlParse(content);
722
834
  return Array.isArray(parsed?.suppressions) ? parsed.suppressions : [];
723
835
  } catch {
@@ -748,14 +860,14 @@ var checkInventoryTool = defineTool({
748
860
  description: "Read the project's package.json and installed dependencies to list packages and exact versions. Must be called before checking version matches.",
749
861
  parameters: z.object({
750
862
  cwd: z.string().describe("Absolute path to the consumer project's root directory"),
751
- packageManager: z.enum(["npm", "pnpm", "yarn"]).optional().describe("Package manager used by the target project (auto-detected if omitted)"),
863
+ packageManager: z.enum(["npm", "pnpm", "yarn", "bun", "deno"]).optional().describe("Package manager used by the target project (auto-detected if omitted)"),
752
864
  policy: z.string().optional().describe("Optional path to .github/autoremediator.yml policy file"),
753
865
  workspace: z.string().optional().describe("Optional workspace/package selector for monorepos")
754
866
  }),
755
867
  execute: async ({ cwd, packageManager, policy, workspace }) => {
756
868
  let pkgJson;
757
869
  try {
758
- pkgJson = JSON.parse(readFileSync3(join5(cwd, "package.json"), "utf8"));
870
+ pkgJson = JSON.parse(readFileSync4(join6(cwd, "package.json"), "utf8"));
759
871
  } catch {
760
872
  return {
761
873
  packages: [],
@@ -769,15 +881,21 @@ var checkInventoryTool = defineTool({
769
881
  workspace: workspace ?? loadedPolicy.constraints?.workspace
770
882
  });
771
883
  let installedVersions = /* @__PURE__ */ new Map();
772
- try {
773
- const [cmd, ...args] = listCommand;
774
- const listResult = await execa3(cmd, args, {
775
- cwd,
776
- stdio: "pipe",
777
- reject: false
778
- });
779
- installedVersions = parseListOutput(pm, listResult.stdout || "");
780
- } catch {
884
+ if (pm === "deno") {
885
+ installedVersions = resolveDenoInventory(cwd);
886
+ } else {
887
+ try {
888
+ const [cmd, ...args] = listCommand;
889
+ if (cmd) {
890
+ const listResult = await execa3(cmd, args, {
891
+ cwd,
892
+ stdio: "pipe",
893
+ reject: false
894
+ });
895
+ installedVersions = parseListOutput(pm, listResult.stdout || "");
896
+ }
897
+ } catch {
898
+ }
781
899
  }
782
900
  const packages = [];
783
901
  for (const [name, version] of installedVersions.entries()) {
@@ -1016,14 +1134,14 @@ function getIntelligenceSourceConfig() {
1016
1134
  }
1017
1135
 
1018
1136
  // src/platform/idempotency.ts
1019
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
1020
- import { join as join6 } from "path";
1137
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
1138
+ import { join as join7 } from "path";
1021
1139
  var DEFAULT_INDEX = {
1022
1140
  schemaVersion: "1.0",
1023
1141
  entries: {}
1024
1142
  };
1025
1143
  function indexFilePath(cwd) {
1026
- return join6(cwd, ".autoremediator", "state", "idempotency.json");
1144
+ return join7(cwd, ".autoremediator", "state", "idempotency.json");
1027
1145
  }
1028
1146
  function entryKey(idempotencyKey, cveId) {
1029
1147
  return `${idempotencyKey}::${cveId.toUpperCase()}`;
@@ -1032,7 +1150,7 @@ function loadIndex(cwd) {
1032
1150
  const filePath = indexFilePath(cwd);
1033
1151
  if (!existsSync6(filePath)) return DEFAULT_INDEX;
1034
1152
  try {
1035
- const parsed = JSON.parse(readFileSync4(filePath, "utf8"));
1153
+ const parsed = JSON.parse(readFileSync5(filePath, "utf8"));
1036
1154
  if (parsed && parsed.schemaVersion === "1.0" && parsed.entries) {
1037
1155
  return parsed;
1038
1156
  }
@@ -1043,7 +1161,7 @@ function loadIndex(cwd) {
1043
1161
  }
1044
1162
  function saveIndex(cwd, index) {
1045
1163
  const filePath = indexFilePath(cwd);
1046
- mkdirSync2(join6(cwd, ".autoremediator", "state"), { recursive: true });
1164
+ mkdirSync2(join7(cwd, ".autoremediator", "state"), { recursive: true });
1047
1165
  writeFileSync2(filePath, JSON.stringify(index, null, 2) + "\n", "utf8");
1048
1166
  }
1049
1167
  function readIdempotentReport(cwd, idempotencyKey, cveId) {
@@ -1331,8 +1449,8 @@ async function enrichWithNvd(details) {
1331
1449
 
1332
1450
  // src/remediation/tools/check-reachability.ts
1333
1451
  import { z as z2 } from "zod";
1334
- import { readdirSync, readFileSync as readFileSync5, statSync } from "fs";
1335
- import { join as join7, extname } from "path";
1452
+ import { readdirSync, readFileSync as readFileSync6, statSync } from "fs";
1453
+ import { join as join8, extname } from "path";
1336
1454
  var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
1337
1455
  var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", "dist", "build", "out", ".git", "coverage", ".cache"]);
1338
1456
  var MAX_FILES = 500;
@@ -1346,7 +1464,7 @@ function collectSourceFiles(dir, files = []) {
1346
1464
  }
1347
1465
  for (const entry of entries) {
1348
1466
  if (files.length >= MAX_FILES) break;
1349
- const full = join7(dir, entry);
1467
+ const full = join8(dir, entry);
1350
1468
  let stat2;
1351
1469
  try {
1352
1470
  stat2 = statSync(full);
@@ -1379,7 +1497,7 @@ function assessPackageReachability(cwd, packageName) {
1379
1497
  for (const filePath of files) {
1380
1498
  let content;
1381
1499
  try {
1382
- content = readFileSync5(filePath, "utf8");
1500
+ content = readFileSync6(filePath, "utf8");
1383
1501
  } catch {
1384
1502
  continue;
1385
1503
  }
@@ -1535,8 +1653,8 @@ function buildSbom(packages, vulnerableNames, results) {
1535
1653
  }
1536
1654
 
1537
1655
  // src/intelligence/sources/registry.ts
1538
- import { readFileSync as readFileSync6 } from "fs";
1539
- import { join as join8 } from "path";
1656
+ import { readFileSync as readFileSync7 } from "fs";
1657
+ import { join as join9 } from "path";
1540
1658
  import { execa as execa4 } from "execa";
1541
1659
  import semver from "semver";
1542
1660
  var NPM_REGISTRY = "https://registry.npmjs.org";
@@ -1705,7 +1823,7 @@ async function queryOutdatedPackages(cwd, options = {}) {
1705
1823
  }
1706
1824
  let directDeps;
1707
1825
  try {
1708
- const pkgRaw = JSON.parse(readFileSync6(join8(cwd, "package.json"), "utf8"));
1826
+ const pkgRaw = JSON.parse(readFileSync7(join9(cwd, "package.json"), "utf8"));
1709
1827
  directDeps = /* @__PURE__ */ new Set([
1710
1828
  ...Object.keys(pkgRaw.dependencies ?? {}),
1711
1829
  ...Object.keys(pkgRaw.devDependencies ?? {})
@@ -1735,22 +1853,22 @@ async function queryOutdatedPackages(cwd, options = {}) {
1735
1853
 
1736
1854
  // src/remediation/tools/apply-version-bump.ts
1737
1855
  import { z as z4 } from "zod";
1738
- import { join as join10 } from "path";
1739
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
1856
+ import { join as join11 } from "path";
1857
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "fs";
1740
1858
  import { execa as execa5 } from "execa";
1741
1859
  import semver2 from "semver";
1742
1860
 
1743
1861
  // src/platform/repo-lock.ts
1744
1862
  import { mkdir, rm } from "fs/promises";
1745
- import { join as join9 } from "path";
1863
+ import { join as join10 } from "path";
1746
1864
  async function sleep(ms) {
1747
1865
  await new Promise((resolve2) => setTimeout(resolve2, ms));
1748
1866
  }
1749
1867
  async function acquireRepoLock(cwd, options = {}) {
1750
1868
  const timeoutMs = options.timeoutMs ?? 15e3;
1751
1869
  const retryDelayMs = options.retryDelayMs ?? 125;
1752
- const lockRoot = join9(cwd, ".autoremediator", "locks");
1753
- const lockPath = join9(cwd, ".autoremediator", "locks", "remediation.lock");
1870
+ const lockRoot = join10(cwd, ".autoremediator", "locks");
1871
+ const lockPath = join10(cwd, ".autoremediator", "locks", "remediation.lock");
1754
1872
  const startedAt = Date.now();
1755
1873
  await mkdir(lockRoot, { recursive: true });
1756
1874
  while (true) {
@@ -1784,7 +1902,7 @@ var applyVersionBumpTool = defineTool({
1784
1902
  description: "Update package.json to use the safe version of a vulnerable package and run the project's package manager install. In dry-run mode, only reports what would change.",
1785
1903
  parameters: z4.object({
1786
1904
  cwd: z4.string().describe("Absolute path to the consumer project root"),
1787
- packageManager: z4.enum(["npm", "pnpm", "yarn"]).optional().describe("Package manager used by the target project (auto-detected if omitted)"),
1905
+ packageManager: z4.enum(["npm", "pnpm", "yarn", "bun", "deno"]).optional().describe("Package manager used by the target project (auto-detected if omitted)"),
1788
1906
  packageName: z4.string().describe("The npm package to upgrade"),
1789
1907
  fromVersion: z4.string().describe("The currently installed vulnerable version"),
1790
1908
  toVersion: z4.string().describe("The safe target version to upgrade to"),
@@ -1811,7 +1929,7 @@ var applyVersionBumpTool = defineTool({
1811
1929
  workspace
1812
1930
  }) => {
1813
1931
  const pm = packageManager ?? detectPackageManager(cwd);
1814
- const pkgPath = join10(cwd, "package.json");
1932
+ const pkgPath = join11(cwd, "package.json");
1815
1933
  const loadedPolicy = loadPolicy(cwd, policy);
1816
1934
  const commandConstraints = {
1817
1935
  ...loadedPolicy.constraints,
@@ -1851,7 +1969,7 @@ var applyVersionBumpTool = defineTool({
1851
1969
  }
1852
1970
  let pkgJson;
1853
1971
  try {
1854
- pkgJson = JSON.parse(readFileSync7(pkgPath, "utf8"));
1972
+ pkgJson = JSON.parse(readFileSync8(pkgPath, "utf8"));
1855
1973
  } catch {
1856
1974
  return {
1857
1975
  packageName,
@@ -1975,8 +2093,8 @@ var applyVersionBumpTool = defineTool({
1975
2093
 
1976
2094
  // src/remediation/tools/apply-package-override/index.ts
1977
2095
  import { z as z5 } from "zod";
1978
- import { join as join11 } from "path";
1979
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
2096
+ import { join as join12 } from "path";
2097
+ import { existsSync as existsSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "fs";
1980
2098
  import { execa as execa7 } from "execa";
1981
2099
  import semver3 from "semver";
1982
2100
 
@@ -1985,6 +2103,7 @@ import { execa as execa6 } from "execa";
1985
2103
  async function collectDependencyTrace(cwd, pm, packageName, constraints) {
1986
2104
  try {
1987
2105
  const whyCommand = resolveWhyCommand(pm, packageName, constraints);
2106
+ if (whyCommand.length === 0) return void 0;
1988
2107
  const [whyCmd, ...whyArgs] = whyCommand;
1989
2108
  const result = await execa6(whyCmd, whyArgs, {
1990
2109
  cwd,
@@ -1999,17 +2118,20 @@ async function collectDependencyTrace(cwd, pm, packageName, constraints) {
1999
2118
  }
2000
2119
  }
2001
2120
  function describeOverrideField(packageManager) {
2002
- if (packageManager === "npm") return "overrides";
2121
+ if (packageManager === "npm" || packageManager === "bun") return "overrides";
2003
2122
  if (packageManager === "pnpm") return "pnpm.overrides";
2123
+ if (packageManager === "deno") return "overrides";
2004
2124
  return "resolutions";
2005
2125
  }
2006
2126
  function getOverrideValue(pkgJson, packageManager, packageName) {
2007
- if (packageManager === "npm") return pkgJson.overrides?.[packageName];
2127
+ if (packageManager === "npm" || packageManager === "bun" || packageManager === "deno") {
2128
+ return pkgJson.overrides?.[packageName];
2129
+ }
2008
2130
  if (packageManager === "pnpm") return pkgJson.pnpm?.overrides?.[packageName];
2009
2131
  return pkgJson.resolutions?.[packageName];
2010
2132
  }
2011
2133
  function setOverrideValue(pkgJson, packageManager, packageName, version) {
2012
- if (packageManager === "npm") {
2134
+ if (packageManager === "npm" || packageManager === "bun" || packageManager === "deno") {
2013
2135
  pkgJson.overrides = { ...pkgJson.overrides ?? {}, [packageName]: version };
2014
2136
  return;
2015
2137
  }
@@ -2026,7 +2148,7 @@ function setOverrideValue(pkgJson, packageManager, packageName, version) {
2026
2148
  pkgJson.resolutions = { ...pkgJson.resolutions ?? {}, [packageName]: version };
2027
2149
  }
2028
2150
  function restoreOverrideValue(pkgJson, packageManager, packageName, previousValue) {
2029
- if (packageManager === "npm") {
2151
+ if (packageManager === "npm" || packageManager === "bun" || packageManager === "deno") {
2030
2152
  pkgJson.overrides = restoreRecord(pkgJson.overrides, packageName, previousValue);
2031
2153
  return;
2032
2154
  }
@@ -2045,6 +2167,34 @@ function restoreOverrideValue(pkgJson, packageManager, packageName, previousValu
2045
2167
  }
2046
2168
  pkgJson.resolutions = restoreRecord(pkgJson.resolutions, packageName, previousValue);
2047
2169
  }
2170
+ function getDenoJsonImportValue(denoJson, packageName) {
2171
+ const imports = denoJson.imports ?? {};
2172
+ if (imports[packageName] !== void 0) {
2173
+ return { key: packageName, value: imports[packageName] };
2174
+ }
2175
+ const npmKey = `npm:${packageName}`;
2176
+ if (imports[npmKey] !== void 0) {
2177
+ return { key: npmKey, value: imports[npmKey] };
2178
+ }
2179
+ return void 0;
2180
+ }
2181
+ function setDenoJsonImportValue(denoJson, packageName, version) {
2182
+ const existing = getDenoJsonImportValue(denoJson, packageName);
2183
+ const key = existing?.key ?? `npm:${packageName}`;
2184
+ denoJson.imports = { ...denoJson.imports ?? {}, [key]: `npm:${packageName}@${version}` };
2185
+ }
2186
+ function restoreDenoJsonImportValue(denoJson, packageName, previousEntry) {
2187
+ const existing = getDenoJsonImportValue(denoJson, packageName);
2188
+ if (!existing) return;
2189
+ const imports = { ...denoJson.imports ?? {} };
2190
+ if (previousEntry === void 0) {
2191
+ delete imports[existing.key];
2192
+ } else {
2193
+ delete imports[existing.key];
2194
+ imports[previousEntry.key] = previousEntry.value;
2195
+ }
2196
+ denoJson.imports = Object.keys(imports).length > 0 ? imports : void 0;
2197
+ }
2048
2198
  function restoreRecord(record, key, previousValue) {
2049
2199
  const nextRecord = { ...record ?? {} };
2050
2200
  if (previousValue === void 0) {
@@ -2057,10 +2207,10 @@ function restoreRecord(record, key, previousValue) {
2057
2207
 
2058
2208
  // src/remediation/tools/apply-package-override/index.ts
2059
2209
  var applyPackageOverrideTool = defineTool({
2060
- description: "Apply a package-manager-native package.json override for a vulnerable transitive dependency and reinstall. Uses npm overrides, pnpm.overrides, or yarn resolutions.",
2210
+ description: "Apply a package-manager-native package.json override for a vulnerable transitive dependency and reinstall. Uses npm overrides, pnpm.overrides, yarn resolutions, bun overrides, or deno.json imports.",
2061
2211
  parameters: z5.object({
2062
2212
  cwd: z5.string().describe("Absolute path to the consumer project root"),
2063
- packageManager: z5.enum(["npm", "pnpm", "yarn"]).optional().describe("Package manager used by the target project (auto-detected if omitted)"),
2213
+ packageManager: z5.enum(["npm", "pnpm", "yarn", "bun", "deno"]).optional().describe("Package manager used by the target project (auto-detected if omitted)"),
2064
2214
  packageName: z5.string().describe("The npm package to override"),
2065
2215
  selector: z5.string().optional().describe("Optional manager-native override selector key (for nested or scoped overrides)"),
2066
2216
  fromVersion: z5.string().describe("The currently installed vulnerable version"),
@@ -2089,7 +2239,9 @@ var applyPackageOverrideTool = defineTool({
2089
2239
  workspace
2090
2240
  }) => {
2091
2241
  const pm = packageManager ?? detectPackageManager(cwd);
2092
- const pkgPath = join11(cwd, "package.json");
2242
+ const pkgPath = join12(cwd, "package.json");
2243
+ const denoJsonPath = join12(cwd, "deno.json");
2244
+ const isDenoNative = pm === "deno" && !existsSync7(pkgPath);
2093
2245
  const loadedPolicy = loadPolicy(cwd, policy);
2094
2246
  const commandConstraints = {
2095
2247
  ...loadedPolicy.constraints,
@@ -2128,9 +2280,108 @@ var applyPackageOverrideTool = defineTool({
2128
2280
  message: `Policy blocked major override for "${packageName}" (${fromVersion} -> ${toVersion}).`
2129
2281
  };
2130
2282
  }
2283
+ if (isDenoNative) {
2284
+ let denoJson;
2285
+ try {
2286
+ denoJson = JSON.parse(readFileSync9(denoJsonPath, "utf8"));
2287
+ } catch {
2288
+ return {
2289
+ packageName,
2290
+ strategy: "none",
2291
+ fromVersion,
2292
+ toVersion,
2293
+ applied: false,
2294
+ dryRun,
2295
+ unresolvedReason: "package-json-not-found",
2296
+ message: `Could not read deno.json at "${denoJsonPath}".`
2297
+ };
2298
+ }
2299
+ const existingEntry = getDenoJsonImportValue(denoJson, overrideSelector);
2300
+ if (!existingEntry) {
2301
+ return {
2302
+ packageName,
2303
+ strategy: "none",
2304
+ fromVersion,
2305
+ toVersion,
2306
+ applied: false,
2307
+ dryRun,
2308
+ unresolvedReason: "transitive-override-unsupported-deno-native",
2309
+ message: `Cannot apply transitive override for "${overrideSelector}" in a native Deno project (no package.json). Only direct dependencies declared in deno.json imports can be overridden.`
2310
+ };
2311
+ }
2312
+ const dependencyTrace2 = await collectDependencyTrace(cwd, pm, packageName, commandConstraints);
2313
+ const dependencyTraceSuffix2 = dependencyTrace2 ? ` Dependency trace: ${dependencyTrace2}` : "";
2314
+ if (dryRun) {
2315
+ return {
2316
+ packageName,
2317
+ strategy: "override",
2318
+ fromVersion,
2319
+ toVersion,
2320
+ applied: false,
2321
+ dryRun: true,
2322
+ message: `[DRY RUN] Would update deno.json imports["${existingEntry.key}"] to "npm:${overrideSelector}@${toVersion}", then run ${installCommand.join(" ")}.${dependencyTraceSuffix2}`
2323
+ };
2324
+ }
2325
+ return withRepoLock(cwd, async () => {
2326
+ setDenoJsonImportValue(denoJson, overrideSelector, toVersion);
2327
+ writeFileSync4(denoJsonPath, JSON.stringify(denoJson, null, 2) + "\n", "utf8");
2328
+ try {
2329
+ const [installCmd, ...installArgs] = installCommand;
2330
+ await execa7(installCmd, installArgs, { cwd, stdio: "pipe" });
2331
+ } catch (err) {
2332
+ restoreDenoJsonImportValue(denoJson, overrideSelector, existingEntry);
2333
+ writeFileSync4(denoJsonPath, JSON.stringify(denoJson, null, 2) + "\n", "utf8");
2334
+ const message = err instanceof Error ? err.message : String(err);
2335
+ return {
2336
+ packageName,
2337
+ strategy: "override",
2338
+ fromVersion,
2339
+ toVersion,
2340
+ applied: false,
2341
+ dryRun: false,
2342
+ unresolvedReason: "override-apply-failed",
2343
+ message: `${installCommand.join(" ")} failed after updating deno.json imports for "${overrideSelector}" to ${toVersion}. Reverted. Error: ${message}${dependencyTraceSuffix2}`
2344
+ };
2345
+ }
2346
+ if (runTests) {
2347
+ try {
2348
+ const [testCmd, ...testArgs] = testCommand;
2349
+ await execa7(testCmd, testArgs, { cwd, stdio: "pipe" });
2350
+ } catch (err) {
2351
+ restoreDenoJsonImportValue(denoJson, overrideSelector, existingEntry);
2352
+ writeFileSync4(denoJsonPath, JSON.stringify(denoJson, null, 2) + "\n", "utf8");
2353
+ try {
2354
+ const [rollbackCmd, ...rollbackArgs] = installCommand;
2355
+ await execa7(rollbackCmd, rollbackArgs, { cwd, stdio: "pipe" });
2356
+ } catch {
2357
+ }
2358
+ const message = err instanceof Error ? err.message : String(err);
2359
+ return {
2360
+ packageName,
2361
+ strategy: "override",
2362
+ fromVersion,
2363
+ toVersion,
2364
+ applied: false,
2365
+ dryRun: false,
2366
+ unresolvedReason: "validation-failed",
2367
+ message: `${testCommand.join(" ")} failed after updating deno.json imports for "${overrideSelector}" to ${toVersion}. Reverted. Error: ${message}${dependencyTraceSuffix2}`
2368
+ };
2369
+ }
2370
+ }
2371
+ return {
2372
+ packageName,
2373
+ strategy: "override",
2374
+ fromVersion,
2375
+ toVersion,
2376
+ applied: true,
2377
+ dryRun: false,
2378
+ message: `Successfully updated deno.json imports["${existingEntry.key}"] for "${overrideSelector}" from ${fromVersion} to ${toVersion}, then ran ${installCommand.join(" ")}${runTests ? ` and passed ${testCommand.join(" ")}` : ""}.${dependencyTraceSuffix2}`
2379
+ };
2380
+ });
2381
+ }
2131
2382
  let pkgJson;
2132
2383
  try {
2133
- pkgJson = JSON.parse(readFileSync8(pkgPath, "utf8"));
2384
+ pkgJson = JSON.parse(readFileSync9(pkgPath, "utf8"));
2134
2385
  } catch {
2135
2386
  return {
2136
2387
  packageName,
@@ -2205,12 +2456,14 @@ var applyPackageOverrideTool = defineTool({
2205
2456
  }
2206
2457
  }
2207
2458
  let dedupeNote = "";
2208
- try {
2209
- const [dedupeCmd, ...dedupeArgs] = dedupeCommand;
2210
- await execa7(dedupeCmd, dedupeArgs, { cwd, stdio: "pipe" });
2211
- } catch (err) {
2212
- const message = err instanceof Error ? err.message : String(err);
2213
- dedupeNote = ` Dedupe warning: ${dedupeCommand.join(" ")} failed (${message}).`;
2459
+ if (dedupeCommand.length > 0) {
2460
+ try {
2461
+ const [dedupeCmd, ...dedupeArgs] = dedupeCommand;
2462
+ await execa7(dedupeCmd, dedupeArgs, { cwd, stdio: "pipe" });
2463
+ } catch (err) {
2464
+ const message = err instanceof Error ? err.message : String(err);
2465
+ dedupeNote = ` Dedupe warning: ${dedupeCommand.join(" ")} failed (${message}).`;
2466
+ }
2214
2467
  }
2215
2468
  return {
2216
2469
  packageName,
@@ -2369,7 +2622,7 @@ async function resolvePrimaryResult(params) {
2369
2622
  // src/remediation/tools/fetch-package-source.ts
2370
2623
  import { z as z6 } from "zod";
2371
2624
  import { mkdir as mkdir2, readdir as readdir2, readFile as readFile3, rm as rm2 } from "fs/promises";
2372
- import { join as join12 } from "path";
2625
+ import { join as join13 } from "path";
2373
2626
  import { execa as execa8 } from "execa";
2374
2627
  var fetchPackageSourceTool = defineTool({
2375
2628
  description: "Download package tarball from npm and extract source files for CVE analysis. Supports custom file patterns (default: *.js, *.ts).",
@@ -2386,23 +2639,23 @@ var fetchPackageSourceTool = defineTool({
2386
2639
  filePatterns
2387
2640
  }) => {
2388
2641
  const tempBaseDir = `/tmp/autoremediator-pkg-${Date.now()}`;
2389
- const extractDir = join12(tempBaseDir, "out");
2642
+ const extractDir = join13(tempBaseDir, "out");
2390
2643
  try {
2391
2644
  const npmUrl = `https://registry.npmjs.org/${packageName}/-/${packageName.split("/").pop()}-${version}.tgz`;
2392
2645
  await mkdir2(tempBaseDir, { recursive: true });
2393
- const tarballPath = join12(tempBaseDir, "package.tgz");
2646
+ const tarballPath = join13(tempBaseDir, "package.tgz");
2394
2647
  await execa8("curl", ["-L", "-o", tarballPath, npmUrl]);
2395
2648
  await mkdir2(extractDir, { recursive: true });
2396
2649
  await execa8("tar", ["-xzf", tarballPath, "-C", extractDir]);
2397
2650
  const extractedContents = await readdir2(extractDir);
2398
- const packageRootDir = extractedContents.includes("package") ? join12(extractDir, "package") : extractDir;
2651
+ const packageRootDir = extractedContents.includes("package") ? join13(extractDir, "package") : extractDir;
2399
2652
  const sourceCode = {};
2400
2653
  async function walkDir(dir, relativeBase) {
2401
2654
  try {
2402
2655
  const files = await readdir2(dir, { withFileTypes: true });
2403
2656
  for (const file of files) {
2404
- const fullPath = join12(dir, file.name);
2405
- const relPath = join12(relativeBase, file.name);
2657
+ const fullPath = join13(dir, file.name);
2658
+ const relPath = join13(relativeBase, file.name);
2406
2659
  if (file.isDirectory()) {
2407
2660
  if (![
2408
2661
  "node_modules",
@@ -2774,24 +3027,23 @@ var generatePatchTool = defineTool({
2774
3027
  // src/remediation/tools/apply-patch-file/index.ts
2775
3028
  import { z as z8 } from "zod";
2776
3029
  import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
2777
- import { join as join14 } from "path";
3030
+ import { join as join15 } from "path";
2778
3031
  import { execa as execa10 } from "execa";
2779
3032
 
2780
3033
  // src/remediation/tools/apply-patch-file/helpers.ts
2781
- import { existsSync as existsSync7 } from "fs";
3034
+ import { existsSync as existsSync8 } from "fs";
2782
3035
  import { mkdtemp, readFile as readFile4, rm as rm3, writeFile } from "fs/promises";
2783
3036
  import { createHash } from "crypto";
2784
3037
  import { tmpdir } from "os";
2785
- import { join as join13 } from "path";
3038
+ import { join as join14 } from "path";
2786
3039
  import { execa as execa9 } from "execa";
2787
3040
  async function resolvePatchMode(packageManager, cwd) {
2788
- if (packageManager === "npm") return "patch-package";
3041
+ if (packageManager === "npm" || packageManager === "bun" || packageManager === "deno") return "patch-package";
2789
3042
  if (packageManager === "pnpm") return "native-pnpm";
2790
3043
  const major = await getYarnMajorVersion(cwd);
2791
3044
  return major >= 2 ? "native-yarn" : "patch-package";
2792
3045
  }
2793
3046
  function patchModeRequiresPackageJsonSnapshot(packageManager) {
2794
- if (packageManager === "npm") return true;
2795
3047
  if (packageManager === "pnpm") return false;
2796
3048
  return true;
2797
3049
  }
@@ -2817,7 +3069,7 @@ async function writePatchManifest(manifestFilePath, artifact) {
2817
3069
  await writeFile(manifestFilePath, JSON.stringify(artifact, null, 2) + "\n", "utf8");
2818
3070
  }
2819
3071
  async function configurePatchPackagePostinstall(cwd, packageManager) {
2820
- const pkgJsonPath = join13(cwd, "package.json");
3072
+ const pkgJsonPath = join14(cwd, "package.json");
2821
3073
  let pkgJson;
2822
3074
  try {
2823
3075
  pkgJson = JSON.parse(await readFile4(pkgJsonPath, "utf8"));
@@ -2857,7 +3109,7 @@ async function configurePatchPackagePostinstall(cwd, packageManager) {
2857
3109
  return { success: true };
2858
3110
  }
2859
3111
  async function capturePackageJsonSnapshot(cwd) {
2860
- const path = join13(cwd, "package.json");
3112
+ const path = join14(cwd, "package.json");
2861
3113
  try {
2862
3114
  const content = await readFile4(path, "utf8");
2863
3115
  return { path, content };
@@ -2927,8 +3179,8 @@ ${createResult.stderr}`);
2927
3179
  error: `Could not determine native patch directory for ${packageSpec}.`
2928
3180
  };
2929
3181
  }
2930
- const tempPatchDir = await mkdtemp(join13(tmpdir(), "autoremediator-native-patch-"));
2931
- const tempPatchFile = join13(tempPatchDir, "change.patch");
3182
+ const tempPatchDir = await mkdtemp(join14(tmpdir(), "autoremediator-native-patch-"));
3183
+ const tempPatchFile = join14(tempPatchDir, "change.patch");
2932
3184
  try {
2933
3185
  await writeFile(tempPatchFile, patchContent, "utf8");
2934
3186
  await execa9("patch", ["-p1", "-i", tempPatchFile], {
@@ -2959,12 +3211,12 @@ ${createResult.stderr}`);
2959
3211
  function extractPatchDirectory(output) {
2960
3212
  const lines = output.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
2961
3213
  for (const line of lines) {
2962
- if (existsSync7(line)) {
3214
+ if (existsSync8(line)) {
2963
3215
  return line;
2964
3216
  }
2965
3217
  const tokens = line.split(/\s+/).map((token) => token.replace(/^['"]|['"]$/g, ""));
2966
3218
  for (const token of tokens) {
2967
- if (token.startsWith("/") && existsSync7(token)) {
3219
+ if (token.startsWith("/") && existsSync8(token)) {
2968
3220
  return token;
2969
3221
  }
2970
3222
  }
@@ -3030,7 +3282,7 @@ var applyPatchFileTool = defineTool({
3030
3282
  ).optional().describe("Patch list from generate-patch; first patch is applied"),
3031
3283
  patchesDir: z8.string().optional().default("./patches").describe("Directory to store patch files"),
3032
3284
  cwd: z8.string().describe("Project root directory (for package.json)"),
3033
- packageManager: z8.enum(["npm", "pnpm", "yarn"]).optional().describe("Package manager used by the target project (auto-detected if omitted)"),
3285
+ packageManager: z8.enum(["npm", "pnpm", "yarn", "bun", "deno"]).optional().describe("Package manager used by the target project (auto-detected if omitted)"),
3034
3286
  policy: z8.string().optional().describe("Optional path to .autoremediator policy file"),
3035
3287
  installMode: z8.enum(["standard", "prefer-offline", "deterministic"]).optional(),
3036
3288
  installPreferOffline: z8.boolean().optional(),
@@ -3108,7 +3360,7 @@ var applyPatchFileTool = defineTool({
3108
3360
  };
3109
3361
  }
3110
3362
  const patchFileName = buildPatchFileName(packageName, vulnerableVersion);
3111
- const patchFilePath = join14(cwd, patchesDir, patchFileName);
3363
+ const patchFilePath = join15(cwd, patchesDir, patchFileName);
3112
3364
  const manifestFilePath = `${patchFilePath}.json`;
3113
3365
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
3114
3366
  const baseArtifact = {
@@ -3147,7 +3399,7 @@ var applyPatchFileTool = defineTool({
3147
3399
  }
3148
3400
  return withRepoLock(cwd, async () => {
3149
3401
  const packageJsonSnapshot = patchModeRequiresPackageJsonSnapshot(pm) ? await capturePackageJsonSnapshot(cwd) : void 0;
3150
- const patchesDirPath = join14(cwd, patchesDir);
3402
+ const patchesDirPath = join15(cwd, patchesDir);
3151
3403
  await mkdir3(patchesDirPath, { recursive: true });
3152
3404
  await writeFile2(patchFilePath, selectedPatch, "utf8");
3153
3405
  validationPhases.push({
@@ -4107,8 +4359,8 @@ function accumulateStepResults(params) {
4107
4359
  }
4108
4360
 
4109
4361
  // src/remediation/orchestration-prompt.ts
4110
- import { existsSync as existsSync8, readFileSync as readFileSync9 } from "fs";
4111
- import { join as join15 } from "path";
4362
+ import { existsSync as existsSync9, readFileSync as readFileSync10 } from "fs";
4363
+ import { join as join16 } from "path";
4112
4364
  function buildProviderAddendum(provider, personality = "balanced") {
4113
4365
  const personalityDirective = personality === "analytical" ? "Use concise, explicit rationale for tool decisions and unresolved outcomes." : personality === "pragmatic" ? "Prefer the smallest safe remediation path while preserving policy and validation gates." : "Balance concise execution with brief rationale for risky or unresolved outcomes.";
4114
4366
  const providerDirective = provider === "remote" ? "Use strict structured output and deterministic reporting fields." : "Use deterministic-first behavior and only rely on remote model fallback when required by patch generation.";
@@ -4119,8 +4371,8 @@ Provider profile:
4119
4371
  - ${personalityDirective}`;
4120
4372
  }
4121
4373
  function loadOrchestrationPrompt(ctx) {
4122
- const promptPath = join15(process.cwd(), ".github", "instructions", "orchestration.instructions.md");
4123
- if (!existsSync8(promptPath)) {
4374
+ const promptPath = join16(process.cwd(), ".github", "instructions", "orchestration.instructions.md");
4375
+ if (!existsSync9(promptPath)) {
4124
4376
  return `You are autoremediator, an agentic security remediation system for Node.js package dependencies.
4125
4377
  Working directory: ${ctx.cwd}
4126
4378
  Package manager: ${ctx.packageManager}
@@ -4146,7 +4398,7 @@ Fallback sequence (when neither version bump nor override can be applied):
4146
4398
 
4147
4399
  Always respect dryRun and policy constraints.`;
4148
4400
  }
4149
- const template = readFileSync9(promptPath, "utf8");
4401
+ const template = readFileSync10(promptPath, "utf8");
4150
4402
  return template.replaceAll("{{cveId}}", ctx.cveId).replaceAll("{{cwd}}", ctx.cwd).replaceAll("{{packageManager}}", ctx.packageManager).replaceAll("{{dryRun}}", String(ctx.dryRun)).replaceAll("{{runTests}}", String(ctx.runTests)).replaceAll("{{policy}}", ctx.policy || "undefined").replaceAll("{{patchesDir}}", ctx.patchesDir).replaceAll("{{directDependenciesOnly}}", String(ctx.constraints.directDependenciesOnly ?? false)).replaceAll("{{preferVersionBump}}", String(ctx.constraints.preferVersionBump ?? false)) + buildProviderAddendum(ctx.llmProvider, ctx.modelPersonality);
4151
4403
  }
4152
4404
 
@@ -5050,7 +5302,7 @@ function resolveConstraints(options, cwd) {
5050
5302
 
5051
5303
  // src/platform/evidence.ts
5052
5304
  import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync5 } from "fs";
5053
- import { join as join16 } from "path";
5305
+ import { join as join17 } from "path";
5054
5306
  function createEvidenceLog(cwd, cveIds, context = {}) {
5055
5307
  return {
5056
5308
  runId: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
@@ -5081,9 +5333,9 @@ function finalizeEvidence(log) {
5081
5333
  return log;
5082
5334
  }
5083
5335
  function writeEvidenceLog(cwd, log) {
5084
- const dir = join16(cwd, ".autoremediator", "evidence");
5336
+ const dir = join17(cwd, ".autoremediator", "evidence");
5085
5337
  mkdirSync3(dir, { recursive: true });
5086
- const filePath = join16(dir, `${log.runId}.json`);
5338
+ const filePath = join17(dir, `${log.runId}.json`);
5087
5339
  writeFileSync5(filePath, JSON.stringify(log, null, 2) + "\n", "utf8");
5088
5340
  return filePath;
5089
5341
  }
@@ -5652,11 +5904,11 @@ async function planRemediation(cveId, options = {}) {
5652
5904
 
5653
5905
  // src/scanner/parse-input.ts
5654
5906
  import { extname as extname2 } from "path";
5655
- import { readFileSync as readFileSync13 } from "fs";
5907
+ import { readFileSync as readFileSync14 } from "fs";
5656
5908
  import { execa as execa12 } from "execa";
5657
5909
 
5658
5910
  // src/scanner/adapters/npm-audit.ts
5659
- import { readFileSync as readFileSync10 } from "fs";
5911
+ import { readFileSync as readFileSync11 } from "fs";
5660
5912
  var CVE_REGEX = /CVE-\d{4}-\d+/gi;
5661
5913
  function normalizeSeverity(raw) {
5662
5914
  if (!raw) return "UNKNOWN";
@@ -5690,12 +5942,12 @@ function parseNpmAuditJsonFromString(content) {
5690
5942
  return findings;
5691
5943
  }
5692
5944
  function parseNpmAuditJsonFile(filePath) {
5693
- const content = readFileSync10(filePath, "utf8");
5945
+ const content = readFileSync11(filePath, "utf8");
5694
5946
  return parseNpmAuditJsonFromString(content);
5695
5947
  }
5696
5948
 
5697
5949
  // src/scanner/adapters/yarn-audit.ts
5698
- import { readFileSync as readFileSync11 } from "fs";
5950
+ import { readFileSync as readFileSync12 } from "fs";
5699
5951
  var CVE_REGEX2 = /CVE-\d{4}-\d+/gi;
5700
5952
  function normalizeSeverity2(raw) {
5701
5953
  if (!raw) return "UNKNOWN";
@@ -5738,12 +5990,12 @@ function parseYarnAuditJsonFromString(content) {
5738
5990
  return findings;
5739
5991
  }
5740
5992
  function parseYarnAuditJsonFile(filePath) {
5741
- const content = readFileSync11(filePath, "utf8");
5993
+ const content = readFileSync12(filePath, "utf8");
5742
5994
  return parseYarnAuditJsonFromString(content);
5743
5995
  }
5744
5996
 
5745
5997
  // src/scanner/adapters/sarif.ts
5746
- import { readFileSync as readFileSync12 } from "fs";
5998
+ import { readFileSync as readFileSync13 } from "fs";
5747
5999
  var CVE_REGEX3 = /CVE-\d{4}-\d+/gi;
5748
6000
  function extractPackageName(result) {
5749
6001
  const pkg = result.properties?.["packageName"];
@@ -5775,7 +6027,7 @@ function parseSarifFromString(content) {
5775
6027
  return findings;
5776
6028
  }
5777
6029
  function parseSarifFile(filePath) {
5778
- const content = readFileSync12(filePath, "utf8");
6030
+ const content = readFileSync13(filePath, "utf8");
5779
6031
  return parseSarifFromString(content);
5780
6032
  }
5781
6033
 
@@ -5826,10 +6078,21 @@ async function parseScanInputFromAudit(params) {
5826
6078
  }
5827
6079
  }
5828
6080
  function defaultAuditFormat(pm) {
5829
- return pm === "yarn" ? "yarn-audit" : "npm-audit";
6081
+ if (pm === "yarn") return "yarn-audit";
6082
+ if (pm === "deno") {
6083
+ throw new Error(
6084
+ "Deno does not support a native audit command. Use --input with a SARIF or npm-audit scan file instead."
6085
+ );
6086
+ }
6087
+ return "npm-audit";
5830
6088
  }
5831
6089
  function ensureAuditFormatCompatibility(pm, resolved) {
5832
6090
  if (resolved === "sarif") return;
6091
+ if (pm === "deno") {
6092
+ throw new Error(
6093
+ "Deno does not support a native audit command. Use --input with a SARIF or npm-audit scan file instead."
6094
+ );
6095
+ }
5833
6096
  if (pm === "yarn" && resolved !== "yarn-audit") {
5834
6097
  throw new Error('Format "npm-audit" is not supported with package manager "yarn" in --audit mode. Use --format yarn-audit or --format auto.');
5835
6098
  }
@@ -5841,7 +6104,7 @@ function inferFormat(filePath) {
5841
6104
  const ext = extname2(filePath).toLowerCase();
5842
6105
  if (ext === ".sarif") return "sarif";
5843
6106
  try {
5844
- const content = readFileSync13(filePath, "utf8");
6107
+ const content = readFileSync14(filePath, "utf8");
5845
6108
  const firstLine = content.split("\n").find((line) => line.trim().startsWith("{"));
5846
6109
  if (firstLine) {
5847
6110
  const parsed = JSON.parse(firstLine);
@@ -6239,14 +6502,14 @@ async function remediatePortfolio(targets, options = {}) {
6239
6502
  }
6240
6503
 
6241
6504
  // src/api/update-outdated/index.ts
6242
- import { join as join17 } from "path";
6243
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync6 } from "fs";
6505
+ import { join as join18 } from "path";
6506
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "fs";
6244
6507
  import { execa as execa13 } from "execa";
6245
6508
  async function applyBump(params) {
6246
- const pkgPath = join17(params.cwd, "package.json");
6509
+ const pkgPath = join18(params.cwd, "package.json");
6247
6510
  let pkgJson;
6248
6511
  try {
6249
- pkgJson = JSON.parse(readFileSync14(pkgPath, "utf8"));
6512
+ pkgJson = JSON.parse(readFileSync15(pkgPath, "utf8"));
6250
6513
  } catch {
6251
6514
  return {
6252
6515
  applied: false,
@@ -6547,9 +6810,9 @@ function toSarifOutput(report) {
6547
6810
  }
6548
6811
 
6549
6812
  // src/version.ts
6550
- import { readFileSync as readFileSync15 } from "fs";
6813
+ import { readFileSync as readFileSync16 } from "fs";
6551
6814
  function readPackageVersion() {
6552
- const raw = readFileSync15(new URL("../package.json", import.meta.url), "utf8");
6815
+ const raw = readFileSync16(new URL("../package.json", import.meta.url), "utf8");
6553
6816
  const metadata = JSON.parse(raw);
6554
6817
  if (!metadata.version) {
6555
6818
  throw new Error("packages/core/package.json is missing a version field.");
@@ -6577,4 +6840,4 @@ export {
6577
6840
  updateOutdated,
6578
6841
  PACKAGE_VERSION
6579
6842
  };
6580
- //# sourceMappingURL=chunk-4CVVRAQM.js.map
6843
+ //# sourceMappingURL=chunk-3NNNFJLV.js.map