@stll/oxlint-config 1.3.0 → 1.4.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.
Files changed (65) hide show
  1. package/README.md +254 -17
  2. package/dist/cloud-setup-cli.cjs +18 -38
  3. package/dist/cloud-setup-cli.cjs.map +1 -1
  4. package/dist/cloud-setup-cli.mjs +21 -41
  5. package/dist/cloud-setup-cli.mjs.map +1 -1
  6. package/dist/consumer-compat-cli.cjs +50 -249
  7. package/dist/consumer-compat-cli.cjs.map +1 -1
  8. package/dist/consumer-compat-cli.mjs +6 -205
  9. package/dist/consumer-compat-cli.mjs.map +1 -1
  10. package/dist/consumer-node-support.cjs +497 -0
  11. package/dist/consumer-node-support.cjs.map +1 -0
  12. package/dist/consumer-node-support.mjs +381 -0
  13. package/dist/consumer-node-support.mjs.map +1 -0
  14. package/dist/dependabot-cli.cjs +67 -0
  15. package/dist/dependabot-cli.cjs.map +1 -0
  16. package/dist/dependabot-cli.d.cts +1 -0
  17. package/dist/dependabot-cli.d.mts +1 -0
  18. package/dist/dependabot-cli.mjs +67 -0
  19. package/dist/dependabot-cli.mjs.map +1 -0
  20. package/dist/dependabot.cjs +5 -0
  21. package/dist/dependabot.d.cts +108 -0
  22. package/dist/dependabot.d.mts +108 -0
  23. package/dist/dependabot.mjs +3 -0
  24. package/dist/generated-file.cjs +61 -0
  25. package/dist/generated-file.cjs.map +1 -0
  26. package/dist/generated-file.mjs +44 -0
  27. package/dist/generated-file.mjs.map +1 -0
  28. package/dist/publish-artifact-syntax.cjs +1309 -0
  29. package/dist/publish-artifact-syntax.cjs.map +1 -0
  30. package/dist/publish-artifact-syntax.mjs +1265 -0
  31. package/dist/publish-artifact-syntax.mjs.map +1 -0
  32. package/dist/publish-contract-cli.cjs +53 -12
  33. package/dist/publish-contract-cli.cjs.map +1 -1
  34. package/dist/publish-contract-cli.mjs +49 -8
  35. package/dist/publish-contract-cli.mjs.map +1 -1
  36. package/dist/toolchain-changed.cjs +5 -1
  37. package/dist/toolchain-changed.cjs.map +1 -1
  38. package/dist/toolchain-changed.mjs +6 -2
  39. package/dist/toolchain-changed.mjs.map +1 -1
  40. package/dist/toolchain-dependabot.cjs +455 -0
  41. package/dist/toolchain-dependabot.cjs.map +1 -0
  42. package/dist/toolchain-dependabot.mjs +423 -0
  43. package/dist/toolchain-dependabot.mjs.map +1 -0
  44. package/dist/toolchain-guard.cjs +1096 -424
  45. package/dist/toolchain-guard.cjs.map +1 -1
  46. package/dist/toolchain-guard.mjs +1085 -413
  47. package/dist/toolchain-guard.mjs.map +1 -1
  48. package/dist/toolchain-inputs.cjs +122 -22
  49. package/dist/toolchain-inputs.cjs.map +1 -1
  50. package/dist/toolchain-inputs.mjs +117 -23
  51. package/dist/toolchain-inputs.mjs.map +1 -1
  52. package/dist/toolchain-schema.cjs +0 -493
  53. package/dist/toolchain-schema.cjs.map +1 -1
  54. package/dist/toolchain-schema.mjs +3 -379
  55. package/dist/toolchain-schema.mjs.map +1 -1
  56. package/dist/typecheck-parity.cjs +1 -1
  57. package/dist/typecheck-probe-cli.cjs +1 -1
  58. package/dist/typecheck-probe-cli.cjs.map +1 -1
  59. package/dist/typecheck-probe-cli.mjs +1 -1
  60. package/dist/typecheck-probe-cli.mjs.map +1 -1
  61. package/package.json +13 -1
  62. package/dist/publish-contract.cjs +0 -431
  63. package/dist/publish-contract.cjs.map +0 -1
  64. package/dist/publish-contract.mjs +0 -396
  65. package/dist/publish-contract.mjs.map +0 -1
