@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,9 +1,9 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime.cjs");
|
|
2
2
|
let node_path = require("node:path");
|
|
3
3
|
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
4
|
+
let smol_toml = require("smol-toml");
|
|
4
5
|
let node_crypto = require("node:crypto");
|
|
5
6
|
let semver = require("semver");
|
|
6
|
-
let smol_toml = require("smol-toml");
|
|
7
7
|
let node_util = require("node:util");
|
|
8
8
|
let yaml = require("yaml");
|
|
9
9
|
let picomatch = require("picomatch");
|
|
@@ -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
|
-
|
|
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")
|
|
@@ -675,7 +700,12 @@ const postgresStart = String.raw`
|
|
|
675
700
|
pg_pid="$(head -n 1 "$pg_data/postmaster.pid")"
|
|
676
701
|
service_process "$pg_pid" "$pg_bin/postgres"
|
|
677
702
|
[[ "$(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"
|
|
678
|
-
|
|
703
|
+
POSTGRES_HOST='127.0.0.1:55432'
|
|
704
|
+
POSTGRES_USER='stll_cloud'
|
|
705
|
+
POSTGRES_PASSWORD="$pg_password"
|
|
706
|
+
POSTGRES_DB_NAME='cloud_test'
|
|
707
|
+
POSTGRES_ADDITIONAL_CONNECTION_DATA=''
|
|
708
|
+
DATABASE_URL="postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/$POSTGRES_DB_NAME$POSTGRES_ADDITIONAL_CONNECTION_DATA"
|
|
679
709
|
printf 'postgres: %s\n' "$pg_state"
|
|
680
710
|
`;
|
|
681
711
|
const valkeyStart = String.raw`
|
|
@@ -838,6 +868,11 @@ const resolveCloudToolchains = ({ cloud, files, rust, rustExceptions }) => {
|
|
|
838
868
|
if (channel !== rust && !rustExceptions.some(({ pin }) => pin === channel)) throw new Error(`cloud Rust must use shared Rust ${rust} or a recorded rustExceptions pin`);
|
|
839
869
|
if (cloud.rust?.toolchain !== void 0 && cloud.rust.toolchain !== channel) throw new Error("cloud.rust.toolchain conflicts with root Rust toolchain");
|
|
840
870
|
}
|
|
871
|
+
const additionalToolchains = cloud.rust?.additionalToolchains ?? [];
|
|
872
|
+
for (const pin of additionalToolchains) {
|
|
873
|
+
if (pin === channel) throw new Error("cloud.rust.additionalToolchains must not repeat the primary toolchain");
|
|
874
|
+
if (pin !== rust && !rustExceptions.some(({ pin: authorized }) => authorized === pin)) throw new Error(`cloud.rust.additionalToolchains ${pin} requires an authorized rustExceptions pin`);
|
|
875
|
+
}
|
|
841
876
|
const components = [.../* @__PURE__ */ new Set([...parseCloudRustNames(declared?.["components"], "components"), ...cloud.rust?.components ?? []])].sort();
|
|
842
877
|
const targets = [.../* @__PURE__ */ new Set([...parseCloudRustNames(declared?.["targets"], "targets"), ...cloud.rust?.targets ?? []])].sort();
|
|
843
878
|
const resolveTool = (tool, version) => {
|
|
@@ -868,6 +903,7 @@ const resolveCloudToolchains = ({ cloud, files, rust, rustExceptions }) => {
|
|
|
868
903
|
return {
|
|
869
904
|
rust: rustEnabled && typeof channel === "string" ? {
|
|
870
905
|
channel,
|
|
906
|
+
additionalToolchains: [...additionalToolchains].sort(),
|
|
871
907
|
components,
|
|
872
908
|
targets,
|
|
873
909
|
installer: cloudSetupArtifacts["rustup-init"]
|
|
@@ -904,7 +940,7 @@ rust_run() {
|
|
|
904
940
|
*) fail 'Invalid Rust execution mode' ;;
|
|
905
941
|
esac
|
|
906
942
|
}
|
|
907
|
-
|
|
943
|
+
primary_rust_ready() {
|
|
908
944
|
local directory
|
|
909
945
|
for directory in "$RUSTUP_HOME" "$CARGO_HOME"; do
|
|
910
946
|
[[ -d "$directory" && ! -L "$directory" && "$(stat -c '%u' "$directory")" == "$OUTPUT_UID" ]] || return 1
|
|
@@ -918,13 +954,19 @@ rust_ready() {
|
|
|
918
954
|
@VERIFY_TARGETS@
|
|
919
955
|
return 0
|
|
920
956
|
}
|
|
957
|
+
rust_ready() {
|
|
958
|
+
local additional_version
|
|
959
|
+
primary_rust_ready || return 1
|
|
960
|
+
@VERIFY_ADDITIONAL_TOOLCHAINS@
|
|
961
|
+
return 0
|
|
962
|
+
}
|
|
921
963
|
verify_rust() { rust_ready || fail 'Pinned Rust, components or targets are unavailable; run install'; }
|
|
922
964
|
install_rust() (
|
|
923
965
|
if ! command -v cc >/dev/null || ! command -v ld >/dev/null || [[ ! -f /usr/include/stdlib.h ]]; then
|
|
924
966
|
apt_refresh_for build-essential
|
|
925
967
|
apt_install build-essential
|
|
926
968
|
fi
|
|
927
|
-
local artifact_url artifact_sha
|
|
969
|
+
local artifact_url artifact_sha additional_version
|
|
928
970
|
# Subshell scope retains scratch for EXIT cleanup after a failed command.
|
|
929
971
|
scratch="$(mktemp -d)"
|
|
930
972
|
trap 'rm -rf -- "$scratch"' EXIT
|
|
@@ -943,9 +985,10 @@ install_rust() (
|
|
|
943
985
|
rust_run network "$scratch/rustup-init" -y --no-modify-path --default-toolchain none --profile minimal
|
|
944
986
|
fi
|
|
945
987
|
rust_run local "$CARGO_HOME/bin/rustup" set auto-self-update disable
|
|
946
|
-
if !
|
|
988
|
+
if ! primary_rust_ready; then
|
|
947
989
|
rust_run network "$CARGO_HOME/bin/rustup" toolchain install @RUST@ --profile minimal --no-self-update @RUST_ARGS@
|
|
948
990
|
fi
|
|
991
|
+
@INSTALL_ADDITIONAL_TOOLCHAINS@
|
|
949
992
|
rust_run local "$CARGO_HOME/bin/rustup" default @RUST@
|
|
950
993
|
verify_rust
|
|
951
994
|
for tool in rustup cargo rustc rustdoc @RUST_PROXIES@; do
|
|
@@ -956,7 +999,7 @@ install_rust() (
|
|
|
956
999
|
fi
|
|
957
1000
|
done
|
|
958
1001
|
)
|
|
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 "));
|
|
1002
|
+
`.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
1003
|
};
|
|
961
1004
|
const packageToolInstall = ({ tool, release }) => {
|
|
962
1005
|
const name = tool.replaceAll("-", "_");
|
|
@@ -979,7 +1022,7 @@ install_${name}() {
|
|
|
979
1022
|
const artifactToolInstall = ({ tool, release }) => {
|
|
980
1023
|
const directory = `/opt/stll-cloud/tools/${tool}/${release.version}`;
|
|
981
1024
|
const command = tool === "wasm-bindgen-cli" ? "wasm-bindgen" : tool;
|
|
982
|
-
const marker = `${tool === "
|
|
1025
|
+
const marker = `${tool === "gitleaks" ? "gitleaks version" : command} ${release.version}`;
|
|
983
1026
|
return {
|
|
984
1027
|
name: tool.replaceAll("-", "_"),
|
|
985
1028
|
text: `verify_${tool.replaceAll("-", "_")}() {
|
|
@@ -1058,9 +1101,9 @@ const script = String.raw`#!/usr/bin/env bash
|
|
|
1058
1101
|
# Supported platform: Ubuntu 24.04 (noble), amd64/arm64, root or passwordless sudo.
|
|
1059
1102
|
set -euo pipefail
|
|
1060
1103
|
|
|
1061
|
-
usage() { echo 'Usage: cloud-setup.sh install|start' >&2; exit 2; }
|
|
1104
|
+
usage() { echo 'Usage: cloud-setup.sh install|start|session' >&2; exit 2; }
|
|
1062
1105
|
[[ "$#" == 1 ]] || usage
|
|
1063
|
-
case "$1" in install|start) MODE="$1" ;; *) usage ;; esac
|
|
1106
|
+
case "$1" in install|start|session) MODE="$1" ;; *) usage ;; esac
|
|
1064
1107
|
fail() { echo "cloud-setup: $*" >&2; exit 1; }
|
|
1065
1108
|
trap 'echo "cloud-setup: command failed at line $LINENO" >&2' ERR
|
|
1066
1109
|
# Each phase logs its start and duration so a stalled phase is visible in the task log.
|
|
@@ -1116,19 +1159,35 @@ esac
|
|
|
1116
1159
|
|
|
1117
1160
|
@NETWORK@
|
|
1118
1161
|
|
|
1162
|
+
node_ready() {
|
|
1163
|
+
local node_version npm_version npx_version
|
|
1164
|
+
[[ -x "$NODE_DIR/bin/node" && -x "$NODE_DIR/bin/npm" && -x "$NODE_DIR/bin/npx" ]] || return 1
|
|
1165
|
+
node_version="$("$NODE_DIR/bin/node" --version)" || return 1
|
|
1166
|
+
[[ "$node_version" == "v$NODE_VERSION" ]] || return 1
|
|
1167
|
+
npm_version="$("$NODE_DIR/bin/npm" --version)" || return 1
|
|
1168
|
+
[[ "$npm_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || return 1
|
|
1169
|
+
npx_version="$("$NODE_DIR/bin/npx" --version)" || return 1
|
|
1170
|
+
[[ "$npx_version" == "$npm_version" ]] || return 1
|
|
1171
|
+
}
|
|
1119
1172
|
runtime_ready() {
|
|
1120
|
-
|
|
1173
|
+
node_ready || fail 'Pinned Node, npm or npx is unavailable; run install'
|
|
1121
1174
|
[[ -x "$BUN_DIR/bun" && "$($BUN_DIR/bun --version)" == "$BUN_VERSION" ]] || fail 'Pinned Bun is unavailable; run install'
|
|
1122
1175
|
}
|
|
1123
|
-
install_runtimes()
|
|
1176
|
+
install_runtimes() (
|
|
1177
|
+
if [[ ! -s /etc/ssl/certs/ca-certificates.crt ]]; then
|
|
1178
|
+
command -v update-ca-certificates >/dev/null || fail 'System CA certificate bundle is missing; restore ca-certificates in the base image offline before install'
|
|
1179
|
+
update-ca-certificates || fail 'System CA certificate bundle could not be repaired offline; restore ca-certificates in the base image before install'
|
|
1180
|
+
fi
|
|
1181
|
+
[[ -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'
|
|
1124
1182
|
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
|
|
1125
1183
|
apt_refresh_for ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1
|
|
1126
1184
|
DEBIAN_FRONTEND=noninteractive apt_install ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1
|
|
1127
1185
|
fi
|
|
1128
|
-
local
|
|
1186
|
+
local node_archive bun_archive bun_folder
|
|
1187
|
+
# Subshell scope retains scratch for EXIT cleanup after a failed command.
|
|
1129
1188
|
scratch="$(mktemp -d)"
|
|
1130
|
-
trap 'rm -rf -- "$scratch"'
|
|
1131
|
-
if
|
|
1189
|
+
trap 'rm -rf -- "$scratch"' EXIT
|
|
1190
|
+
if ! node_ready; then
|
|
1132
1191
|
node_archive="node-v$NODE_VERSION-linux-$NODE_ARCH.tar.xz"
|
|
1133
1192
|
download_file "https://nodejs.org/dist/v$NODE_VERSION/$node_archive" "$scratch/$node_archive" 120
|
|
1134
1193
|
download_file "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt" "$scratch/node-sums" 45
|
|
@@ -1151,9 +1210,7 @@ install_runtimes() {
|
|
|
1151
1210
|
ln -sfnT -- "$NODE_DIR/bin/npm" /usr/local/bin/npm
|
|
1152
1211
|
ln -sfnT -- "$NODE_DIR/bin/npx" /usr/local/bin/npx
|
|
1153
1212
|
ln -sfnT -- "$BUN_DIR/bun" /usr/local/bin/bun
|
|
1154
|
-
|
|
1155
|
-
trap - RETURN
|
|
1156
|
-
}
|
|
1213
|
+
)
|
|
1157
1214
|
|
|
1158
1215
|
dependency_install() {
|
|
1159
1216
|
local directory download_hosts
|
|
@@ -1199,6 +1256,8 @@ process.stdout.write([...hosts].sort().join(","));
|
|
|
1199
1256
|
@INPUT_VALIDATION@
|
|
1200
1257
|
|
|
1201
1258
|
@ENV_FUNCTIONS@
|
|
1259
|
+
@ENVIRONMENT_VALUES@
|
|
1260
|
+
@SESSION_ENVIRONMENT@
|
|
1202
1261
|
|
|
1203
1262
|
@PREPARE_FUNCTION@
|
|
1204
1263
|
|
|
@@ -1211,14 +1270,38 @@ if [[ "$MODE" == install ]]; then
|
|
|
1211
1270
|
@PREPARE_STEP@
|
|
1212
1271
|
exit 0
|
|
1213
1272
|
fi
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
step
|
|
1217
|
-
step
|
|
1218
|
-
|
|
1219
|
-
step
|
|
1220
|
-
|
|
1221
|
-
|
|
1273
|
+
@ENV_INITIALIZE@
|
|
1274
|
+
start_environment() {
|
|
1275
|
+
step runtime-check runtime_ready
|
|
1276
|
+
step tool-check verify_tools
|
|
1277
|
+
step shell install_shell_environment
|
|
1278
|
+
step shell-check verify_shell_environment
|
|
1279
|
+
@ENV_VALIDATE@
|
|
1280
|
+
step state prepare_state
|
|
1281
|
+
step service-start start_services
|
|
1282
|
+
@ENV_WRITE@
|
|
1283
|
+
}
|
|
1284
|
+
if [[ "$MODE" == session ]]; then
|
|
1285
|
+
start_environment >&2
|
|
1286
|
+
else
|
|
1287
|
+
start_environment
|
|
1288
|
+
fi
|
|
1289
|
+
@SESSION_ENVIRONMENT_CALL@
|
|
1290
|
+
`;
|
|
1291
|
+
const environmentValuesFunction = String.raw`
|
|
1292
|
+
environment_values() {
|
|
1293
|
+
local emit="$1"
|
|
1294
|
+
"$emit" NODE_ENV test
|
|
1295
|
+
if [[ -n "$DATABASE_URL" ]]; then
|
|
1296
|
+
"$emit" DATABASE_URL "$DATABASE_URL"
|
|
1297
|
+
"$emit" POSTGRES_HOST "$POSTGRES_HOST"
|
|
1298
|
+
"$emit" POSTGRES_USER "$POSTGRES_USER"
|
|
1299
|
+
"$emit" POSTGRES_PASSWORD "$POSTGRES_PASSWORD"
|
|
1300
|
+
"$emit" POSTGRES_DB_NAME "$POSTGRES_DB_NAME"
|
|
1301
|
+
"$emit" POSTGRES_ADDITIONAL_CONNECTION_DATA "$POSTGRES_ADDITIONAL_CONNECTION_DATA"
|
|
1302
|
+
fi
|
|
1303
|
+
if [[ -n "$REDIS_URL" ]]; then "$emit" REDIS_URL "$REDIS_URL"; fi
|
|
1304
|
+
}
|
|
1222
1305
|
`;
|
|
1223
1306
|
const environmentFunctions = String.raw`
|
|
1224
1307
|
validate_environment() {
|
|
@@ -1234,20 +1317,26 @@ validate_environment() {
|
|
|
1234
1317
|
[[ "$first_line" == "$ENV_MARKER" ]] || fail 'Refusing to overwrite an unowned environment file'
|
|
1235
1318
|
fi
|
|
1236
1319
|
}
|
|
1320
|
+
environment_file_value() { printf '%s=%s\n' "$1" "$2"; }
|
|
1237
1321
|
write_environment() {
|
|
1238
1322
|
validate_environment
|
|
1239
1323
|
local env_path="$REPO_ROOT/$ENV_FILE" temporary
|
|
1240
1324
|
temporary="$(mktemp "$(dirname -- "$env_path")/.stll-cloud-env.XXXXXX")"
|
|
1241
1325
|
chmod 600 "$temporary"
|
|
1242
1326
|
{
|
|
1243
|
-
printf '%s\n' "$ENV_MARKER"
|
|
1244
|
-
|
|
1245
|
-
if [[ -n "$REDIS_URL" ]]; then printf 'REDIS_URL=%s\n' "$REDIS_URL"; fi
|
|
1327
|
+
printf '%s\n' "$ENV_MARKER"
|
|
1328
|
+
environment_values environment_file_value
|
|
1246
1329
|
} > "$temporary"
|
|
1247
1330
|
chown "$OUTPUT_UID:$OUTPUT_GID" "$temporary"
|
|
1248
1331
|
mv -f -- "$temporary" "$env_path"
|
|
1249
1332
|
}
|
|
1250
1333
|
`;
|
|
1334
|
+
const sessionEnvironmentFunction = String.raw`
|
|
1335
|
+
environment_shell_value() { printf 'export %s=%q\n' "$1" "$2"; }
|
|
1336
|
+
emit_session_environment() {
|
|
1337
|
+
environment_values environment_shell_value
|
|
1338
|
+
}
|
|
1339
|
+
`;
|
|
1251
1340
|
const shellQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
1252
1341
|
const renderPrepare = (prepare, files) => {
|
|
1253
1342
|
if (prepare === void 0) return "";
|
|
@@ -1301,7 +1390,11 @@ const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExcept
|
|
|
1301
1390
|
["@NODE@", exactNode],
|
|
1302
1391
|
["@ENV_ASSIGNMENTS@", selected.envFile === void 0 ? "" : `ENV_FILE=${shellQuote(selected.envFile)}\nENV_MARKER=${shellQuote(cloudEnvironmentMarker)}`],
|
|
1303
1392
|
["@ENV_FUNCTIONS@", selected.envFile === void 0 ? "" : environmentFunctions],
|
|
1304
|
-
["@
|
|
1393
|
+
["@ENVIRONMENT_VALUES@", selected.services.length === 0 ? "" : environmentValuesFunction],
|
|
1394
|
+
["@ENV_INITIALIZE@", selected.services.length === 0 ? "" : "DATABASE_URL=''\nPOSTGRES_HOST=''\nPOSTGRES_USER=''\nPOSTGRES_PASSWORD=''\nPOSTGRES_DB_NAME=''\nPOSTGRES_ADDITIONAL_CONNECTION_DATA=''\nREDIS_URL=''"],
|
|
1395
|
+
["@ENV_VALIDATE@", selected.envFile === void 0 ? "" : "validate_environment"],
|
|
1396
|
+
["@SESSION_ENVIRONMENT@", selected.services.length === 0 ? "" : sessionEnvironmentFunction],
|
|
1397
|
+
["@SESSION_ENVIRONMENT_CALL@", selected.services.length === 0 ? "" : "if [[ \"$MODE\" == session ]]; then emit_session_environment; fi"],
|
|
1305
1398
|
["@ENV_WRITE@", selected.envFile === void 0 ? "" : "write_environment"],
|
|
1306
1399
|
["@PREPARE_FUNCTION@", renderPrepare(selected.prepare, files)],
|
|
1307
1400
|
["@PREPARE_STEP@", selected.prepare === void 0 ? "" : " step prepare prepare_sources"],
|
|
@@ -1317,16 +1410,16 @@ const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExcept
|
|
|
1317
1410
|
valkey: policy.valkey
|
|
1318
1411
|
})]
|
|
1319
1412
|
]);
|
|
1320
|
-
return script.replace(/@[A-Z0-9_]+@/g, (token) => {
|
|
1413
|
+
return `${script.replace(/@[A-Z0-9_]+@/g, (token) => {
|
|
1321
1414
|
const value = replacements.get(token);
|
|
1322
1415
|
if (value === void 0) throw new Error(`Missing cloud setup field: ${token}`);
|
|
1323
1416
|
return value;
|
|
1324
|
-
})
|
|
1417
|
+
}).replace(/[ \t]+$/gm, "").trimEnd()}\n`;
|
|
1325
1418
|
};
|
|
1326
1419
|
//#endregion
|
|
1327
1420
|
//#region src/cloud-setup-claude.ts
|
|
1328
1421
|
const cloudClaudeSettingsPath = ".claude/settings.json";
|
|
1329
|
-
const
|
|
1422
|
+
const releasedSessionStartHook = (script) => ({
|
|
1330
1423
|
matcher: "",
|
|
1331
1424
|
hooks: [{
|
|
1332
1425
|
type: "command",
|
|
@@ -1343,8 +1436,75 @@ const sessionStartHook = (script) => ({
|
|
|
1343
1436
|
fi`
|
|
1344
1437
|
}]
|
|
1345
1438
|
});
|
|
1439
|
+
const sessionStartHook = (script) => ({
|
|
1440
|
+
matcher: "",
|
|
1441
|
+
hooks: [{
|
|
1442
|
+
type: "command",
|
|
1443
|
+
command: `if [ "\${CLAUDE_CODE_REMOTE:-}" = "true" ]; then
|
|
1444
|
+
cloud_setup_incomplete() {
|
|
1445
|
+
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.'
|
|
1446
|
+
printf '%s\\n' "cloud-setup: $1" >&2
|
|
1447
|
+
exit 0
|
|
1448
|
+
}
|
|
1449
|
+
if [ -n "\${CLAUDE_ENV_FILE:-}" ]; then
|
|
1450
|
+
cloud_session_exports="$(${script} session)" || cloud_setup_incomplete 'startup failed; run install'
|
|
1451
|
+
else
|
|
1452
|
+
${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'
|
|
1453
|
+
exit 0
|
|
1454
|
+
fi
|
|
1455
|
+
if [ -n "\${CLAUDE_ENV_FILE:-}" ]; then
|
|
1456
|
+
if [ ! -s ${cloudShellProfilePath} ]; then
|
|
1457
|
+
cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1458
|
+
fi
|
|
1459
|
+
cloud_shell_exports="$(cat ${cloudShellProfilePath})" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'
|
|
1460
|
+
[ -n "$cloud_shell_exports" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1461
|
+
if [ -e "$CLAUDE_ENV_FILE" ] || [ -L "$CLAUDE_ENV_FILE" ]; then
|
|
1462
|
+
[ -f "$CLAUDE_ENV_FILE" ] && [ ! -L "$CLAUDE_ENV_FILE" ] || cloud_setup_incomplete 'session environment must be a regular file; check its path and rerun start'
|
|
1463
|
+
fi
|
|
1464
|
+
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'
|
|
1465
|
+
if [ -e "$CLAUDE_ENV_FILE" ] || [ -L "$CLAUDE_ENV_FILE" ]; then
|
|
1466
|
+
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'; }
|
|
1467
|
+
fi
|
|
1468
|
+
if [ -n "$cloud_session_exports" ]; then
|
|
1469
|
+
cloud_session_exports="$cloud_session_exports
|
|
1470
|
+
$cloud_shell_exports"
|
|
1471
|
+
else
|
|
1472
|
+
cloud_session_exports="$cloud_shell_exports"
|
|
1473
|
+
fi
|
|
1474
|
+
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'; }
|
|
1475
|
+
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'; }
|
|
1476
|
+
fi
|
|
1477
|
+
fi`
|
|
1478
|
+
}]
|
|
1479
|
+
});
|
|
1480
|
+
const currentMainSessionStartHook = (script) => ({
|
|
1481
|
+
matcher: "",
|
|
1482
|
+
hooks: [{
|
|
1483
|
+
type: "command",
|
|
1484
|
+
command: `if [ "\${CLAUDE_CODE_REMOTE:-}" = "true" ]; then
|
|
1485
|
+
cloud_setup_incomplete() {
|
|
1486
|
+
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.'
|
|
1487
|
+
printf '%s\\n' "cloud-setup: $1" >&2
|
|
1488
|
+
exit 0
|
|
1489
|
+
}
|
|
1490
|
+
${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'
|
|
1491
|
+
if [ -n "\${CLAUDE_ENV_FILE:-}" ]; then
|
|
1492
|
+
if [ ! -s ${cloudShellProfilePath} ]; then
|
|
1493
|
+
cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1494
|
+
fi
|
|
1495
|
+
cloud_shell_exports="$(cat ${cloudShellProfilePath})" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'
|
|
1496
|
+
[ -n "$cloud_shell_exports" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1497
|
+
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'
|
|
1498
|
+
fi
|
|
1499
|
+
fi`
|
|
1500
|
+
}]
|
|
1501
|
+
});
|
|
1346
1502
|
const cloudSessionStartHook = sessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`);
|
|
1347
|
-
const previousCloudSessionStartHooks = [
|
|
1503
|
+
const previousCloudSessionStartHooks = [
|
|
1504
|
+
releasedSessionStartHook(`bash ${cloudSetupPath}`),
|
|
1505
|
+
releasedSessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`),
|
|
1506
|
+
currentMainSessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`)
|
|
1507
|
+
];
|
|
1348
1508
|
const cloudAttribution = {
|
|
1349
1509
|
commit: "",
|
|
1350
1510
|
pr: ""
|
|
@@ -1578,6 +1738,18 @@ const javascriptDependencyLockfiles = [
|
|
|
1578
1738
|
"yarn.lock",
|
|
1579
1739
|
"pnpm-lock.yaml"
|
|
1580
1740
|
];
|
|
1741
|
+
const dependabotManifestEcosystems = {
|
|
1742
|
+
Gemfile: "bundler",
|
|
1743
|
+
"Gemfile.lock": "bundler",
|
|
1744
|
+
"composer.json": "composer",
|
|
1745
|
+
"composer.lock": "composer"
|
|
1746
|
+
};
|
|
1747
|
+
/** Share ecosystem inventory with snapshot selection; no dependency graph reads are needed. */
|
|
1748
|
+
const dependabotManifestEcosystem = (file) => {
|
|
1749
|
+
if (excludedInputPath(file)) return void 0;
|
|
1750
|
+
const basename = file.split("/").at(-1);
|
|
1751
|
+
for (const [name, ecosystem] of Object.entries(dependabotManifestEcosystems)) if (basename === name) return ecosystem;
|
|
1752
|
+
};
|
|
1581
1753
|
/** Match project, environment, local, and fragment filenames recognized by mise. */
|
|
1582
1754
|
const isMiseConfigPath = (file) => !excludedInputPath(file) && (/(?:^|\/)\.?mise(?:\.[^./][^/]*)?\.toml$/.test(file) || /(?:^|\/)(?:\.?mise|\.config\/mise)\/config(?:\.[^./][^/]*)?\.toml$/.test(file) || /(?:^|\/)(?:\.?mise|\.config\/mise)\/conf\.d\/[^./][^/]*\.toml$/.test(file));
|
|
1583
1755
|
/** GitHub action metadata may live at the repository root or in any directory. */
|
|
@@ -1613,10 +1785,10 @@ const isDockerDefinitionPath = (file) => {
|
|
|
1613
1785
|
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));
|
|
1614
1786
|
/** Lockfiles establish ecosystem presence without reading their dependency graphs. */
|
|
1615
1787
|
const toolchainInputKind = (file, text = "") => {
|
|
1616
|
-
if (file === ".agents/cloud-setup.sh" || file === ".claude/settings.json" || file === "Cargo.lock") return "config";
|
|
1788
|
+
if (file === "bunfig.toml" || file === ".agents/cloud-setup.sh" || file === ".claude/settings.json" || file === "Cargo.lock") return "config";
|
|
1617
1789
|
if (githubAutomationFileKind(file) !== void 0) return "config";
|
|
1618
1790
|
if (excludedInputPath(file)) return void 0;
|
|
1619
|
-
if (pythonDependencyManifestKind(file) === "pipfile-lock" || javascriptDependencyLockfiles.some((name) => file.split("/").at(-1) === name) || /(?:^|\/)uv\.lock$/.test(file)) return "presence";
|
|
1791
|
+
if (dependabotManifestEcosystem(file) !== void 0 || pythonDependencyManifestKind(file) === "pipfile-lock" || javascriptDependencyLockfiles.some((name) => file.split("/").at(-1) === name) || /(?:^|\/)uv\.lock$/.test(file)) return "presence";
|
|
1620
1792
|
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";
|
|
1621
1793
|
};
|
|
1622
1794
|
//#endregion
|
|
@@ -1650,6 +1822,12 @@ Object.defineProperty(exports, "containerDocumentImages", {
|
|
|
1650
1822
|
return containerDocumentImages;
|
|
1651
1823
|
}
|
|
1652
1824
|
});
|
|
1825
|
+
Object.defineProperty(exports, "dependabotManifestEcosystem", {
|
|
1826
|
+
enumerable: true,
|
|
1827
|
+
get: function() {
|
|
1828
|
+
return dependabotManifestEcosystem;
|
|
1829
|
+
}
|
|
1830
|
+
});
|
|
1653
1831
|
Object.defineProperty(exports, "generateCloudSetup", {
|
|
1654
1832
|
enumerable: true,
|
|
1655
1833
|
get: function() {
|