@stll/oxlint-config 1.3.1 → 1.5.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.
- package/README.md +341 -28
- package/dist/cloud-setup-cli.cjs +20 -40
- package/dist/cloud-setup-cli.cjs.map +1 -1
- package/dist/cloud-setup-cli.mjs +21 -41
- package/dist/cloud-setup-cli.mjs.map +1 -1
- package/dist/consumer-compat-cli.cjs +52 -251
- package/dist/consumer-compat-cli.cjs.map +1 -1
- package/dist/consumer-compat-cli.mjs +7 -206
- package/dist/consumer-compat-cli.mjs.map +1 -1
- package/dist/consumer-node-support.cjs +497 -0
- package/dist/consumer-node-support.cjs.map +1 -0
- package/dist/consumer-node-support.mjs +381 -0
- package/dist/consumer-node-support.mjs.map +1 -0
- package/dist/dependabot-cli.cjs +91 -0
- package/dist/dependabot-cli.cjs.map +1 -0
- package/dist/dependabot-cli.d.cts +1 -0
- package/dist/dependabot-cli.d.mts +1 -0
- package/dist/dependabot-cli.mjs +91 -0
- package/dist/dependabot-cli.mjs.map +1 -0
- package/dist/dependabot.cjs +7 -0
- package/dist/dependabot.d.cts +118 -0
- package/dist/dependabot.d.mts +118 -0
- package/dist/dependabot.mjs +3 -0
- package/dist/generated-file.cjs +61 -0
- package/dist/generated-file.cjs.map +1 -0
- package/dist/generated-file.mjs +44 -0
- package/dist/generated-file.mjs.map +1 -0
- package/dist/git-tracked-output.cjs +2 -2
- package/dist/git-tracked-output.mjs +1 -1
- package/dist/jsonc.cjs +66 -0
- package/dist/jsonc.cjs.map +1 -0
- package/dist/jsonc.mjs +61 -0
- package/dist/jsonc.mjs.map +1 -0
- package/dist/publish-artifact-syntax.cjs +1309 -0
- package/dist/publish-artifact-syntax.cjs.map +1 -0
- package/dist/publish-artifact-syntax.mjs +1265 -0
- package/dist/publish-artifact-syntax.mjs.map +1 -0
- package/dist/publish-build-target-vite-dts-helper2.cjs +1 -1
- package/dist/publish-build-target-vite-dts-helper2.mjs +1 -1
- package/dist/publish-contract-cli.cjs +55 -14
- package/dist/publish-contract-cli.cjs.map +1 -1
- package/dist/publish-contract-cli.mjs +50 -9
- package/dist/publish-contract-cli.mjs.map +1 -1
- package/dist/quarantine-cli.cjs +66 -0
- package/dist/quarantine-cli.cjs.map +1 -0
- package/dist/quarantine-cli.d.cts +1 -0
- package/dist/quarantine-cli.d.mts +1 -0
- package/dist/quarantine-cli.mjs +66 -0
- package/dist/quarantine-cli.mjs.map +1 -0
- package/dist/quarantine-policy.cjs +10 -0
- package/dist/quarantine-policy.d.cts +27 -0
- package/dist/quarantine-policy.d.mts +27 -0
- package/dist/quarantine-policy.mjs +1 -0
- package/dist/quarantine-policy2.cjs +399 -0
- package/dist/quarantine-policy2.cjs.map +1 -0
- package/dist/quarantine-policy2.mjs +352 -0
- package/dist/quarantine-policy2.mjs.map +1 -0
- package/dist/toolchain-changed.cjs +16 -67
- package/dist/toolchain-changed.cjs.map +1 -1
- package/dist/toolchain-changed.mjs +19 -70
- package/dist/toolchain-changed.mjs.map +1 -1
- package/dist/toolchain-check-cli.cjs +1 -0
- package/dist/toolchain-check-cli.cjs.map +1 -1
- package/dist/toolchain-check-cli.mjs +1 -0
- package/dist/toolchain-check-cli.mjs.map +1 -1
- package/dist/toolchain-dependabot.cjs +529 -0
- package/dist/toolchain-dependabot.cjs.map +1 -0
- package/dist/toolchain-dependabot.mjs +485 -0
- package/dist/toolchain-dependabot.mjs.map +1 -0
- package/dist/toolchain-guard.cjs +1143 -432
- package/dist/toolchain-guard.cjs.map +1 -1
- package/dist/toolchain-guard.mjs +1132 -421
- package/dist/toolchain-guard.mjs.map +1 -1
- package/dist/toolchain-inputs.cjs +216 -38
- package/dist/toolchain-inputs.cjs.map +1 -1
- package/dist/toolchain-inputs.mjs +213 -41
- package/dist/toolchain-inputs.mjs.map +1 -1
- package/dist/toolchain-schema.cjs +0 -493
- package/dist/toolchain-schema.cjs.map +1 -1
- package/dist/toolchain-schema.mjs +3 -379
- package/dist/toolchain-schema.mjs.map +1 -1
- package/dist/typecheck-parity.cjs +4 -3
- package/dist/typecheck-parity.cjs.map +1 -1
- package/dist/typecheck-parity.mjs +4 -3
- package/dist/typecheck-parity.mjs.map +1 -1
- package/dist/typecheck-probe-cli.cjs +3 -3
- package/dist/typecheck-probe-cli.cjs.map +1 -1
- package/dist/typecheck-probe-cli.mjs +3 -3
- package/dist/typecheck-probe-cli.mjs.map +1 -1
- package/package.json +25 -1
- package/toolchain.json +11 -4
- package/dist/publish-contract.cjs +0 -431
- package/dist/publish-contract.cjs.map +0 -1
- package/dist/publish-contract.mjs +0 -396
- package/dist/publish-contract.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { parse } from "smol-toml";
|
|
2
3
|
import { createHash } from "node:crypto";
|
|
3
4
|
import { subset, valid, validRange } from "semver";
|
|
4
|
-
import { parse as parse$1 } from "smol-toml";
|
|
5
5
|
import { isDeepStrictEqual } from "node:util";
|
|
6
6
|
import { parseDocument } from "yaml";
|
|
7
7
|
import picomatch from "picomatch";
|
|
@@ -375,6 +375,21 @@ const cloudSetupArtifacts = {
|
|
|
375
375
|
binaries: { "rustup-init": "rustup-init" }
|
|
376
376
|
}
|
|
377
377
|
},
|
|
378
|
+
gitleaks: {
|
|
379
|
+
version: "8.30.1",
|
|
380
|
+
amd64: {
|
|
381
|
+
url: "https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz",
|
|
382
|
+
sha256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb",
|
|
383
|
+
archive: "tar.gz",
|
|
384
|
+
binaries: { gitleaks: "gitleaks" }
|
|
385
|
+
},
|
|
386
|
+
arm64: {
|
|
387
|
+
url: "https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_arm64.tar.gz",
|
|
388
|
+
sha256: "e4a487ee7ccd7d3a7f7ec08657610aa3606637dab924210b3aee62570fb4b080",
|
|
389
|
+
archive: "tar.gz",
|
|
390
|
+
binaries: { gitleaks: "gitleaks" }
|
|
391
|
+
}
|
|
392
|
+
},
|
|
378
393
|
"cargo-nextest": {
|
|
379
394
|
version: "0.9.148",
|
|
380
395
|
amd64: {
|
|
@@ -442,7 +457,8 @@ const cloudSetupArtifactVersions = {
|
|
|
442
457
|
"rustup-init": [cloudSetupArtifacts["rustup-init"]],
|
|
443
458
|
"cargo-nextest": [cloudSetupArtifacts["cargo-nextest"]],
|
|
444
459
|
"wasm-bindgen-cli": wasmBindgenArtifactReleases,
|
|
445
|
-
uv: [cloudSetupArtifacts.uv]
|
|
460
|
+
uv: [cloudSetupArtifacts.uv],
|
|
461
|
+
gitleaks: [cloudSetupArtifacts.gitleaks]
|
|
446
462
|
};
|
|
447
463
|
/** A new version requires an explicit, verified catalog entry; never build from source. */
|
|
448
464
|
const getCloudSetupArtifact = (tool, version) => {
|
|
@@ -497,11 +513,20 @@ const parseRust = (input) => {
|
|
|
497
513
|
if (!object(input) || Object.keys(input).some((key) => ![
|
|
498
514
|
"toolchain",
|
|
499
515
|
"components",
|
|
500
|
-
"targets"
|
|
501
|
-
|
|
516
|
+
"targets",
|
|
517
|
+
"additionalToolchains"
|
|
518
|
+
].includes(key))) throw new Error("cloud.rust accepts only toolchain, components, targets and additionalToolchains");
|
|
502
519
|
const toolchain = input["toolchain"];
|
|
503
520
|
if (toolchain !== void 0 && !exactPin(toolchain)) throw new Error("cloud.rust.toolchain must be an exact stable release");
|
|
521
|
+
const additional = input["additionalToolchains"];
|
|
522
|
+
if (additional !== void 0 && !Array.isArray(additional)) throw new Error("cloud.rust.additionalToolchains requires exact stable releases");
|
|
523
|
+
const additionalToolchains = additional === void 0 ? [] : Array.from(additional, (pin) => {
|
|
524
|
+
if (!exactPin(pin)) throw new Error("cloud.rust.additionalToolchains requires exact stable releases");
|
|
525
|
+
return pin;
|
|
526
|
+
});
|
|
527
|
+
if (new Set(additionalToolchains).size !== additionalToolchains.length) throw new Error("cloud.rust.additionalToolchains contains duplicates");
|
|
504
528
|
return {
|
|
529
|
+
additionalToolchains,
|
|
505
530
|
...toolchain === void 0 ? {} : { toolchain },
|
|
506
531
|
components: parseCloudRustNames(input["components"], "components"),
|
|
507
532
|
targets: parseCloudRustNames(input["targets"], "targets")
|
|
@@ -672,7 +697,12 @@ const postgresStart = String.raw`
|
|
|
672
697
|
pg_pid="$(head -n 1 "$pg_data/postmaster.pid")"
|
|
673
698
|
service_process "$pg_pid" "$pg_bin/postgres"
|
|
674
699
|
[[ "$(env -u PGSERVICE -u PGSERVICEFILE -u PGOPTIONS PGHOSTADDR=127.0.0.1 PGPASSWORD="$pg_password" PGCONNECT_TIMEOUT=2 "$pg_bin/psql" -X -h 127.0.0.1 -p 55432 -U stll_cloud -d postgres -At -v ON_ERROR_STOP=1 -c "SELECT count(*) FROM pg_database WHERE datname = 'cloud_test'")" == 1 ]] || env -u PGSERVICE -u PGSERVICEFILE -u PGOPTIONS PGHOSTADDR=127.0.0.1 PGPASSWORD="$pg_password" PGCONNECT_TIMEOUT=2 "$pg_bin/createdb" -h 127.0.0.1 -p 55432 -U stll_cloud cloud_test || fail "PostgreSQL test database creation failed"
|
|
675
|
-
|
|
700
|
+
POSTGRES_HOST='127.0.0.1:55432'
|
|
701
|
+
POSTGRES_USER='stll_cloud'
|
|
702
|
+
POSTGRES_PASSWORD="$pg_password"
|
|
703
|
+
POSTGRES_DB_NAME='cloud_test'
|
|
704
|
+
POSTGRES_ADDITIONAL_CONNECTION_DATA=''
|
|
705
|
+
DATABASE_URL="postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/$POSTGRES_DB_NAME$POSTGRES_ADDITIONAL_CONNECTION_DATA"
|
|
676
706
|
printf 'postgres: %s\n' "$pg_state"
|
|
677
707
|
`;
|
|
678
708
|
const valkeyStart = String.raw`
|
|
@@ -817,7 +847,7 @@ const resolveCloudToolchains = ({ cloud, files, rust, rustExceptions }) => {
|
|
|
817
847
|
if (source !== void 0 && selector !== void 0) throw new Error("cloud Rust requires one root rust-toolchain.toml or rust-toolchain file");
|
|
818
848
|
let declared;
|
|
819
849
|
if (source !== void 0 || selector?.trimStart().startsWith("[")) {
|
|
820
|
-
const parsed = parse
|
|
850
|
+
const parsed = parse(source ?? selector ?? "");
|
|
821
851
|
if (!record$2(parsed["toolchain"])) throw new Error("cloud Rust requires [toolchain]");
|
|
822
852
|
declared = parsed["toolchain"];
|
|
823
853
|
if (Object.keys(declared).some((key) => ![
|
|
@@ -835,6 +865,11 @@ const resolveCloudToolchains = ({ cloud, files, rust, rustExceptions }) => {
|
|
|
835
865
|
if (channel !== rust && !rustExceptions.some(({ pin }) => pin === channel)) throw new Error(`cloud Rust must use shared Rust ${rust} or a recorded rustExceptions pin`);
|
|
836
866
|
if (cloud.rust?.toolchain !== void 0 && cloud.rust.toolchain !== channel) throw new Error("cloud.rust.toolchain conflicts with root Rust toolchain");
|
|
837
867
|
}
|
|
868
|
+
const additionalToolchains = cloud.rust?.additionalToolchains ?? [];
|
|
869
|
+
for (const pin of additionalToolchains) {
|
|
870
|
+
if (pin === channel) throw new Error("cloud.rust.additionalToolchains must not repeat the primary toolchain");
|
|
871
|
+
if (pin !== rust && !rustExceptions.some(({ pin: authorized }) => authorized === pin)) throw new Error(`cloud.rust.additionalToolchains ${pin} requires an authorized rustExceptions pin`);
|
|
872
|
+
}
|
|
838
873
|
const components = [.../* @__PURE__ */ new Set([...parseCloudRustNames(declared?.["components"], "components"), ...cloud.rust?.components ?? []])].sort();
|
|
839
874
|
const targets = [.../* @__PURE__ */ new Set([...parseCloudRustNames(declared?.["targets"], "targets"), ...cloud.rust?.targets ?? []])].sort();
|
|
840
875
|
const resolveTool = (tool, version) => {
|
|
@@ -847,7 +882,7 @@ const resolveCloudToolchains = ({ cloud, files, rust, rustExceptions }) => {
|
|
|
847
882
|
if (tool === "wasm-bindgen-cli") {
|
|
848
883
|
const lock = files["Cargo.lock"];
|
|
849
884
|
if (lock === void 0) throw new Error("wasm-bindgen-cli requires tracked root Cargo.lock");
|
|
850
|
-
const packages = parse
|
|
885
|
+
const packages = parse(lock)["package"];
|
|
851
886
|
if (!Array.isArray(packages)) throw new Error("Cargo.lock requires package entries for wasm-bindgen-cli");
|
|
852
887
|
const versions = new Set(packages.flatMap((entry) => record$2(entry) && entry["name"] === "wasm-bindgen" ? [entry["version"]] : []));
|
|
853
888
|
if (versions.size !== 1 || !versions.has(version)) throw new Error(`cloud.tools.wasm-bindgen-cli ${version} must equal the unique wasm-bindgen crate version in Cargo.lock (found ${[...versions].join(", ") || "none"})`);
|
|
@@ -865,6 +900,7 @@ const resolveCloudToolchains = ({ cloud, files, rust, rustExceptions }) => {
|
|
|
865
900
|
return {
|
|
866
901
|
rust: rustEnabled && typeof channel === "string" ? {
|
|
867
902
|
channel,
|
|
903
|
+
additionalToolchains: [...additionalToolchains].sort(),
|
|
868
904
|
components,
|
|
869
905
|
targets,
|
|
870
906
|
installer: cloudSetupArtifacts["rustup-init"]
|
|
@@ -901,7 +937,7 @@ rust_run() {
|
|
|
901
937
|
*) fail 'Invalid Rust execution mode' ;;
|
|
902
938
|
esac
|
|
903
939
|
}
|
|
904
|
-
|
|
940
|
+
primary_rust_ready() {
|
|
905
941
|
local directory
|
|
906
942
|
for directory in "$RUSTUP_HOME" "$CARGO_HOME"; do
|
|
907
943
|
[[ -d "$directory" && ! -L "$directory" && "$(stat -c '%u' "$directory")" == "$OUTPUT_UID" ]] || return 1
|
|
@@ -915,13 +951,19 @@ rust_ready() {
|
|
|
915
951
|
@VERIFY_TARGETS@
|
|
916
952
|
return 0
|
|
917
953
|
}
|
|
954
|
+
rust_ready() {
|
|
955
|
+
local additional_version
|
|
956
|
+
primary_rust_ready || return 1
|
|
957
|
+
@VERIFY_ADDITIONAL_TOOLCHAINS@
|
|
958
|
+
return 0
|
|
959
|
+
}
|
|
918
960
|
verify_rust() { rust_ready || fail 'Pinned Rust, components or targets are unavailable; run install'; }
|
|
919
961
|
install_rust() (
|
|
920
962
|
if ! command -v cc >/dev/null || ! command -v ld >/dev/null || [[ ! -f /usr/include/stdlib.h ]]; then
|
|
921
963
|
apt_refresh_for build-essential
|
|
922
964
|
apt_install build-essential
|
|
923
965
|
fi
|
|
924
|
-
local artifact_url artifact_sha
|
|
966
|
+
local artifact_url artifact_sha additional_version
|
|
925
967
|
# Subshell scope retains scratch for EXIT cleanup after a failed command.
|
|
926
968
|
scratch="$(mktemp -d)"
|
|
927
969
|
trap 'rm -rf -- "$scratch"' EXIT
|
|
@@ -940,9 +982,10 @@ install_rust() (
|
|
|
940
982
|
rust_run network "$scratch/rustup-init" -y --no-modify-path --default-toolchain none --profile minimal
|
|
941
983
|
fi
|
|
942
984
|
rust_run local "$CARGO_HOME/bin/rustup" set auto-self-update disable
|
|
943
|
-
if !
|
|
985
|
+
if ! primary_rust_ready; then
|
|
944
986
|
rust_run network "$CARGO_HOME/bin/rustup" toolchain install @RUST@ --profile minimal --no-self-update @RUST_ARGS@
|
|
945
987
|
fi
|
|
988
|
+
@INSTALL_ADDITIONAL_TOOLCHAINS@
|
|
946
989
|
rust_run local "$CARGO_HOME/bin/rustup" default @RUST@
|
|
947
990
|
verify_rust
|
|
948
991
|
for tool in rustup cargo rustc rustdoc @RUST_PROXIES@; do
|
|
@@ -953,7 +996,7 @@ install_rust() (
|
|
|
953
996
|
fi
|
|
954
997
|
done
|
|
955
998
|
)
|
|
956
|
-
`.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 "));
|
|
999
|
+
`.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 "));
|
|
957
1000
|
};
|
|
958
1001
|
const packageToolInstall = ({ tool, release }) => {
|
|
959
1002
|
const name = tool.replaceAll("-", "_");
|
|
@@ -976,7 +1019,7 @@ install_${name}() {
|
|
|
976
1019
|
const artifactToolInstall = ({ tool, release }) => {
|
|
977
1020
|
const directory = `/opt/stll-cloud/tools/${tool}/${release.version}`;
|
|
978
1021
|
const command = tool === "wasm-bindgen-cli" ? "wasm-bindgen" : tool;
|
|
979
|
-
const marker = `${tool === "
|
|
1022
|
+
const marker = `${tool === "gitleaks" ? "gitleaks version" : command} ${release.version}`;
|
|
980
1023
|
return {
|
|
981
1024
|
name: tool.replaceAll("-", "_"),
|
|
982
1025
|
text: `verify_${tool.replaceAll("-", "_")}() {
|
|
@@ -1055,9 +1098,9 @@ const script = String.raw`#!/usr/bin/env bash
|
|
|
1055
1098
|
# Supported platform: Ubuntu 24.04 (noble), amd64/arm64, root or passwordless sudo.
|
|
1056
1099
|
set -euo pipefail
|
|
1057
1100
|
|
|
1058
|
-
usage() { echo 'Usage: cloud-setup.sh install|start' >&2; exit 2; }
|
|
1101
|
+
usage() { echo 'Usage: cloud-setup.sh install|start|session' >&2; exit 2; }
|
|
1059
1102
|
[[ "$#" == 1 ]] || usage
|
|
1060
|
-
case "$1" in install|start) MODE="$1" ;; *) usage ;; esac
|
|
1103
|
+
case "$1" in install|start|session) MODE="$1" ;; *) usage ;; esac
|
|
1061
1104
|
fail() { echo "cloud-setup: $*" >&2; exit 1; }
|
|
1062
1105
|
trap 'echo "cloud-setup: command failed at line $LINENO" >&2' ERR
|
|
1063
1106
|
# Each phase logs its start and duration so a stalled phase is visible in the task log.
|
|
@@ -1113,19 +1156,35 @@ esac
|
|
|
1113
1156
|
|
|
1114
1157
|
@NETWORK@
|
|
1115
1158
|
|
|
1159
|
+
node_ready() {
|
|
1160
|
+
local node_version npm_version npx_version
|
|
1161
|
+
[[ -x "$NODE_DIR/bin/node" && -x "$NODE_DIR/bin/npm" && -x "$NODE_DIR/bin/npx" ]] || return 1
|
|
1162
|
+
node_version="$("$NODE_DIR/bin/node" --version)" || return 1
|
|
1163
|
+
[[ "$node_version" == "v$NODE_VERSION" ]] || return 1
|
|
1164
|
+
npm_version="$("$NODE_DIR/bin/npm" --version)" || return 1
|
|
1165
|
+
[[ "$npm_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || return 1
|
|
1166
|
+
npx_version="$("$NODE_DIR/bin/npx" --version)" || return 1
|
|
1167
|
+
[[ "$npx_version" == "$npm_version" ]] || return 1
|
|
1168
|
+
}
|
|
1116
1169
|
runtime_ready() {
|
|
1117
|
-
|
|
1170
|
+
node_ready || fail 'Pinned Node, npm or npx is unavailable; run install'
|
|
1118
1171
|
[[ -x "$BUN_DIR/bun" && "$($BUN_DIR/bun --version)" == "$BUN_VERSION" ]] || fail 'Pinned Bun is unavailable; run install'
|
|
1119
1172
|
}
|
|
1120
|
-
install_runtimes()
|
|
1173
|
+
install_runtimes() (
|
|
1174
|
+
if [[ ! -s /etc/ssl/certs/ca-certificates.crt ]]; then
|
|
1175
|
+
command -v update-ca-certificates >/dev/null || fail 'System CA certificate bundle is missing; restore ca-certificates in the base image offline before install'
|
|
1176
|
+
update-ca-certificates || fail 'System CA certificate bundle could not be repaired offline; restore ca-certificates in the base image before install'
|
|
1177
|
+
fi
|
|
1178
|
+
[[ -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'
|
|
1121
1179
|
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
|
|
1122
1180
|
apt_refresh_for ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1
|
|
1123
1181
|
DEBIAN_FRONTEND=noninteractive apt_install ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1
|
|
1124
1182
|
fi
|
|
1125
|
-
local
|
|
1183
|
+
local node_archive bun_archive bun_folder
|
|
1184
|
+
# Subshell scope retains scratch for EXIT cleanup after a failed command.
|
|
1126
1185
|
scratch="$(mktemp -d)"
|
|
1127
|
-
trap 'rm -rf -- "$scratch"'
|
|
1128
|
-
if
|
|
1186
|
+
trap 'rm -rf -- "$scratch"' EXIT
|
|
1187
|
+
if ! node_ready; then
|
|
1129
1188
|
node_archive="node-v$NODE_VERSION-linux-$NODE_ARCH.tar.xz"
|
|
1130
1189
|
download_file "https://nodejs.org/dist/v$NODE_VERSION/$node_archive" "$scratch/$node_archive" 120
|
|
1131
1190
|
download_file "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt" "$scratch/node-sums" 45
|
|
@@ -1148,9 +1207,7 @@ install_runtimes() {
|
|
|
1148
1207
|
ln -sfnT -- "$NODE_DIR/bin/npm" /usr/local/bin/npm
|
|
1149
1208
|
ln -sfnT -- "$NODE_DIR/bin/npx" /usr/local/bin/npx
|
|
1150
1209
|
ln -sfnT -- "$BUN_DIR/bun" /usr/local/bin/bun
|
|
1151
|
-
|
|
1152
|
-
trap - RETURN
|
|
1153
|
-
}
|
|
1210
|
+
)
|
|
1154
1211
|
|
|
1155
1212
|
dependency_install() {
|
|
1156
1213
|
local directory download_hosts
|
|
@@ -1196,6 +1253,8 @@ process.stdout.write([...hosts].sort().join(","));
|
|
|
1196
1253
|
@INPUT_VALIDATION@
|
|
1197
1254
|
|
|
1198
1255
|
@ENV_FUNCTIONS@
|
|
1256
|
+
@ENVIRONMENT_VALUES@
|
|
1257
|
+
@SESSION_ENVIRONMENT@
|
|
1199
1258
|
|
|
1200
1259
|
@PREPARE_FUNCTION@
|
|
1201
1260
|
|
|
@@ -1208,14 +1267,38 @@ if [[ "$MODE" == install ]]; then
|
|
|
1208
1267
|
@PREPARE_STEP@
|
|
1209
1268
|
exit 0
|
|
1210
1269
|
fi
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
step
|
|
1214
|
-
step
|
|
1215
|
-
|
|
1216
|
-
step
|
|
1217
|
-
|
|
1218
|
-
|
|
1270
|
+
@ENV_INITIALIZE@
|
|
1271
|
+
start_environment() {
|
|
1272
|
+
step runtime-check runtime_ready
|
|
1273
|
+
step tool-check verify_tools
|
|
1274
|
+
step shell install_shell_environment
|
|
1275
|
+
step shell-check verify_shell_environment
|
|
1276
|
+
@ENV_VALIDATE@
|
|
1277
|
+
step state prepare_state
|
|
1278
|
+
step service-start start_services
|
|
1279
|
+
@ENV_WRITE@
|
|
1280
|
+
}
|
|
1281
|
+
if [[ "$MODE" == session ]]; then
|
|
1282
|
+
start_environment >&2
|
|
1283
|
+
else
|
|
1284
|
+
start_environment
|
|
1285
|
+
fi
|
|
1286
|
+
@SESSION_ENVIRONMENT_CALL@
|
|
1287
|
+
`;
|
|
1288
|
+
const environmentValuesFunction = String.raw`
|
|
1289
|
+
environment_values() {
|
|
1290
|
+
local emit="$1"
|
|
1291
|
+
"$emit" NODE_ENV test
|
|
1292
|
+
if [[ -n "$DATABASE_URL" ]]; then
|
|
1293
|
+
"$emit" DATABASE_URL "$DATABASE_URL"
|
|
1294
|
+
"$emit" POSTGRES_HOST "$POSTGRES_HOST"
|
|
1295
|
+
"$emit" POSTGRES_USER "$POSTGRES_USER"
|
|
1296
|
+
"$emit" POSTGRES_PASSWORD "$POSTGRES_PASSWORD"
|
|
1297
|
+
"$emit" POSTGRES_DB_NAME "$POSTGRES_DB_NAME"
|
|
1298
|
+
"$emit" POSTGRES_ADDITIONAL_CONNECTION_DATA "$POSTGRES_ADDITIONAL_CONNECTION_DATA"
|
|
1299
|
+
fi
|
|
1300
|
+
if [[ -n "$REDIS_URL" ]]; then "$emit" REDIS_URL "$REDIS_URL"; fi
|
|
1301
|
+
}
|
|
1219
1302
|
`;
|
|
1220
1303
|
const environmentFunctions = String.raw`
|
|
1221
1304
|
validate_environment() {
|
|
@@ -1231,20 +1314,26 @@ validate_environment() {
|
|
|
1231
1314
|
[[ "$first_line" == "$ENV_MARKER" ]] || fail 'Refusing to overwrite an unowned environment file'
|
|
1232
1315
|
fi
|
|
1233
1316
|
}
|
|
1317
|
+
environment_file_value() { printf '%s=%s\n' "$1" "$2"; }
|
|
1234
1318
|
write_environment() {
|
|
1235
1319
|
validate_environment
|
|
1236
1320
|
local env_path="$REPO_ROOT/$ENV_FILE" temporary
|
|
1237
1321
|
temporary="$(mktemp "$(dirname -- "$env_path")/.stll-cloud-env.XXXXXX")"
|
|
1238
1322
|
chmod 600 "$temporary"
|
|
1239
1323
|
{
|
|
1240
|
-
printf '%s\n' "$ENV_MARKER"
|
|
1241
|
-
|
|
1242
|
-
if [[ -n "$REDIS_URL" ]]; then printf 'REDIS_URL=%s\n' "$REDIS_URL"; fi
|
|
1324
|
+
printf '%s\n' "$ENV_MARKER"
|
|
1325
|
+
environment_values environment_file_value
|
|
1243
1326
|
} > "$temporary"
|
|
1244
1327
|
chown "$OUTPUT_UID:$OUTPUT_GID" "$temporary"
|
|
1245
1328
|
mv -f -- "$temporary" "$env_path"
|
|
1246
1329
|
}
|
|
1247
1330
|
`;
|
|
1331
|
+
const sessionEnvironmentFunction = String.raw`
|
|
1332
|
+
environment_shell_value() { printf 'export %s=%q\n' "$1" "$2"; }
|
|
1333
|
+
emit_session_environment() {
|
|
1334
|
+
environment_values environment_shell_value
|
|
1335
|
+
}
|
|
1336
|
+
`;
|
|
1248
1337
|
const shellQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
1249
1338
|
const renderPrepare = (prepare, files) => {
|
|
1250
1339
|
if (prepare === void 0) return "";
|
|
@@ -1298,7 +1387,11 @@ const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExcept
|
|
|
1298
1387
|
["@NODE@", exactNode],
|
|
1299
1388
|
["@ENV_ASSIGNMENTS@", selected.envFile === void 0 ? "" : `ENV_FILE=${shellQuote(selected.envFile)}\nENV_MARKER=${shellQuote(cloudEnvironmentMarker)}`],
|
|
1300
1389
|
["@ENV_FUNCTIONS@", selected.envFile === void 0 ? "" : environmentFunctions],
|
|
1301
|
-
["@
|
|
1390
|
+
["@ENVIRONMENT_VALUES@", selected.services.length === 0 ? "" : environmentValuesFunction],
|
|
1391
|
+
["@ENV_INITIALIZE@", selected.services.length === 0 ? "" : "DATABASE_URL=''\nPOSTGRES_HOST=''\nPOSTGRES_USER=''\nPOSTGRES_PASSWORD=''\nPOSTGRES_DB_NAME=''\nPOSTGRES_ADDITIONAL_CONNECTION_DATA=''\nREDIS_URL=''"],
|
|
1392
|
+
["@ENV_VALIDATE@", selected.envFile === void 0 ? "" : "validate_environment"],
|
|
1393
|
+
["@SESSION_ENVIRONMENT@", selected.services.length === 0 ? "" : sessionEnvironmentFunction],
|
|
1394
|
+
["@SESSION_ENVIRONMENT_CALL@", selected.services.length === 0 ? "" : "if [[ \"$MODE\" == session ]]; then emit_session_environment; fi"],
|
|
1302
1395
|
["@ENV_WRITE@", selected.envFile === void 0 ? "" : "write_environment"],
|
|
1303
1396
|
["@PREPARE_FUNCTION@", renderPrepare(selected.prepare, files)],
|
|
1304
1397
|
["@PREPARE_STEP@", selected.prepare === void 0 ? "" : " step prepare prepare_sources"],
|
|
@@ -1314,16 +1407,16 @@ const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExcept
|
|
|
1314
1407
|
valkey: policy.valkey
|
|
1315
1408
|
})]
|
|
1316
1409
|
]);
|
|
1317
|
-
return script.replace(/@[A-Z0-9_]+@/g, (token) => {
|
|
1410
|
+
return `${script.replace(/@[A-Z0-9_]+@/g, (token) => {
|
|
1318
1411
|
const value = replacements.get(token);
|
|
1319
1412
|
if (value === void 0) throw new Error(`Missing cloud setup field: ${token}`);
|
|
1320
1413
|
return value;
|
|
1321
|
-
})
|
|
1414
|
+
}).replace(/[ \t]+$/gm, "").trimEnd()}\n`;
|
|
1322
1415
|
};
|
|
1323
1416
|
//#endregion
|
|
1324
1417
|
//#region src/cloud-setup-claude.ts
|
|
1325
1418
|
const cloudClaudeSettingsPath = ".claude/settings.json";
|
|
1326
|
-
const
|
|
1419
|
+
const releasedSessionStartHook = (script) => ({
|
|
1327
1420
|
matcher: "",
|
|
1328
1421
|
hooks: [{
|
|
1329
1422
|
type: "command",
|
|
@@ -1340,8 +1433,75 @@ const sessionStartHook = (script) => ({
|
|
|
1340
1433
|
fi`
|
|
1341
1434
|
}]
|
|
1342
1435
|
});
|
|
1436
|
+
const sessionStartHook = (script) => ({
|
|
1437
|
+
matcher: "",
|
|
1438
|
+
hooks: [{
|
|
1439
|
+
type: "command",
|
|
1440
|
+
command: `if [ "\${CLAUDE_CODE_REMOTE:-}" = "true" ]; then
|
|
1441
|
+
cloud_setup_incomplete() {
|
|
1442
|
+
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.'
|
|
1443
|
+
printf '%s\\n' "cloud-setup: $1" >&2
|
|
1444
|
+
exit 0
|
|
1445
|
+
}
|
|
1446
|
+
if [ -n "\${CLAUDE_ENV_FILE:-}" ]; then
|
|
1447
|
+
cloud_session_exports="$(${script} session)" || cloud_setup_incomplete 'startup failed; run install'
|
|
1448
|
+
else
|
|
1449
|
+
${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'
|
|
1450
|
+
exit 0
|
|
1451
|
+
fi
|
|
1452
|
+
if [ -n "\${CLAUDE_ENV_FILE:-}" ]; then
|
|
1453
|
+
if [ ! -s ${cloudShellProfilePath} ]; then
|
|
1454
|
+
cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1455
|
+
fi
|
|
1456
|
+
cloud_shell_exports="$(cat ${cloudShellProfilePath})" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'
|
|
1457
|
+
[ -n "$cloud_shell_exports" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1458
|
+
if [ -e "$CLAUDE_ENV_FILE" ] || [ -L "$CLAUDE_ENV_FILE" ]; then
|
|
1459
|
+
[ -f "$CLAUDE_ENV_FILE" ] && [ ! -L "$CLAUDE_ENV_FILE" ] || cloud_setup_incomplete 'session environment must be a regular file; check its path and rerun start'
|
|
1460
|
+
fi
|
|
1461
|
+
cloud_env_temporary="$(umask 077; mktemp "\${CLAUDE_ENV_FILE}.XXXXXX")" || cloud_setup_incomplete 'session environment could not be prepared; check its write access and rerun start'
|
|
1462
|
+
if [ -e "$CLAUDE_ENV_FILE" ] || [ -L "$CLAUDE_ENV_FILE" ]; then
|
|
1463
|
+
cat "$CLAUDE_ENV_FILE" > "$cloud_env_temporary" || { rm -f -- "$cloud_env_temporary"; cloud_setup_incomplete 'session environment could not be read; check its access and rerun start'; }
|
|
1464
|
+
fi
|
|
1465
|
+
if [ -n "$cloud_session_exports" ]; then
|
|
1466
|
+
cloud_session_exports="$cloud_session_exports
|
|
1467
|
+
$cloud_shell_exports"
|
|
1468
|
+
else
|
|
1469
|
+
cloud_session_exports="$cloud_shell_exports"
|
|
1470
|
+
fi
|
|
1471
|
+
printf '\\n%s\\n' "$cloud_session_exports" >> "$cloud_env_temporary" || { rm -f -- "$cloud_env_temporary"; cloud_setup_incomplete 'session environment could not be prepared; check its write access and rerun start'; }
|
|
1472
|
+
mv -f -- "$cloud_env_temporary" "$CLAUDE_ENV_FILE" || { rm -f -- "$cloud_env_temporary"; cloud_setup_incomplete 'session environment could not be persisted; check its write access and rerun start'; }
|
|
1473
|
+
fi
|
|
1474
|
+
fi`
|
|
1475
|
+
}]
|
|
1476
|
+
});
|
|
1477
|
+
const currentMainSessionStartHook = (script) => ({
|
|
1478
|
+
matcher: "",
|
|
1479
|
+
hooks: [{
|
|
1480
|
+
type: "command",
|
|
1481
|
+
command: `if [ "\${CLAUDE_CODE_REMOTE:-}" = "true" ]; then
|
|
1482
|
+
cloud_setup_incomplete() {
|
|
1483
|
+
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.'
|
|
1484
|
+
printf '%s\\n' "cloud-setup: $1" >&2
|
|
1485
|
+
exit 0
|
|
1486
|
+
}
|
|
1487
|
+
${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'
|
|
1488
|
+
if [ -n "\${CLAUDE_ENV_FILE:-}" ]; then
|
|
1489
|
+
if [ ! -s ${cloudShellProfilePath} ]; then
|
|
1490
|
+
cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1491
|
+
fi
|
|
1492
|
+
cloud_shell_exports="$(cat ${cloudShellProfilePath})" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'
|
|
1493
|
+
[ -n "$cloud_shell_exports" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1494
|
+
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'
|
|
1495
|
+
fi
|
|
1496
|
+
fi`
|
|
1497
|
+
}]
|
|
1498
|
+
});
|
|
1343
1499
|
const cloudSessionStartHook = sessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`);
|
|
1344
|
-
const previousCloudSessionStartHooks = [
|
|
1500
|
+
const previousCloudSessionStartHooks = [
|
|
1501
|
+
releasedSessionStartHook(`bash ${cloudSetupPath}`),
|
|
1502
|
+
releasedSessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`),
|
|
1503
|
+
currentMainSessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`)
|
|
1504
|
+
];
|
|
1345
1505
|
const cloudAttribution = {
|
|
1346
1506
|
commit: "",
|
|
1347
1507
|
pr: ""
|
|
@@ -1575,6 +1735,18 @@ const javascriptDependencyLockfiles = [
|
|
|
1575
1735
|
"yarn.lock",
|
|
1576
1736
|
"pnpm-lock.yaml"
|
|
1577
1737
|
];
|
|
1738
|
+
const dependabotManifestEcosystems = {
|
|
1739
|
+
Gemfile: "bundler",
|
|
1740
|
+
"Gemfile.lock": "bundler",
|
|
1741
|
+
"composer.json": "composer",
|
|
1742
|
+
"composer.lock": "composer"
|
|
1743
|
+
};
|
|
1744
|
+
/** Share ecosystem inventory with snapshot selection; no dependency graph reads are needed. */
|
|
1745
|
+
const dependabotManifestEcosystem = (file) => {
|
|
1746
|
+
if (excludedInputPath(file)) return void 0;
|
|
1747
|
+
const basename = file.split("/").at(-1);
|
|
1748
|
+
for (const [name, ecosystem] of Object.entries(dependabotManifestEcosystems)) if (basename === name) return ecosystem;
|
|
1749
|
+
};
|
|
1578
1750
|
/** Match project, environment, local, and fragment filenames recognized by mise. */
|
|
1579
1751
|
const isMiseConfigPath = (file) => !excludedInputPath(file) && (/(?:^|\/)\.?mise(?:\.[^./][^/]*)?\.toml$/.test(file) || /(?:^|\/)(?:\.?mise|\.config\/mise)\/config(?:\.[^./][^/]*)?\.toml$/.test(file) || /(?:^|\/)(?:\.?mise|\.config\/mise)\/conf\.d\/[^./][^/]*\.toml$/.test(file));
|
|
1580
1752
|
/** GitHub action metadata may live at the repository root or in any directory. */
|
|
@@ -1610,13 +1782,13 @@ const isDockerDefinitionPath = (file) => {
|
|
|
1610
1782
|
const isShellScript = (file, text = "") => !excludedInputPath(file) && (/\.(?:sh|bash|zsh)$/.test(file) || /^#![ \t]*(?:\/(?:[^ \t\r\n]+\/)*(?:bash|dash|ksh|zsh|sh)|\/usr\/bin\/env[ \t]+(?:-S[ \t]+)?(?:bash|dash|ksh|zsh|sh))(?=[ \t\r\n]|$)/.test(text));
|
|
1611
1783
|
/** Lockfiles establish ecosystem presence without reading their dependency graphs. */
|
|
1612
1784
|
const toolchainInputKind = (file, text = "") => {
|
|
1613
|
-
if (file === ".agents/cloud-setup.sh" || file === ".claude/settings.json" || file === "Cargo.lock") return "config";
|
|
1785
|
+
if (file === "bunfig.toml" || file === ".agents/cloud-setup.sh" || file === ".claude/settings.json" || file === "Cargo.lock") return "config";
|
|
1614
1786
|
if (githubAutomationFileKind(file) !== void 0) return "config";
|
|
1615
1787
|
if (excludedInputPath(file)) return void 0;
|
|
1616
|
-
if (pythonDependencyManifestKind(file) === "pipfile-lock" || javascriptDependencyLockfiles.some((name) => file.split("/").at(-1) === name) || /(?:^|\/)uv\.lock$/.test(file)) return "presence";
|
|
1788
|
+
if (dependabotManifestEcosystem(file) !== void 0 || pythonDependencyManifestKind(file) === "pipfile-lock" || javascriptDependencyLockfiles.some((name) => file.split("/").at(-1) === name) || /(?:^|\/)uv\.lock$/.test(file)) return "presence";
|
|
1617
1789
|
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";
|
|
1618
1790
|
};
|
|
1619
1791
|
//#endregion
|
|
1620
|
-
export {
|
|
1792
|
+
export { nodePolicyValid as C, parseCloudSetup as E, generateCloudSetup as S, nodeSupportRangeMatches as T, cloudSessionStartFix as _, isMiseConfigPath as a, mergeCloudClaudeSettings as b, javascriptDependencyLockfiles as c, containerDocumentImages as d, isComposeDefinitionPath as f, cloudClaudeSettingsPath as g, cloudAttributionFix as h, isDockerDefinitionPath as i, pythonDependencyManifestKind as l, workspaceContains as m, githubAutomationFileKind as n, isPythonDependencyManifest as o, isKubernetesDefinitionPath as p, isDependabotGithubActionsPath as r, isShellScript as s, dependabotManifestEcosystem as t, toolchainInputKind as u, hasCloudAttribution as v, nodeSelectorMatches as w, cloudSetupPath as x, hasCloudSessionStartHook as y };
|
|
1621
1793
|
|
|
1622
1794
|
//# sourceMappingURL=toolchain-inputs.mjs.map
|