@@ -378,6 +378,21 @@ const cloudSetupArtifacts = {
378
378
  binaries: { "rustup-init": "rustup-init" }
379
379
  }
380
380
  },
381
+ gitleaks: {
382
+ version: "8.30.1",
383
+ amd64: {
384
+ url: "https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz",
385
+ sha256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb",
386
+ archive: "tar.gz",
387
+ binaries: { gitleaks: "gitleaks" }
388
+ },
389
+ arm64: {
390
+ url: "https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_arm64.tar.gz",
391
+ sha256: "e4a487ee7ccd7d3a7f7ec08657610aa3606637dab924210b3aee62570fb4b080",
392
+ archive: "tar.gz",
393
+ binaries: { gitleaks: "gitleaks" }
394
+ }
395
+ },
381
396
  "cargo-nextest": {
382
397
  version: "0.9.148",
383
398
  amd64: {
@@ -445,7 +460,8 @@ const cloudSetupArtifactVersions = {
445
460
  "rustup-init": [cloudSetupArtifacts["rustup-init"]],
446
461
  "cargo-nextest": [cloudSetupArtifacts["cargo-nextest"]],
447
462
  "wasm-bindgen-cli": wasmBindgenArtifactReleases,
448
- uv: [cloudSetupArtifacts.uv]
463
+ uv: [cloudSetupArtifacts.uv],
464
+ gitleaks: [cloudSetupArtifacts.gitleaks]
449
465
  };
450
466
  /** A new version requires an explicit, verified catalog entry; never build from source. */
451
467
  const getCloudSetupArtifact = (tool, version) => {
@@ -500,11 +516,20 @@ const parseRust = (input) => {
500
516
  if (!object(input) || Object.keys(input).some((key) => ![
501
517
  "toolchain",
502
518
  "components",
503
- "targets"
504
- ].includes(key))) throw new Error("cloud.rust accepts only toolchain, components and targets");
519
+ "targets",
520
+ "additionalToolchains"
521
+ ].includes(key))) throw new Error("cloud.rust accepts only toolchain, components, targets and additionalToolchains");
505
522
  const toolchain = input["toolchain"];
506
523
  if (toolchain !== void 0 && !exactPin(toolchain)) throw new Error("cloud.rust.toolchain must be an exact stable release");
524
+ const additional = input["additionalToolchains"];
525
+ if (additional !== void 0 && !Array.isArray(additional)) throw new Error("cloud.rust.additionalToolchains requires exact stable releases");
526
+ const additionalToolchains = additional === void 0 ? [] : Array.from(additional, (pin) => {
527
+ if (!exactPin(pin)) throw new Error("cloud.rust.additionalToolchains requires exact stable releases");
528
+ return pin;
529
+ });
530
+ if (new Set(additionalToolchains).size !== additionalToolchains.length) throw new Error("cloud.rust.additionalToolchains contains duplicates");
507
531
  return {
532
+ additionalToolchains,
508
533
  ...toolchain === void 0 ? {} : { toolchain },
509
534
  components: parseCloudRustNames(input["components"], "components"),
510
535
  targets: parseCloudRustNames(input["targets"], "targets")
@@ -838,6 +863,11 @@ const resolveCloudToolchains = ({ cloud, files, rust, rustExceptions }) => {
838
863
  if (channel !== rust && !rustExceptions.some(({ pin }) => pin === channel)) throw new Error(`cloud Rust must use shared Rust ${rust} or a recorded rustExceptions pin`);
839
864
  if (cloud.rust?.toolchain !== void 0 && cloud.rust.toolchain !== channel) throw new Error("cloud.rust.toolchain conflicts with root Rust toolchain");
840
865
  }
866
+ const additionalToolchains = cloud.rust?.additionalToolchains ?? [];
867
+ for (const pin of additionalToolchains) {
868
+ if (pin === channel) throw new Error("cloud.rust.additionalToolchains must not repeat the primary toolchain");
869
+ if (pin !== rust && !rustExceptions.some(({ pin: authorized }) => authorized === pin)) throw new Error(`cloud.rust.additionalToolchains ${pin} requires an authorized rustExceptions pin`);
870
+ }
841
871
  const components = [.../* @__PURE__ */ new Set([...parseCloudRustNames(declared?.["components"], "components"), ...cloud.rust?.components ?? []])].sort();
842
872
  const targets = [.../* @__PURE__ */ new Set([...parseCloudRustNames(declared?.["targets"], "targets"), ...cloud.rust?.targets ?? []])].sort();
843
873
  const resolveTool = (tool, version) => {
@@ -868,6 +898,7 @@ const resolveCloudToolchains = ({ cloud, files, rust, rustExceptions }) => {
868
898
  return {
869
899
  rust: rustEnabled && typeof channel === "string" ? {
870
900
  channel,
901
+ additionalToolchains: [...additionalToolchains].sort(),
871
902
  components,
872
903
  targets,
873
904
  installer: cloudSetupArtifacts["rustup-init"]
@@ -904,7 +935,7 @@ rust_run() {
904
935
  *) fail 'Invalid Rust execution mode' ;;
905
936
  esac
906
937
  }
907
- rust_ready() {
938
+ primary_rust_ready() {
908
939
  local directory
909
940
  for directory in "$RUSTUP_HOME" "$CARGO_HOME"; do
910
941
  [[ -d "$directory" && ! -L "$directory" && "$(stat -c '%u' "$directory")" == "$OUTPUT_UID" ]] || return 1
@@ -918,13 +949,19 @@ rust_ready() {
918
949
  @VERIFY_TARGETS@
919
950
  return 0
920
951
  }
952
+ rust_ready() {
953
+ local additional_version
954
+ primary_rust_ready || return 1
955
+ @VERIFY_ADDITIONAL_TOOLCHAINS@
956
+ return 0
957
+ }
921
958
  verify_rust() { rust_ready || fail 'Pinned Rust, components or targets are unavailable; run install'; }
922
959
  install_rust() (
923
960
  if ! command -v cc >/dev/null || ! command -v ld >/dev/null || [[ ! -f /usr/include/stdlib.h ]]; then
924
961
  apt_refresh_for build-essential
925
962
  apt_install build-essential
926
963
  fi
927
- local artifact_url artifact_sha
964
+ local artifact_url artifact_sha additional_version
928
965
  # Subshell scope retains scratch for EXIT cleanup after a failed command.
929
966
  scratch="$(mktemp -d)"
930
967
  trap 'rm -rf -- "$scratch"' EXIT
@@ -943,9 +980,10 @@ install_rust() (
943
980
  rust_run network "$scratch/rustup-init" -y --no-modify-path --default-toolchain none --profile minimal
944
981
  fi
945
982
  rust_run local "$CARGO_HOME/bin/rustup" set auto-self-update disable
946
- if ! rust_ready; then
983
+ if ! primary_rust_ready; then
947
984
  rust_run network "$CARGO_HOME/bin/rustup" toolchain install @RUST@ --profile minimal --no-self-update @RUST_ARGS@
948
985
  fi
986
+ @INSTALL_ADDITIONAL_TOOLCHAINS@
949
987
  rust_run local "$CARGO_HOME/bin/rustup" default @RUST@
950
988
  verify_rust
951
989
  for tool in rustup cargo rustc rustdoc @RUST_PROXIES@; do
@@ -956,7 +994,7 @@ install_rust() (
956
994
  fi
957
995
  done
958
996
  )
959
- `.replaceAll("@RUSTUP@", rust.installer.version).replaceAll("@RUST@", rust.channel).replace("@RUSTUP_ARTIFACT@", artifactSelection(rust.installer)).replace("@RUST_ARGS@", args).replace("@RUST_PROXIES@", Object.entries(cloudRustComponentBinaries).flatMap(([component, binaries]) => rust.components.includes(component) ? Array.from(binaries) : []).join(" ")).replace("@VERIFY_COMPONENTS@", rust.components.map((name) => `rust_run local "$CARGO_HOME/bin/rustup" component list --toolchain ${quote(rust.channel)} --installed | awk -v name=${quote(name)} -v host="$host" '$1 == name || $1 == name "-" host { found=1 } END { exit !found }' || return 1`).join("\n ")).replace("@VERIFY_TARGETS@", rust.targets.map((name) => `rust_run local "$CARGO_HOME/bin/rustup" target list --toolchain ${quote(rust.channel)} --installed | awk -v name=${quote(name)} '$1 == name { found=1 } END { exit !found }' || return 1`).join("\n "));
997
+ `.replace("@VERIFY_ADDITIONAL_TOOLCHAINS@", rust.additionalToolchains.map((pin) => `additional_version="$(rust_run local "$CARGO_HOME/bin/rustc" +${pin} --version)" || return 1\n [[ "$additional_version" == 'rustc ${pin} '* ]] || return 1`).join("\n ")).replace("@INSTALL_ADDITIONAL_TOOLCHAINS@", rust.additionalToolchains.map((pin) => `if ! additional_version="$(rust_run local "$CARGO_HOME/bin/rustc" +${pin} --version)" || [[ "$additional_version" != 'rustc ${pin} '* ]]; then\n rust_run network "$CARGO_HOME/bin/rustup" toolchain install ${pin} --profile minimal --no-self-update\n fi`).join("\n ")).replaceAll("@RUSTUP@", rust.installer.version).replaceAll("@RUST@", rust.channel).replace("@RUSTUP_ARTIFACT@", artifactSelection(rust.installer)).replace("@RUST_ARGS@", args).replace("@RUST_PROXIES@", Object.entries(cloudRustComponentBinaries).flatMap(([component, binaries]) => rust.components.includes(component) ? Array.from(binaries) : []).join(" ")).replace("@VERIFY_COMPONENTS@", rust.components.map((name) => `rust_run local "$CARGO_HOME/bin/rustup" component list --toolchain ${quote(rust.channel)} --installed | awk -v name=${quote(name)} -v host="$host" '$1 == name || $1 == name "-" host { found=1 } END { exit !found }' || return 1`).join("\n ")).replace("@VERIFY_TARGETS@", rust.targets.map((name) => `rust_run local "$CARGO_HOME/bin/rustup" target list --toolchain ${quote(rust.channel)} --installed | awk -v name=${quote(name)} '$1 == name { found=1 } END { exit !found }' || return 1`).join("\n "));
960
998
  };
961
999
  const packageToolInstall = ({ tool, release }) => {
962
1000
  const name = tool.replaceAll("-", "_");
@@ -979,7 +1017,7 @@ install_${name}() {
979
1017
  const artifactToolInstall = ({ tool, release }) => {
980
1018
  const directory = `/opt/stll-cloud/tools/${tool}/${release.version}`;
981
1019
  const command = tool === "wasm-bindgen-cli" ? "wasm-bindgen" : tool;
982
- const marker = `${tool === "cargo-nextest" ? "cargo-nextest" : command} ${release.version}`;
1020
+ const marker = `${tool === "gitleaks" ? "gitleaks version" : command} ${release.version}`;
983
1021
  return {
984
1022
  name: tool.replaceAll("-", "_"),
985
1023
  text: `verify_${tool.replaceAll("-", "_")}() {
@@ -1089,7 +1127,15 @@ OUTPUT_USER="$(getent passwd "$OUTPUT_UID" | cut -d: -f1)"
1089
1127
  OUTPUT_HOME="$(getent passwd "$OUTPUT_UID" | cut -d: -f6)"
1090
1128
  [[ -n "$OUTPUT_USER" && "$OUTPUT_HOME" == /* && -d "$OUTPUT_HOME" ]] || fail 'Invoking user requires an existing home directory'
1091
1129
  root() { "$@"; }
1092
- service_run() { runuser -u stll-cloud -- "$@" 9>&-; }
1130
+ # Service daemons outlive setup, so they inherit no descriptor beyond stdio: a cloud
1131
+ # runner can pass its terminal as extra descriptors and wait until every copy closes.
1132
+ service_run() (
1133
+ for descriptor in "/proc/$BASHPID/fd/"*; do
1134
+ descriptor="$(basename -- "$descriptor")"
1135
+ if [[ "$descriptor" =~ ^[0-9]+$ ]] && (( descriptor > 2 )); then eval "exec $descriptor>&-"; fi
1136
+ done
1137
+ exec runuser -u stll-cloud -- "$@"
1138
+ )
1093
1139
  BUN_VERSION='@BUN@'
1094
1140
  NODE_VERSION='@NODE@'
1095
1141
  NODE_DIR="/opt/stll-cloud/node/$NODE_VERSION"
@@ -1108,19 +1154,35 @@ esac
1108
1154
 
1109
1155
  @NETWORK@
1110
1156
 
1157
+ node_ready() {
1158
+ local node_version npm_version npx_version
1159
+ [[ -x "$NODE_DIR/bin/node" && -x "$NODE_DIR/bin/npm" && -x "$NODE_DIR/bin/npx" ]] || return 1
1160
+ node_version="$("$NODE_DIR/bin/node" --version)" || return 1
1161
+ [[ "$node_version" == "v$NODE_VERSION" ]] || return 1
1162
+ npm_version="$("$NODE_DIR/bin/npm" --version)" || return 1
1163
+ [[ "$npm_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || return 1
1164
+ npx_version="$("$NODE_DIR/bin/npx" --version)" || return 1
1165
+ [[ "$npx_version" == "$npm_version" ]] || return 1
1166
+ }
1111
1167
  runtime_ready() {
1112
- [[ -x "$NODE_DIR/bin/node" && "$($NODE_DIR/bin/node --version)" == "v$NODE_VERSION" ]] || fail 'Pinned Node is unavailable; run install'
1168
+ node_ready || fail 'Pinned Node, npm or npx is unavailable; run install'
1113
1169
  [[ -x "$BUN_DIR/bun" && "$($BUN_DIR/bun --version)" == "$BUN_VERSION" ]] || fail 'Pinned Bun is unavailable; run install'
1114
1170
  }
1115
- install_runtimes() {
1171
+ install_runtimes() (
1172
+ if [[ ! -s /etc/ssl/certs/ca-certificates.crt ]]; then
1173
+ command -v update-ca-certificates >/dev/null || fail 'System CA certificate bundle is missing; restore ca-certificates in the base image offline before install'
1174
+ update-ca-certificates || fail 'System CA certificate bundle could not be repaired offline; restore ca-certificates in the base image before install'
1175
+ fi
1176
+ [[ -s /etc/ssl/certs/ca-certificates.crt ]] || fail 'System CA certificate bundle is unavailable after offline repair; restore ca-certificates in the base image before install'
1116
1177
  if ! command -v curl >/dev/null || ! command -v unzip >/dev/null || ! command -v xz >/dev/null || ! command -v openssl >/dev/null || ! command -v gpg >/dev/null || ! ldconfig -p | awk '$1 == "libatomic.so.1" { found=1 } END { exit !found }'; then
1117
1178
  apt_refresh_for ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1
1118
1179
  DEBIAN_FRONTEND=noninteractive apt_install ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1
1119
1180
  fi
1120
- local scratch node_archive bun_archive bun_folder
1181
+ local node_archive bun_archive bun_folder
1182
+ # Subshell scope retains scratch for EXIT cleanup after a failed command.
1121
1183
  scratch="$(mktemp -d)"
1122
- trap 'rm -rf -- "$scratch"' RETURN
1123
- if [[ ! -x "$NODE_DIR/bin/node" ]] || [[ "$($NODE_DIR/bin/node --version)" != "v$NODE_VERSION" ]]; then
1184
+ trap 'rm -rf -- "$scratch"' EXIT
1185
+ if ! node_ready; then
1124
1186
  node_archive="node-v$NODE_VERSION-linux-$NODE_ARCH.tar.xz"
1125
1187
  download_file "https://nodejs.org/dist/v$NODE_VERSION/$node_archive" "$scratch/$node_archive" 120
1126
1188
  download_file "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt" "$scratch/node-sums" 45
@@ -1143,9 +1205,7 @@ install_runtimes() {
1143
1205
  ln -sfnT -- "$NODE_DIR/bin/npm" /usr/local/bin/npm
1144
1206
  ln -sfnT -- "$NODE_DIR/bin/npx" /usr/local/bin/npx
1145
1207
  ln -sfnT -- "$BUN_DIR/bun" /usr/local/bin/bun
1146
- rm -rf -- "$scratch"
1147
- trap - RETURN
1148
- }
1208
+ )
1149
1209
 
1150
1210
  dependency_install() {
1151
1211
  local directory download_hosts
@@ -1309,16 +1369,16 @@ const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExcept
1309
1369
  valkey: policy.valkey
1310
1370
  })]
1311
1371
  ]);
1312
- return script.replace(/@[A-Z0-9_]+@/g, (token) => {
1372
+ return `${script.replace(/@[A-Z0-9_]+@/g, (token) => {
1313
1373
  const value = replacements.get(token);
1314
1374
  if (value === void 0) throw new Error(`Missing cloud setup field: ${token}`);
1315
1375
  return value;
1316
- });
1376
+ }).replace(/[ \t]+$/gm, "").trimEnd()}\n`;
1317
1377
  };
1318
1378
  //#endregion
1319
1379
  //#region src/cloud-setup-claude.ts
1320
1380
  const cloudClaudeSettingsPath = ".claude/settings.json";
1321
- const sessionStartHook = (script) => ({
1381
+ const releasedSessionStartHook = (script) => ({
1322
1382
  matcher: "",
1323
1383
  hooks: [{
1324
1384
  type: "command",
@@ -1335,8 +1395,30 @@ const sessionStartHook = (script) => ({
1335
1395
  fi`
1336
1396
  }]
1337
1397
  });
1398
+ const sessionStartHook = (script) => ({
1399
+ matcher: "",
1400
+ hooks: [{
1401
+ type: "command",
1402
+ command: `if [ "\${CLAUDE_CODE_REMOTE:-}" = "true" ]; then
1403
+ cloud_setup_incomplete() {
1404
+ printf '%s\\n' 'Cloud setup could not establish a verified session environment. From the repository root, run bash .agents/cloud-setup.sh install and then bash .agents/cloud-setup.sh start. Do not assume pinned tools or services are ready until start succeeds.'
1405
+ printf '%s\\n' "cloud-setup: $1" >&2
1406
+ exit 0
1407
+ }
1408
+ ${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'
1409
+ if [ -n "\${CLAUDE_ENV_FILE:-}" ]; then
1410
+ if [ ! -s ${cloudShellProfilePath} ]; then
1411
+ cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
1412
+ fi
1413
+ cloud_shell_exports="$(cat ${cloudShellProfilePath})" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'
1414
+ [ -n "$cloud_shell_exports" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
1415
+ printf '\\n%s\\n' "$cloud_shell_exports" >> "$CLAUDE_ENV_FILE" || cloud_setup_incomplete 'session environment could not be persisted; check its write access and rerun start'
1416
+ fi
1417
+ fi`
1418
+ }]
1419
+ });
1338
1420
  const cloudSessionStartHook = sessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`);
1339
- const previousCloudSessionStartHooks = [sessionStartHook(`bash ${cloudSetupPath}`)];
1421
+ const previousCloudSessionStartHooks = [releasedSessionStartHook(`bash ${cloudSetupPath}`), releasedSessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`)];
1340
1422
  const cloudAttribution = {
1341
1423
  commit: "",
1342
1424
  pr: ""
@@ -1570,6 +1652,18 @@ const javascriptDependencyLockfiles = [
1570
1652
  "yarn.lock",
1571
1653
  "pnpm-lock.yaml"
1572
1654
  ];
1655
+ const dependabotManifestEcosystems = {
1656
+ Gemfile: "bundler",
1657
+ "Gemfile.lock": "bundler",
1658
+ "composer.json": "composer",
1659
+ "composer.lock": "composer"
1660
+ };
1661
+ /** Share ecosystem inventory with snapshot selection; no dependency graph reads are needed. */
1662
+ const dependabotManifestEcosystem = (file) => {
1663
+ if (excludedInputPath(file)) return void 0;
1664
+ const basename = file.split("/").at(-1);
1665
+ for (const [name, ecosystem] of Object.entries(dependabotManifestEcosystems)) if (basename === name) return ecosystem;
1666
+ };
1573
1667
  /** Match project, environment, local, and fragment filenames recognized by mise. */
1574
1668
  const isMiseConfigPath = (file) => !excludedInputPath(file) && (/(?:^|\/)\.?mise(?:\.[^./][^/]*)?\.toml$/.test(file) || /(?:^|\/)(?:\.?mise|\.config\/mise)\/config(?:\.[^./][^/]*)?\.toml$/.test(file) || /(?:^|\/)(?:\.?mise|\.config\/mise)\/conf\.d\/[^./][^/]*\.toml$/.test(file));
1575
1669
  /** GitHub action metadata may live at the repository root or in any directory. */
@@ -1608,7 +1702,7 @@ const toolchainInputKind = (file, text = "") => {
1608
1702
  if (file === ".agents/cloud-setup.sh" || file === ".claude/settings.json" || file === "Cargo.lock") return "config";
1609
1703
  if (githubAutomationFileKind(file) !== void 0) return "config";
1610
1704
  if (excludedInputPath(file)) return void 0;
1611
- if (pythonDependencyManifestKind(file) === "pipfile-lock" || javascriptDependencyLockfiles.some((name) => file.split("/").at(-1) === name) || /(?:^|\/)uv\.lock$/.test(file)) return "presence";
1705
+ if (dependabotManifestEcosystem(file) !== void 0 || pythonDependencyManifestKind(file) === "pipfile-lock" || javascriptDependencyLockfiles.some((name) => file.split("/").at(-1) === name) || /(?:^|\/)uv\.lock$/.test(file)) return "presence";
1612
1706
  if (githubAutomationFileKind(file) !== void 0 || isShellScript(file, text) || /(?:^|\/)ci-service-images\.json$/.test(file) || isMiseConfigPath(file) || isPythonDependencyManifest(file) || isDockerDefinitionPath(file) || isComposeDefinitionPath(file) || isKubernetesDefinitionPath(file) || /(?:^|\/)(?:package\.json|consumer-compat\.json|pnpm-workspace\.yaml|stll-toolchain\.json|\.bun-version|\.node-version|\.nvmrc|\.python-version|rust-toolchain(?:\.toml)?|\.tool-versions|\.?mise\.toml|uv\.toml|\.uv\.toml|\.github\/dependabot\.ya?ml|Cargo\.toml)$/.test(file)) return "config";
1613
1707
  };
1614
1708
  //#endregion
@@ -1642,6 +1736,12 @@ Object.defineProperty(exports, "containerDocumentImages", {
1642
1736
  return containerDocumentImages;
1643
1737
  }
1644
1738
  });
1739
+ Object.defineProperty(exports, "dependabotManifestEcosystem", {
1740
+ enumerable: true,
1741
+ get: function() {
1742
+ return dependabotManifestEcosystem;
1743
+ }
1744
+ });
1645
1745
  Object.defineProperty(exports, "generateCloudSetup", {
1646
1746
  enumerable: true,
1647
1747
  get: function() {