@stll/oxlint-config 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"toolchain-inputs.mjs","names":["exhaustive","exhaustive","quote","record","parseToml","exhaustive","record","exhaustive"],"sources":["../src/cloud-setup-install.ts","../src/cloud-setup-network.ts","../src/cloud-setup-artifacts.ts","../src/cloud-setup-schema.ts","../src/cloud-setup-services.ts","../src/cloud-setup-shell.ts","../src/cloud-setup-toolchains.ts","../src/cloud-setup-tools-install.ts","../src/toolchain-node.ts","../src/cloud-setup.ts","../src/cloud-setup-claude.ts","../src/toolchain-workspaces.ts","../src/toolchain-container-inputs.ts","../src/toolchain-inputs.ts"],"sourcesContent":["import type { CloudService } from \"./cloud-setup-schema\";\nimport type { parseToolchainPolicy } from \"./toolchain-schema\";\n\ntype CloudServiceInstallOptions = {\n services: readonly CloudService[];\n postgres: string;\n valkey: string;\n valkeyArtifacts: ReturnType<typeof parseToolchainPolicy>[\"valkeyArtifacts\"];\n};\n\nconst packageInstall = String.raw`\n# Prevent package maintainer scripts from starting unmanaged system services.\napt_install() (\n # EXIT runs after function locals expire; this subshell owns the trap state.\n backup=''\n policy_state=untouched\n [[ ! -L /var/lock/stll-cloud-apt.lock ]] || fail 'Invalid package install lock'\n exec 8>/var/lock/stll-cloud-apt.lock\n flock -x -w 120 8 || fail 'Another package installation is active'\n [[ ! -L /usr/sbin/policy-rc.d ]] || fail 'Unsupported service-start policy symlink'\n [[ ! -e /usr/sbin/policy-rc.d || -f /usr/sbin/policy-rc.d ]] || fail 'Unsupported service-start policy file'\n backup=\"$(mktemp -d)\"\n cleanup_package_policy() {\n local status=$?\n trap - EXIT HUP INT TERM\n if [[ \"$policy_state\" == installed ]]; then\n if [[ -f \"$backup/original\" ]]; then\n if ! cp -p \"$backup/original\" /usr/sbin/policy-rc.d; then status=1; fi\n else\n if ! rm -f /usr/sbin/policy-rc.d; then status=1; fi\n fi\n fi\n rm -rf -- \"$backup\"\n exit \"$status\"\n }\n trap cleanup_package_policy EXIT\n trap 'exit 129' HUP\n trap 'exit 130' INT\n trap 'exit 143' TERM\n if [[ -e /usr/sbin/policy-rc.d ]]; then cp -p /usr/sbin/policy-rc.d \"$backup/original\"; fi\n policy_state=installed\n printf '%s\\n' '#!/bin/sh' 'exit 101' > /usr/sbin/policy-rc.d\n chmod 755 /usr/sbin/policy-rc.d\n local package\n for package in \"$@\"; do\n if [[ \"$package\" == */* ]]; then\n # apt cannot fetch local archives with --download-only, so their installs\n # stay one call. Package triggers can be slow on cloud filesystems; the\n # longer whole-call deadline covers them while Acquire timeouts still\n # bound each network request.\n APT_DEADLINE=600 DEBIAN_FRONTEND=noninteractive apt_network install -y --no-install-recommends \"$@\"\n return\n fi\n done\n # The network deadline covers downloads only; unpacking and maintainer scripts\n # (for example locale generation or cluster creation) run offline afterwards.\n DEBIAN_FRONTEND=noninteractive apt_network install -y --no-install-recommends --download-only \"$@\"\n DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --no-download \"$@\"\n)\n\n`;\n\nconst postgresSourceLine =\n \"deb [signed-by=/usr/share/keyrings/stll-pgdg.asc] https://apt.postgresql.org/pub/repos/apt noble-pgdg main\";\nconst postgresSigningFingerprint = \"B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8\";\n\nconst postgresSources = String.raw`\npgdg_key_fingerprint() {\n gpg --batch --show-keys --with-colons \"$1\" | awk -F: '$1 == \"pub\" { primary = 1 } $1 == \"sub\" { primary = 0 } $1 == \"fpr\" && primary { print toupper($10); primary = 0 }'\n}\npgdg_sources_ready() {\n local managed=\"$1\" file mode records suite keyring override fingerprint selected_keyring=''\n shift\n PGDG_SOURCE_STATE=missing\n [[ ! -L \"$managed\" ]] || fail \"Managed PGDG source must not be a symlink: $managed\"\n for file in \"$@\"; do\n [[ -e \"$file\" ]] || continue\n [[ -f \"$file\" ]] || fail \"APT source must be a regular file: $file\"\n case \"$file\" in *.sources) mode=sources ;; *) mode=list ;; esac\n records=\"$(awk -v mode=\"$mode\" '\n function trim(value) { gsub(/^[[:space:]]+|[[:space:]]+$/, \"\", value); return value }\n function pgdg_uri(uri) {\n uri = tolower(uri)\n if (uri !~ /^[a-z][a-z0-9+.-]*:\\/\\//) return 0\n sub(/^[a-z][a-z0-9+.-]*:\\/\\//, \"\", uri)\n sub(/[\\/?#].*$/, \"\", uri)\n sub(/^.*@/, \"\", uri)\n sub(/:.*$/, \"\", uri)\n return uri == \"apt.postgresql.org\" || uri == \"apt.postgresql.org.\"\n }\n function contains_pgdg(value, tokens, count, token_index) {\n count = split(value, tokens, /[[:space:]]+/)\n for (token_index = 1; token_index <= count; token_index++) if (pgdg_uri(tokens[token_index])) return 1\n return 0\n }\n function unsafe_field(name) {\n return name ~ /^(trusted|allow-insecure|allow-weak|allow-downgrade-to-insecure)$/\n }\n function disabled_override(value) {\n value = tolower(trim(value))\n gsub(/^[\"\\047]|[\"\\047]$/, \"\", value)\n return value ~ /^(no|false|without|off|disable|0)$/\n }\n function stanza(override_index) {\n override = 0\n for (override_index = 1; override_index <= override_count; override_index++) {\n if (!disabled_override(override_values[override_index])) override = 1\n delete override_values[override_index]\n }\n if (tolower(trim(enabled)) != \"no\" && pgdg) print (trim(suites) == \"\" ? \"-\" : trim(suites)) \"\\t\" (trim(keyring) == \"\" ? \"-\" : trim(keyring)) \"\\t\" (override ? \"unsafe\" : \"safe\")\n enabled = \"\"; pgdg = 0; field = \"\"; suites = \"\"; keyring = \"\"; override = 0; override_count = 0\n }\n /^[[:space:]]*#/ { if (mode == \"list\" || $0 ~ /^#/) next }\n {\n line = $0\n if (mode == \"list\") {\n sub(/[[:space:]]*#.*$/, \"\", line)\n if (line !~ /^[[:space:]]*deb(-src)?[[:space:]]/ || !contains_pgdg(line)) next\n keyring = \"\"; override = 0\n if (match(line, /\\[[^]]*\\]/)) {\n options = substr(line, RSTART + 1, RLENGTH - 2)\n count = split(options, tokens, /[[:space:]]+/)\n for (token_index = 1; token_index <= count; token_index++) {\n if (tolower(tokens[token_index]) ~ /^signed-by=/) { keyring = tokens[token_index]; sub(/^[^=]*=/, \"\", keyring) }\n option_name = tolower(tokens[token_index]); sub(/=.*/, \"\", option_name)\n option_value = tokens[token_index]; sub(/^[^=]*=/, \"\", option_value)\n if (unsafe_field(option_name) && !disabled_override(option_value)) override = 1\n }\n sub(/\\[[^]]*\\]/, \"\", line)\n }\n count = split(line, tokens, /[[:space:]]+/)\n for (token_index = 1; token_index <= count; token_index++) if (pgdg_uri(tokens[token_index])) print (tokens[token_index + 1] == \"\" ? \"-\" : tokens[token_index + 1]) \"\\t\" (keyring == \"\" ? \"-\" : keyring) \"\\t\" (override ? \"unsafe\" : \"safe\")\n next\n }\n if (line ~ /^[[:space:]]*$/) { stanza(); next }\n if (line ~ /^[[:space:]]/) {\n if (field == \"uris\" && contains_pgdg(line)) pgdg = 1\n if (field == \"enabled\") enabled = enabled \" \" line\n if (field == \"suites\") suites = suites \" \" line\n if (field == \"signed-by\") keyring = keyring \" \" line\n if (unsafe_field(field)) override_values[override_count] = override_values[override_count] \" \" line\n next\n }\n field = tolower(line)\n sub(/:.*/, \"\", field)\n value = line\n sub(/^[^:]*:[[:space:]]*/, \"\", value)\n if (field == \"uris\" && contains_pgdg(value)) pgdg = 1\n if (field == \"enabled\") enabled = value\n if (field == \"suites\") suites = value\n if (field == \"signed-by\") keyring = value\n if (unsafe_field(field)) override_values[++override_count] = value\n }\n END { if (mode == \"sources\") stanza() }\n ' \"$file\")\" || fail \"Cannot inspect APT source: $file\"\n if [[ \"$file\" == \"$managed\" && -z \"$records\" ]]; then\n fail \"Managed PGDG source has no active PGDG entry: $file\"\n fi\n while IFS=$'\\t' read -r suite keyring override; do\n [[ -n \"$suite\" ]] || continue\n [[ \"$override\" == safe ]] || fail \"PGDG source enables an unsafe trust override: $file\"\n [[ \"$suite\" == noble-pgdg && \"$keyring\" == /* && ! \"$keyring\" =~ [[:space:],] ]] || fail \"PGDG source requires noble-pgdg and one Signed-By keyring: $file\"\n [[ -z \"$selected_keyring\" || \"$selected_keyring\" == \"$keyring\" ]] || fail \"Conflicting PGDG Signed-By keyrings: $file\"\n fingerprint=\"$(pgdg_key_fingerprint \"$keyring\")\" || fail \"Cannot verify PGDG Signed-By keyring: $file\"\n [[ \"$fingerprint\" == @PGDG_FINGERPRINT@ ]] || fail \"PGDG Signed-By fingerprint mismatch: $file\"\n selected_keyring=\"$keyring\"\n PGDG_SOURCE_STATE=reuse\n done <<< \"$records\"\n done\n}\n`;\n\nconst postgresInstall = String.raw`\n postgres_ready() {\n local binary\n for binary in postgres initdb pg_ctl psql createdb; do\n [[ -x \"/usr/lib/postgresql/@POSTGRES@/bin/$binary\" ]] || return 1\n done\n /usr/lib/postgresql/@POSTGRES@/bin/postgres --version | grep -Eq '^postgres \\(PostgreSQL\\) @POSTGRES@\\.'\n }\n if ! postgres_ready; then\n pgdg_sources_ready /etc/apt/sources.list.d/stll-pgdg.list /etc/apt/sources.list /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources\n if [[ \"$PGDG_SOURCE_STATE\" == missing ]]; then\n local key key_fingerprint\n key=\"$(mktemp)\"\n download_file https://www.postgresql.org/media/keys/ACCC4CF8.asc \"$key\" 45\n key_fingerprint=\"$(pgdg_key_fingerprint \"$key\")\"\n [[ \"$key_fingerprint\" == @PGDG_FINGERPRINT@ ]] || fail 'PostgreSQL signing key mismatch'\n install -d -m 755 /usr/share/keyrings\n install -m 644 \"$key\" /usr/share/keyrings/stll-pgdg.asc\n rm -- \"$key\"\n printf '%s\\n' '@PGDG_SOURCE@' > /etc/apt/sources.list.d/stll-pgdg.list\n fi\n apt_refresh_for postgresql-@POSTGRES@ postgresql-client-@POSTGRES@\n apt_install postgresql-@POSTGRES@ postgresql-client-@POSTGRES@\n fi\n postgres_ready || fail 'PostgreSQL toolchain is incomplete or differs from the policy major'\n`;\n\nconst valkeyInstall = String.raw`\n if ! command -v valkey-server >/dev/null || [[ \"$(valkey-server --version | sed -nE 's/.*v=([0-9.]+).*/\\1/p')\" != '@VALKEY@' ]] || ! command -v valkey-cli >/dev/null || [[ \"$(valkey-cli --version)\" != 'valkey-cli @VALKEY@' ]]; then\n local scratch server_url server_sha tools_url tools_sha package\n scratch=\"$(mktemp -d)\"\n chmod 755 \"$scratch\"\n case \"$ARCH\" in\n amd64) server_url='@AMD64_SERVER_URL@'; server_sha='@AMD64_SERVER_SHA@'; tools_url='@AMD64_TOOLS_URL@'; tools_sha='@AMD64_TOOLS_SHA@' ;;\n arm64) server_url='@ARM64_SERVER_URL@'; server_sha='@ARM64_SERVER_SHA@'; tools_url='@ARM64_TOOLS_URL@'; tools_sha='@ARM64_TOOLS_SHA@' ;;\n *) fail 'Unsupported Valkey architecture' ;;\n esac\n download_file \"$server_url\" \"$scratch/valkey-server.deb\" 120\n download_file \"$tools_url\" \"$scratch/valkey-tools.deb\" 120\n (cd \"$scratch\"; printf '%s %s\\n' \"$server_sha\" valkey-server.deb \"$tools_sha\" valkey-tools.deb | sha256sum --strict -c -)\n for package in valkey-server valkey-tools; do\n [[ \"$(dpkg-deb -f \"$scratch/$package.deb\" Package)\" == \"$package\" ]] || fail 'Valkey artifact package mismatch'\n [[ \"$(dpkg-deb -f \"$scratch/$package.deb\" Version)\" == '@VALKEY@-1.noble' ]] || fail 'Valkey artifact version mismatch'\n [[ \"$(dpkg-deb -f \"$scratch/$package.deb\" Architecture)\" == \"$ARCH\" ]] || fail 'Valkey artifact architecture mismatch'\n done\n apt_refresh_for \"$scratch/valkey-server.deb\" \"$scratch/valkey-tools.deb\"\n apt_install \"$scratch/valkey-server.deb\" \"$scratch/valkey-tools.deb\"\n rm -rf -- \"$scratch\"\n fi\n [[ \"$(valkey-server --version | sed -nE 's/.*v=([0-9.]+).*/\\1/p')\" == '@VALKEY@' ]] || fail 'Valkey version differs from policy'\n [[ \"$(valkey-cli --version)\" == 'valkey-cli @VALKEY@' ]] || fail 'Valkey client version differs from policy'\n`;\n\nconst state = String.raw`\nservice_account_ready() {\n local uid gid shell\n uid=\"$(id -u stll-cloud)\" || fail 'Service user is unavailable; run install'\n gid=\"$(id -g stll-cloud)\"\n shell=\"$(getent passwd stll-cloud | cut -d: -f7)\"\n [[ \"$uid\" =~ ^[1-9][0-9]*$ && \"$gid\" =~ ^[1-9][0-9]*$ && \"$shell\" == /usr/sbin/nologin ]] || fail 'Service user must be unprivileged with no login shell'\n}\nprepare_state() {\n service_account_ready\n [[ ! -L /var/lib/stll-cloud ]] || fail 'Service state root must not be a symlink'\n if [[ -e /var/lib/stll-cloud ]]; then\n [[ -d /var/lib/stll-cloud && \"$(stat -c '%u:%a' /var/lib/stll-cloud)\" == 0:755 ]] || fail 'Invalid service state root'\n else\n install -d -m 755 -o root -g root /var/lib/stll-cloud\n fi\n STATE=\"/var/lib/stll-cloud/$(printf '%s' \"$REPO_ROOT\" | sha256sum | cut -d' ' -f1)\"\n [[ ! -L \"$STATE\" ]] || fail 'Service state must not be a symlink'\n if [[ -e \"$STATE\" ]]; then\n [[ -d \"$STATE\" && \"$(stat -c '%u:%a' \"$STATE\")\" == 0:710 && \"$(stat -c '%g' \"$STATE\")\" == \"$(id -g stll-cloud)\" ]] || fail 'Invalid service state ownership'\n else\n install -d -m 710 -o root -g stll-cloud \"$STATE\"\n fi\n [[ ! -L \"$STATE/lock\" ]] || fail 'Service lock must not be a symlink'\n exec 9>\"$STATE/lock\"\n flock -x -w 10 9 || fail 'Another setup process owns the service state'\n}\n`;\n\nexport const renderCloudServiceInstall = ({\n services,\n postgres,\n valkey,\n valkeyArtifacts,\n}: CloudServiceInstallOptions) => {\n const parts = services.map((service) => {\n switch (service) {\n case \"postgres\":\n return postgresInstall\n .replaceAll(\"@POSTGRES@\", postgres)\n .replaceAll(\"@PGDG_SOURCE@\", postgresSourceLine)\n .replaceAll(\"@PGDG_FINGERPRINT@\", postgresSigningFingerprint);\n case \"valkey\": {\n const replacements = new Map([\n [\"@VALKEY@\", valkey],\n [\"@AMD64_SERVER_URL@\", valkeyArtifacts.amd64.server.url],\n [\"@AMD64_SERVER_SHA@\", valkeyArtifacts.amd64.server.sha256],\n [\"@AMD64_TOOLS_URL@\", valkeyArtifacts.amd64.tools.url],\n [\"@AMD64_TOOLS_SHA@\", valkeyArtifacts.amd64.tools.sha256],\n [\"@ARM64_SERVER_URL@\", valkeyArtifacts.arm64.server.url],\n [\"@ARM64_SERVER_SHA@\", valkeyArtifacts.arm64.server.sha256],\n [\"@ARM64_TOOLS_URL@\", valkeyArtifacts.arm64.tools.url],\n [\"@ARM64_TOOLS_SHA@\", valkeyArtifacts.arm64.tools.sha256],\n ]);\n return valkeyInstall.replace(/@[A-Z0-9_]+@/g, (token) => {\n const value = replacements.get(token);\n if (value === undefined)\n throw new Error(`Missing Valkey artifact field: ${token}`);\n return value;\n });\n }\n default: {\n const exhaustive: never = service;\n throw new Error(`Unsupported service: ${String(exhaustive)}`);\n }\n }\n });\n const user =\n services.length === 0\n ? \"\"\n : \" if ! id stll-cloud >/dev/null 2>&1; then useradd --system --user-group --no-create-home --shell /usr/sbin/nologin stll-cloud; fi\\n service_account_ready\\n\";\n return `${packageInstall}\\n${services.includes(\"postgres\") ? postgresSources.replaceAll(\"@PGDG_FINGERPRINT@\", postgresSigningFingerprint) : \"\"}\\n${services.length === 0 ? \"prepare_state() { :; }\\n\" : state}\\ninstall_services() {\\n${user}${parts.join(\"\")}\\n :\\n}\\n`;\n};\n","/** Shared deadlines cover retries and package-manager subprocesses. */\nexport const renderCloudNetwork = () => String.raw`\nrelease_log_holders() {\n # Processes left by package scripts may still hold a step log after the command exits.\n # Setup starts its own services later, so end them rather than let them write into a\n # deleted log for their whole lifetime.\n # One find over all descriptor links; no process per descriptor.\n local log=\"$1\" root=\"${\"$\"}{CLOUD_PROC_ROOT:-/proc}\" fd pid\n while IFS= read -r fd; do\n pid=\"${\"$\"}{fd%/fd/*}\"\n pid=\"${\"$\"}{pid##*/}\"\n [[ \"$pid\" =~ ^[0-9]+$ && \"$pid\" != \"$$\" ]] || continue\n kill -TERM \"$pid\" 2>/dev/null || true\n done < <(find \"$root\" -mindepth 3 -maxdepth 3 -path \"$root/[0-9]*/fd/*\" -lname \"$log\" 2>/dev/null)\n}\nnetwork_run() (\n local host=\"$1\" seconds=\"$2\" status=0\n shift 2\n network_log=\"$(mktemp)\" || return \"$?\"\n trap 'rm -f -- \"$network_log\"' EXIT\n trap 'exit 129' HUP\n trap 'exit 130' INT\n trap 'exit 143' TERM\n # Output goes to a file, never a pipe: package scripts may leave processes that keep\n # inherited descriptors open, and a pipe reader would wait for them past the command.\n # Input is never the terminal: timeout runs the command outside the foreground process\n # group, where apt restoring terminal settings on a terminal stdin stops it for good.\n timeout --signal=TERM --kill-after=5s \"$seconds\"s \"$@\" < /dev/null > \"$network_log\" 2>&1 || status=$?\n release_log_holders \"$network_log\"\n cat -- \"$network_log\" || fail 'Cannot capture network command output'\n [[ \"$status\" != 0 ]] || return 0\n if [[ \"$status\" == 124 || \"$status\" == 137 || \"$status\" == 28 ]] || grep -Eiq 'timed[[:space:]-]+out|time[[:space:]-]+out|timeout[[:space:]]+(was[[:space:]]+)?(reached|expired)|(connection|operation|socket)[[:space:]-]+timeout' \"$network_log\"; then\n fail \"download timed out: $host\"\n fi\n return \"$status\"\n)\ndownload_file() {\n local url=\"$1\" destination=\"$2\" seconds=\"$3\" host\n host=\"$(printf '%s\\n' \"$url\" | cut -d/ -f3 | sed 's/.*@//')\"\n [[ \"$url\" == https://* && -n \"$host\" ]] || fail 'Downloads require an HTTPS host'\n network_run \"$host\" \"$seconds\" curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' --tlsv1.2 --connect-timeout 20 --max-time \"$seconds\" --retry 3 --retry-all-errors --retry-max-time \"$seconds\" \"$url\" -o \"$destination\"\n}\napt_network() {\n local hosts\n # --print-uris reads configured indexes without contacting their servers.\n hosts=\"$(set -o pipefail; apt-get --print-uris update | awk -F/ '/^\\047https?:\\/\\// { host=$3; sub(/.*@/, \"\", host); if (!seen[host]++) { printf \"%s%s\", separator, host; separator=\",\" } }')\" || return \"$?\"\n [[ -n \"$hosts\" ]] || hosts='configured APT hosts'\n # APT_DEADLINE: whole-call seconds; callers that also unpack packages may extend it.\n network_run \"$hosts\" \"${\"$\"}{APT_DEADLINE:-180}\" apt-get -o Acquire::http::Timeout=20 -o Acquire::https::Timeout=20 -o Acquire::Retries=3 -o APT::Update::Error-Mode=any \"$@\"\n}\napt_refresh_for() {\n # Skip the refresh only when the install downloads nothing: then no package\n # source is contacted and stale cached indexes cannot point at missing files.\n local uris\n if uris=\"$(DEBIAN_FRONTEND=noninteractive apt-get --print-uris -qq -y --no-install-recommends install \"$@\" 2>/dev/null)\" && [[ -z \"$uris\" ]]; then\n return 0\n fi\n apt_network update\n}\n`;\n","type CloudSetupArtifact = {\n url: `https://${string}`;\n sha256: string;\n archive: \"binary\" | \"tar.gz\";\n binaries: Readonly<Record<string, string>>;\n};\n\ntype CloudSetupArtifactRelease = {\n version: string;\n amd64: CloudSetupArtifact;\n arm64: CloudSetupArtifact;\n};\n\nconst wasmBindgen0126 = {\n version: \"0.2.126\",\n amd64: {\n url: \"https://github.com/wasm-bindgen/wasm-bindgen/releases/download/0.2.126/wasm-bindgen-0.2.126-x86_64-unknown-linux-musl.tar.gz\",\n sha256: \"064948d58e2d6c0a745216477a639ba696216d6309aaa902939d1b865b1d869d\",\n archive: \"tar.gz\",\n binaries: {\n \"wasm-bindgen-test-runner\":\n \"wasm-bindgen-0.2.126-x86_64-unknown-linux-musl/wasm-bindgen-test-runner\",\n wasm2es6js: \"wasm-bindgen-0.2.126-x86_64-unknown-linux-musl/wasm2es6js\",\n \"wasm-bindgen\":\n \"wasm-bindgen-0.2.126-x86_64-unknown-linux-musl/wasm-bindgen\",\n },\n },\n arm64: {\n url: \"https://github.com/wasm-bindgen/wasm-bindgen/releases/download/0.2.126/wasm-bindgen-0.2.126-aarch64-unknown-linux-musl.tar.gz\",\n sha256: \"2245120254a9f6c9a9adf3601f3d52bb31309219e9ceab7696e74e24885c440a\",\n archive: \"tar.gz\",\n binaries: {\n \"wasm-bindgen-test-runner\":\n \"wasm-bindgen-0.2.126-aarch64-unknown-linux-musl/wasm-bindgen-test-runner\",\n wasm2es6js: \"wasm-bindgen-0.2.126-aarch64-unknown-linux-musl/wasm2es6js\",\n \"wasm-bindgen\":\n \"wasm-bindgen-0.2.126-aarch64-unknown-linux-musl/wasm-bindgen\",\n },\n },\n} as const satisfies CloudSetupArtifactRelease;\n\n/** Pinned upstream Linux artifacts, verified against their published SHA-256 sums. */\nexport const cloudSetupArtifacts = {\n \"rustup-init\": {\n version: \"1.29.1\",\n amd64: {\n url: \"https://static.rust-lang.org/rustup/archive/1.29.1/x86_64-unknown-linux-gnu/rustup-init\",\n sha256:\n \"dda7234360b7f578ca8b0ddcb80145646fa61a67c1720a5abc7051b35c9fcb71\",\n archive: \"binary\",\n binaries: {\n \"rustup-init\": \"rustup-init\",\n },\n },\n arm64: {\n url: \"https://static.rust-lang.org/rustup/archive/1.29.1/aarch64-unknown-linux-gnu/rustup-init\",\n sha256:\n \"15f6e4ce9f583b929c996c91562bad6d4454f3281de858b02cdfdef615fac433\",\n archive: \"binary\",\n binaries: {\n \"rustup-init\": \"rustup-init\",\n },\n },\n },\n gitleaks: {\n version: \"8.30.1\",\n amd64: {\n url: \"https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz\",\n sha256:\n \"551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb\",\n archive: \"tar.gz\",\n binaries: { gitleaks: \"gitleaks\" },\n },\n arm64: {\n url: \"https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_arm64.tar.gz\",\n sha256:\n \"e4a487ee7ccd7d3a7f7ec08657610aa3606637dab924210b3aee62570fb4b080\",\n archive: \"tar.gz\",\n binaries: { gitleaks: \"gitleaks\" },\n },\n },\n \"cargo-nextest\": {\n version: \"0.9.148\",\n amd64: {\n url: \"https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-0.9.148/cargo-nextest-0.9.148-x86_64-unknown-linux-musl.tar.gz\",\n sha256:\n \"bf92cb81450872d960ffa13857a83084d557ec0cdc141663d263bb23ef756f97\",\n archive: \"tar.gz\",\n binaries: {\n \"cargo-nextest\": \"cargo-nextest\",\n },\n },\n arm64: {\n url: \"https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-0.9.148/cargo-nextest-0.9.148-aarch64-unknown-linux-musl.tar.gz\",\n sha256:\n \"94676506ceaed01746d78cfe9ed124ee841b2932fd18d9d10f438a347bd9ba5e\",\n archive: \"tar.gz\",\n binaries: {\n \"cargo-nextest\": \"cargo-nextest\",\n },\n },\n },\n \"wasm-bindgen-cli\": {\n version: \"0.2.129\",\n amd64: {\n url: \"https://github.com/wasm-bindgen/wasm-bindgen/releases/download/0.2.129/wasm-bindgen-0.2.129-x86_64-unknown-linux-musl.tar.gz\",\n sha256:\n \"82d12bb940e2d4e72e0d5605387fc1b8ca179044e012b620f0ce4e7440e8320e\",\n archive: \"tar.gz\",\n binaries: {\n \"wasm-bindgen-test-runner\":\n \"wasm-bindgen-0.2.129-x86_64-unknown-linux-musl/wasm-bindgen-test-runner\",\n wasm2es6js: \"wasm-bindgen-0.2.129-x86_64-unknown-linux-musl/wasm2es6js\",\n \"wasm-bindgen\":\n \"wasm-bindgen-0.2.129-x86_64-unknown-linux-musl/wasm-bindgen\",\n },\n },\n arm64: {\n url: \"https://github.com/wasm-bindgen/wasm-bindgen/releases/download/0.2.129/wasm-bindgen-0.2.129-aarch64-unknown-linux-musl.tar.gz\",\n sha256:\n \"2ed4351c35dd9440308bbb02767d47ea278efe851a52465300f3c94f5b6c2a87\",\n archive: \"tar.gz\",\n binaries: {\n \"wasm-bindgen-test-runner\":\n \"wasm-bindgen-0.2.129-aarch64-unknown-linux-musl/wasm-bindgen-test-runner\",\n wasm2es6js:\n \"wasm-bindgen-0.2.129-aarch64-unknown-linux-musl/wasm2es6js\",\n \"wasm-bindgen\":\n \"wasm-bindgen-0.2.129-aarch64-unknown-linux-musl/wasm-bindgen\",\n },\n },\n },\n uv: {\n version: \"0.13.1\",\n amd64: {\n url: \"https://github.com/astral-sh/uv/releases/download/0.13.1/uv-x86_64-unknown-linux-musl.tar.gz\",\n sha256:\n \"6c86040a8f045ab9adc9e3ec4cdafa03fd00e9a988ed2bf28971c7fc2d0debd0\",\n archive: \"tar.gz\",\n binaries: {\n uv: \"uv-x86_64-unknown-linux-musl/uv\",\n uvx: \"uv-x86_64-unknown-linux-musl/uvx\",\n },\n },\n arm64: {\n url: \"https://github.com/astral-sh/uv/releases/download/0.13.1/uv-aarch64-unknown-linux-musl.tar.gz\",\n sha256:\n \"345a8308e4d1835cdfaadf692836fd3137a6d45864773f05ad7bf59442b1ba16\",\n archive: \"tar.gz\",\n binaries: {\n uv: \"uv-aarch64-unknown-linux-musl/uv\",\n uvx: \"uv-aarch64-unknown-linux-musl/uvx\",\n },\n },\n },\n} as const satisfies Record<string, CloudSetupArtifactRelease>;\n\nexport type CloudSetupArtifactTool = keyof typeof cloudSetupArtifacts;\nexport type CloudSetupArchitecture = keyof Omit<\n (typeof cloudSetupArtifacts)[CloudSetupArtifactTool],\n \"version\"\n>;\n\n/** Explicit releases whose CLI must match a project's wasm-bindgen crate exactly. */\nexport const wasmBindgenArtifactReleases = [\n wasmBindgen0126,\n cloudSetupArtifacts[\"wasm-bindgen-cli\"],\n] as const;\n\n/** Every supported version participates in lookup and catalog validation. */\nexport const cloudSetupArtifactVersions = {\n \"rustup-init\": [cloudSetupArtifacts[\"rustup-init\"]],\n \"cargo-nextest\": [cloudSetupArtifacts[\"cargo-nextest\"]],\n \"wasm-bindgen-cli\": wasmBindgenArtifactReleases,\n uv: [cloudSetupArtifacts.uv],\n gitleaks: [cloudSetupArtifacts.gitleaks],\n} as const satisfies Record<\n CloudSetupArtifactTool,\n readonly CloudSetupArtifactRelease[]\n>;\n\n/** A new version requires an explicit, verified catalog entry; never build from source. */\nexport const getCloudSetupArtifact = (\n tool: CloudSetupArtifactTool,\n version: string,\n) => {\n const releases = cloudSetupArtifactVersions[tool];\n const artifact = releases.find((release) => release.version === version);\n if (artifact === undefined)\n throw new Error(\n `Unsupported ${tool} version ${version}; supported versions: ${releases.map((release) => release.version).join(\", \")}`,\n );\n return artifact;\n};\n\ntype CloudSetupPackage = {\n version: string;\n package: string;\n binary: `/${string}`;\n identity: string;\n};\n\n/** Ubuntu 24.04 packages; apt resolves them from the image's configured sources. */\nexport const cloudSetupPackages = {\n // GNU time reports \"UNKNOWN\" as its version; dpkg records the upstream release.\n time: {\n version: \"1.9\",\n package: \"time\",\n binary: \"/usr/bin/time\",\n identity: \"time (GNU Time) \",\n },\n} as const satisfies Record<string, CloudSetupPackage>;\n\nexport type CloudSetupPackageTool = keyof typeof cloudSetupPackages;\n\n/** Ubuntu 24.04 ships one release per package; other versions are unsupported. */\nexport const getCloudSetupPackage = (\n tool: CloudSetupPackageTool,\n version: string,\n) => {\n const release = cloudSetupPackages[tool];\n if (release.version !== version)\n throw new Error(\n `Unsupported ${tool} version ${version}; supported versions: ${release.version}`,\n );\n return release;\n};\n","import {\n cloudSetupArtifacts,\n type CloudSetupArtifactTool,\n cloudSetupPackages,\n type CloudSetupPackageTool,\n} from \"./cloud-setup-artifacts\";\n\nexport const cloudServices = [\"postgres\", \"valkey\"] as const;\nexport type CloudService = (typeof cloudServices)[number];\nexport type CloudArtifactTool = Exclude<CloudSetupArtifactTool, \"rustup-init\">;\nexport const cloudArtifactTools = Object.keys(cloudSetupArtifacts).filter(\n (tool): tool is CloudArtifactTool =>\n tool !== \"rustup-init\" && Object.hasOwn(cloudSetupArtifacts, tool),\n);\nexport const cloudPackageTools = Object.keys(cloudSetupPackages).filter(\n (tool): tool is CloudSetupPackageTool =>\n Object.hasOwn(cloudSetupPackages, tool),\n);\nexport type CloudExtraTool = CloudArtifactTool | CloudSetupPackageTool;\nexport const cloudExtraTools = [...cloudArtifactTools, ...cloudPackageTools];\nexport const isCloudPackageTool = (\n tool: string,\n): tool is CloudSetupPackageTool =>\n cloudPackageTools.some((candidate) => candidate === tool);\n\nconst object = (input: unknown): input is Record<string, unknown> =>\n typeof input === \"object\" && input !== null && !Array.isArray(input);\nconst exactPin = (input: unknown): input is string =>\n typeof input === \"string\" &&\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)$/.test(input);\n// Upstream releases of distribution packages may omit the patch component.\nconst exactToolPin = (tool: CloudExtraTool, input: unknown): input is string =>\n isCloudPackageTool(tool)\n ? typeof input === \"string\" &&\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:\\.(?:0|[1-9]\\d*))?$/.test(input)\n : exactPin(input);\n\nexport const cloudRustComponentBinaries = {\n clippy: [\"cargo-clippy\", \"clippy-driver\"],\n rustfmt: [\"rustfmt\", \"cargo-fmt\"],\n \"rust-src\": [],\n \"rust-analyzer\": [\"rust-analyzer\"],\n} as const;\nexport const parseCloudRustNames = (\n input: unknown,\n kind: \"components\" | \"targets\",\n) => {\n const label = `cloud Rust ${kind}`;\n if (input === undefined) return [];\n if (!Array.isArray(input)) throw new Error(`${label} must be an array`);\n const result = input.map((value: unknown) => {\n if (typeof value !== \"string\" || !/^[a-z][a-z0-9_-]*$/.test(value))\n throw new Error(`${label} requires canonical names`);\n if (\n kind === \"components\" &&\n !Object.hasOwn(cloudRustComponentBinaries, value)\n )\n throw new Error(`${label} contains an unsupported component: ${value}`);\n return value;\n });\n if (new Set(result).size !== result.length)\n throw new Error(`${label} contains duplicates`);\n return result;\n};\nconst parseRust = (input: unknown) => {\n if (input === undefined) return undefined;\n if (\n !object(input) ||\n Object.keys(input).some(\n (key) =>\n ![\n \"toolchain\",\n \"components\",\n \"targets\",\n \"additionalToolchains\",\n ].includes(key),\n )\n )\n throw new Error(\n \"cloud.rust accepts only toolchain, components, targets and additionalToolchains\",\n );\n const toolchain = input[\"toolchain\"];\n if (toolchain !== undefined && !exactPin(toolchain))\n throw new Error(\"cloud.rust.toolchain must be an exact stable release\");\n const additional = input[\"additionalToolchains\"];\n if (additional !== undefined && !Array.isArray(additional))\n throw new Error(\n \"cloud.rust.additionalToolchains requires exact stable releases\",\n );\n const additionalToolchains =\n additional === undefined\n ? []\n : Array.from(additional, (pin: unknown) => {\n if (!exactPin(pin))\n throw new Error(\n \"cloud.rust.additionalToolchains requires exact stable releases\",\n );\n return pin;\n });\n if (new Set(additionalToolchains).size !== additionalToolchains.length)\n throw new Error(\"cloud.rust.additionalToolchains contains duplicates\");\n return {\n additionalToolchains,\n ...(toolchain === undefined ? {} : { toolchain }),\n components: parseCloudRustNames(input[\"components\"], \"components\"),\n targets: parseCloudRustNames(input[\"targets\"], \"targets\"),\n };\n};\nconst parseTools = (input: unknown) => {\n if (input === undefined) return undefined;\n if (\n !object(input) ||\n Object.keys(input).some(\n (key) => !cloudExtraTools.some((tool) => tool === key),\n )\n )\n throw new Error(`cloud.tools accepts only ${cloudExtraTools.join(\", \")}`);\n const result: Partial<Record<CloudExtraTool, string>> = {};\n for (const tool of cloudExtraTools) {\n const pin = input[tool];\n if (pin === undefined) {\n if (Object.hasOwn(input, tool))\n throw new Error(`cloud.tools.${tool} must be an exact stable release`);\n continue;\n }\n if (!exactToolPin(tool, pin))\n throw new Error(`cloud.tools.${tool} must be an exact stable release`);\n result[tool] = pin;\n }\n return result;\n};\n\nexport const cloudInstallCommand = \"bun install --frozen-lockfile\";\n// Lifecycle scripts (postinstall code generation) can outlast a cloud setup\n// budget; a repository opts out and lets tasks generate what they need.\nexport const cloudInstallCommands = [\n cloudInstallCommand,\n `${cloudInstallCommand} --ignore-scripts`,\n] as const;\nexport type CloudInstallCommand = (typeof cloudInstallCommands)[number];\n\nconst cloudInstall = (value: unknown): value is CloudInstallCommand =>\n cloudInstallCommands.some((command) => value === command);\n\nconst cloudService = (value: unknown): value is CloudService =>\n cloudServices.some((service) => value === service);\n\nconst parseEnvFile = (input: object) => {\n if (!(\"envFile\" in input) || typeof input.envFile !== \"string\")\n throw new Error(\n \"cloud.envFile must be a canonical repository-relative path\",\n );\n const envFile = input.envFile;\n if (\n envFile.startsWith(\"/\") ||\n /^[A-Za-z]:/.test(envFile) ||\n envFile.includes(\"\\\\\") ||\n /\\p{Cc}/u.test(envFile) ||\n envFile\n .split(\"/\")\n .some((part) => part === \"\" || part === \".\" || part === \"..\")\n )\n throw new Error(\n \"cloud.envFile must be a canonical repository-relative path\",\n );\n return envFile;\n};\n\n// One package script the install snapshot runs after dependencies, for\n// derived sources a repository's tasks need but its install skips (for\n// example with --ignore-scripts). It is offline work, so it gets a hard\n// time bound instead of a network allowance.\nexport const cloudPrepareMaxSeconds = 900;\nconst cloudPrepareScript = /^[a-z0-9][a-z0-9:._-]*$/;\n\nconst parsePrepare = (input: unknown) => {\n if (input === undefined) return undefined;\n if (typeof input !== \"object\" || input === null || Array.isArray(input))\n throw new Error(\"cloud.prepare must be an object\");\n for (const key of Object.keys(input))\n if (key !== \"script\" && key !== \"seconds\")\n throw new Error(`unsupported cloud.prepare key: ${key}`);\n const script = \"script\" in input ? input.script : undefined;\n if (typeof script !== \"string\" || !cloudPrepareScript.test(script))\n throw new Error(\"cloud.prepare.script must name a package script\");\n const seconds = \"seconds\" in input ? input.seconds : undefined;\n if (\n typeof seconds !== \"number\" ||\n !Number.isInteger(seconds) ||\n seconds < 1 ||\n seconds > cloudPrepareMaxSeconds\n )\n throw new Error(\n `cloud.prepare.seconds must be an integer from 1 to ${cloudPrepareMaxSeconds}`,\n );\n return { script, seconds } as const;\n};\n\n/** Parse an explicit declaration without assuming services for undeclared repositories. */\nexport const parseCloudSetup = (input: unknown) => {\n if (input === undefined) return undefined;\n if (typeof input !== \"object\" || input === null || Array.isArray(input))\n throw new Error(\"cloud must be an object\");\n for (const key of Object.keys(input))\n if (\n key !== \"services\" &&\n key !== \"install\" &&\n key !== \"envFile\" &&\n key !== \"rust\" &&\n key !== \"tools\" &&\n key !== \"prepare\" &&\n key !== \"submodules\"\n )\n throw new Error(`unsupported cloud key: ${key}`);\n const rust = parseRust(\"rust\" in input ? input.rust : undefined);\n const tools = parseTools(\"tools\" in input ? input.tools : undefined);\n const prepare = parsePrepare(\"prepare\" in input ? input.prepare : undefined);\n const submodules = \"submodules\" in input ? input.submodules : false;\n if (typeof submodules !== \"boolean\")\n throw new Error(\"cloud.submodules must be a boolean when provided\");\n const extensions = {\n ...(rust === undefined ? {} : { rust }),\n ...(tools === undefined ? {} : { tools }),\n ...(prepare === undefined ? {} : { prepare }),\n };\n const selected = \"services\" in input ? input.services : [];\n if (!Array.isArray(selected))\n throw new Error(\"cloud.services must be an array when provided\");\n if (!(\"install\" in input) || !cloudInstall(input.install))\n throw new Error(\n `cloud.install must be exactly one of: ${cloudInstallCommands.join(\", \")}`,\n );\n const install = input.install;\n const seen = new Set<CloudService>();\n const services = Array.from(selected, (service: unknown) => {\n if (!cloudService(service))\n throw new Error(\"cloud.services contains an unsupported service\");\n if (seen.has(service))\n throw new Error(`cloud.services contains duplicate service: ${service}`);\n seen.add(service);\n return service;\n });\n if (services.length === 0 && \"envFile\" in input)\n throw new Error(\"cloud.envFile is not allowed without services\");\n return {\n services,\n install,\n ...(submodules ? { submodules } : {}),\n ...extensions,\n ...(services.length === 0 ? {} : { envFile: parseEnvFile(input) }),\n } as const;\n};\n","import type { CloudService } from \"./cloud-setup-schema\";\n\ntype CloudServiceStartOptions = {\n services: readonly CloudService[];\n postgres: string;\n valkey: string;\n};\n\nconst common = String.raw`\nservice_file() {\n local file=\"$1\" owner=\"$2\"\n [[ ! -L \"$file\" ]] || fail \"Service state must not contain symbolic links\"\n if [[ -e \"$file\" ]]; then\n [[ -f \"$file\" && \"$(stat -c '%u:%a' \"$file\")\" == \"$owner:600\" ]] || fail \"Invalid service state file\"\n fi\n}\nservice_directory() {\n local directory=\"$1\"\n [[ ! -L \"$directory\" ]] || fail \"Service directory must not be a symbolic link\"\n if [[ -e \"$directory\" ]]; then\n [[ -d \"$directory\" && \"$(stat -c '%u:%a' \"$directory\")\" == \"$SERVICE_UID:700\" ]] || fail \"Invalid service directory\"\n else\n root install -d -m 700 -o stll-cloud -g stll-cloud \"$directory\"\n fi\n}\nservice_password() {\n local file=\"$1\"\n service_file \"$file\" 0\n if [[ ! -e \"$file\" ]]; then\n (umask 077; openssl rand -hex 32 > \"$file\")\n root chown root:root \"$file\"\n fi\n [[ \"$(cat \"$file\")\" =~ ^[0-9a-f]{64}$ ]] || fail \"Invalid service credential state\"\n}\nservice_process_matches() {\n local pid=\"$1\" executable=\"$2\" owner actual expected\n [[ \"$pid\" =~ ^[1-9][0-9]*$ && -d \"/proc/$pid\" ]] || return 1\n owner=\"$(stat -c '%u' \"/proc/$pid\" 2>/dev/null)\" || return 2\n [[ \"$owner\" =~ ^[0-9]+$ ]] || return 2\n [[ \"$owner\" == \"$SERVICE_UID\" ]] || return 1\n # Read the executable link as its verified owner: container root may lack the ptrace\n # capability that reading another user's /proc/<pid>/exe requires.\n actual=\"$(service_run readlink -f \"/proc/$pid/exe\" 2>/dev/null)\" || return 2\n expected=\"$(readlink -f \"$executable\")\" || return 2\n [[ -n \"$actual\" && -n \"$expected\" && \"$actual\" != *' (deleted)' ]] || return 2\n [[ \"$actual\" == \"$expected\" ]]\n}\nservice_process() {\n service_process_matches \"$1\" \"$2\" || fail \"Managed service process identity differs from the recorded state\"\n}\nservice_prune_pid() {\n local file=\"$1\" executable=\"$2\" service=\"$3\" pid identity\n [[ -e \"$file\" ]] || return 0\n pid=\"$(head -n 1 \"$file\")\"\n # PostgreSQL encodes a standalone backend with a negative PID.\n if [[ \"$service\" == postgres ]]; then pid=\"$(printf '%s' \"$pid\" | sed 's/^-//')\"; fi\n if service_process_matches \"$pid\" \"$executable\"; then return 0; else identity=$?; fi\n [[ \"$identity\" != 2 ]] || fail \"Cannot verify recorded live service process; retaining its PID file\"\n # Let PostgreSQL check orphan shared memory before removing a dead-PID lock.\n if [[ \"$service\" == postgres && \"$pid\" =~ ^[1-9][0-9]*$ && ! -d \"/proc/$pid\" ]]; then return 0; fi\n if [[ \"$service\" == postgres ]]; then\n [[ \"$pid\" =~ ^[1-9][0-9]*$ && \"$SERVICE_UID\" != 0 ]] || fail \"Cannot safely recover PostgreSQL PID state\"\n # The root controller is not our nonroot postgres. Preserve the remaining\n # lock rows so PostgreSQL's EPERM/ancestor path still checks orphan memory.\n root sed -i \"1s/.*/$$/\" \"$file\"\n return 0\n fi\n # Restored state can name an unrelated live process; never signal that PID.\n root rm -- \"$file\"\n}\n`;\n\nconst postgresStart = String.raw`\n local pg_bin='/usr/lib/postgresql/@POSTGRES@/bin' pg_data=\"$STATE/postgres\" pg_password pg_details pg_pid pg_version pg_state='already running'\n service_password \"$STATE/postgres.password\"\n pg_password=\"$(cat \"$STATE/postgres.password\")\"\n service_directory \"$pg_data\"\n for file in PG_VERSION postmaster.pid postgresql.conf pg_hba.conf pg_ident.conf postgresql.auto.conf; do\n service_file \"$pg_data/$file\" \"$SERVICE_UID\"\n done\n if [[ ! -e \"$pg_data/PG_VERSION\" ]]; then\n [[ -z \"$(ls -A \"$pg_data\")\" ]] || fail \"PostgreSQL data directory is not initialized\"\n service_file \"$STATE/postgres.init-password\" \"$SERVICE_UID\"\n (umask 077; printf '%s\\n' \"$pg_password\" > \"$STATE/postgres.init-password\")\n root chown stll-cloud:stll-cloud \"$STATE/postgres.init-password\"\n service_run env PGHOST=127.0.0.1 PGHOSTADDR=127.0.0.1 \"$pg_bin/initdb\" -D \"$pg_data\" --username=stll_cloud --auth-host=scram-sha-256 --auth-local=scram-sha-256 --pwfile=\"$STATE/postgres.init-password\" --encoding=UTF8 --locale=C --set=unix_socket_directories= >/dev/null || fail \"PostgreSQL initialization failed\"\n root rm \"$STATE/postgres.init-password\"\n fi\n [[ -f \"$pg_data/PG_VERSION\" && \"$(cat \"$pg_data/PG_VERSION\")\" == '@POSTGRES@' ]] || fail \"PostgreSQL data has a different major version\"\n service_prune_pid \"$pg_data/postmaster.pid\" \"$pg_bin/postgres\" postgres\n if ! service_run env PGHOST=127.0.0.1 PGHOSTADDR=127.0.0.1 \"$pg_bin/pg_ctl\" -D \"$pg_data\" status >/dev/null 2>&1; then\n service_run env PGHOST=127.0.0.1 PGHOSTADDR=127.0.0.1 \"$pg_bin/pg_ctl\" -D \"$pg_data\" -l \"$pg_data/cloud.log\" -o \"-h 127.0.0.1 -p 55432 -c unix_socket_directories=\" -t 10 -w start >/dev/null || fail \"PostgreSQL start failed; port 55432 must be available\"\n pg_state=started\n fi\n pg_details=\"$(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 current_setting('data_directory'), current_setting('listen_addresses'), current_setting('port'), current_setting('server_version_num'), current_setting('unix_socket_directories')\")\" || fail \"PostgreSQL authenticated readiness failed\"\n pg_version=\"$(printf '%s\\n' \"$pg_details\" | cut -d '|' -f4)\"\n [[ \"$pg_details\" == \"$pg_data|127.0.0.1|55432|$pg_version|\" && \"$pg_version\" =~ ^[0-9]{6}$ ]] || fail \"PostgreSQL endpoint does not match managed data and listener\"\n (( pg_version / 10000 == @POSTGRES@ )) || fail \"PostgreSQL endpoint has a different major version\"\n pg_pid=\"$(head -n 1 \"$pg_data/postmaster.pid\")\"\n service_process \"$pg_pid\" \"$pg_bin/postgres\"\n [[ \"$(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\"\n POSTGRES_HOST='127.0.0.1:55432'\n POSTGRES_USER='stll_cloud'\n POSTGRES_PASSWORD=\"$pg_password\"\n POSTGRES_DB_NAME='cloud_test'\n POSTGRES_ADDITIONAL_CONNECTION_DATA=''\n DATABASE_URL=\"postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/$POSTGRES_DB_NAME$POSTGRES_ADDITIONAL_CONNECTION_DATA\"\n printf 'postgres: %s\\n' \"$pg_state\"\n`;\n\nconst valkeyStart = String.raw`\n local vk_data=\"$STATE/valkey\" vk_password vk_config vk_info vk_pid vk_expected ready=0 vk_state='already running'\n service_password \"$STATE/valkey.password\"\n vk_password=\"$(cat \"$STATE/valkey.password\")\"\n service_directory \"$vk_data\"\n vk_config=\"$vk_data/valkey.conf\"\n service_file \"$vk_config\" \"$SERVICE_UID\"\n for file in valkey.pid valkey.log dump.rdb; do\n [[ ! -L \"$vk_data/$file\" ]] || fail \"Valkey state must not contain symbolic links\"\n if [[ -e \"$vk_data/$file\" ]]; then\n [[ -f \"$vk_data/$file\" && \"$(stat -c '%u' \"$vk_data/$file\")\" == \"$SERVICE_UID\" ]] || fail \"Invalid Valkey state file\"\n fi\n done\n vk_expected=\"$(printf '%s\\n' 'bind 127.0.0.1' 'port 56379' 'protected-mode yes' 'daemonize yes' \"requirepass $vk_password\" \"dir $vk_data\" \"pidfile $vk_data/valkey.pid\" \"logfile $vk_data/valkey.log\" 'save \"\"' 'appendonly no')\"\n if [[ ! -e \"$vk_config\" ]]; then\n (umask 077; printf '%s\\n' \"$vk_expected\" > \"$vk_config\")\n root chown stll-cloud:stll-cloud \"$vk_config\"\n fi\n [[ \"$(cat \"$vk_config\")\" == \"$vk_expected\" ]] || fail \"Valkey configuration differs from managed settings\"\n service_prune_pid \"$vk_data/valkey.pid\" \"$(command -v valkey-server)\" valkey\n if [[ ! -e \"$vk_data/valkey.pid\" ]]; then\n service_run valkey-server \"$vk_config\" >/dev/null || fail \"Valkey start failed; port 56379 must be available\"\n vk_state=started\n fi\n for ((attempt=0; attempt<20; attempt++)); do\n if vk_info=\"$(VALKEYCLI_AUTH=\"$vk_password\" timeout 0.2 valkey-cli -h 127.0.0.1 -p 56379 --raw INFO server 2>/dev/null)\"; then\n if [[ \"$vk_info\" == *$'valkey_version:@VALKEY@\\r\\n'* && \"$vk_info\" == *\"config_file:$vk_config\"$'\\r\\n'* ]]; then ready=1; break; fi\n fi\n sleep 0.25\n done\n [[ \"$ready\" == 1 ]] || fail \"Valkey authenticated readiness or managed version/configuration check failed\"\n [[ -f \"$vk_data/valkey.pid\" ]] || fail \"Valkey managed process identifier is unavailable\"\n vk_pid=\"$(cat \"$vk_data/valkey.pid\")\"\n service_process \"$vk_pid\" \"$(command -v valkey-server)\"\n [[ \"$vk_info\" == *\"process_id:$vk_pid\"$'\\r\\n'* ]] || fail \"Valkey endpoint has a different process identifier\"\n [[ \"$(VALKEYCLI_AUTH=\"$vk_password\" timeout 2 valkey-cli -h 127.0.0.1 -p 56379 --raw CONFIG GET bind)\" == $'bind\\n127.0.0.1' ]] || fail \"Valkey endpoint must bind only loopback\"\n [[ \"$(VALKEYCLI_AUTH=\"$vk_password\" timeout 2 valkey-cli -h 127.0.0.1 -p 56379 --raw CONFIG GET dir)\" == \"$(printf 'dir\\n%s' \"$vk_data\")\" ]] || fail \"Valkey endpoint has a different data directory\"\n REDIS_URL=\"redis://:$vk_password@127.0.0.1:56379/0\"\n printf 'valkey: %s\\n' \"$vk_state\"\n`;\n\n/** Render only declared services; installation and environment-file ownership stay with the caller. */\nexport const renderCloudServiceStart = ({\n services,\n postgres,\n valkey,\n}: CloudServiceStartOptions): string => {\n if (!/^[1-9][0-9]*$/.test(postgres) || !/^\\d+\\.\\d+\\.\\d+$/.test(valkey))\n throw new Error(\"Invalid cloud service runtime policy\");\n if (services.length === 0) return \"start_services() { :; }\\n\";\n const bodies = services.map((service) => {\n switch (service) {\n case \"postgres\":\n return postgresStart.replaceAll(\"@POSTGRES@\", postgres);\n case \"valkey\":\n return valkeyStart.replaceAll(\"@VALKEY@\", valkey);\n default: {\n const exhaustive: never = service;\n throw new Error(`Unsupported cloud service: ${String(exhaustive)}`);\n }\n }\n });\n return `${common}\\nstart_services() {\\n local SERVICE_UID file attempt\\n SERVICE_UID=\"$(id -u stll-cloud)\"\\n [[ -d \"$STATE\" && ! -L \"$STATE\" && \"$(stat -c '%u' \"$STATE\")\" == 0 ]] || fail \"Invalid cloud service state directory\"\\n${bodies.join(\"\")}\\n}\\n`;\n};\n","import { createHash } from \"node:crypto\";\n\nimport type { resolveCloudToolchains } from \"./cloud-setup-toolchains\";\n\nexport const cloudShellProfilePath = \"/etc/profile.d/stll-cloud.sh\";\nexport const cloudShellProfileSource = `. ${cloudShellProfilePath}`;\n\nconst quote = (value: string) => `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\ntype CloudShellOptions = {\n nodeVersion: string;\n bunVersion: string;\n rust: ReturnType<typeof resolveCloudToolchains>[\"rust\"];\n};\n\nexport const renderCloudShellProfile = ({\n nodeVersion,\n bunVersion,\n rust,\n}: CloudShellOptions) => {\n const node = `/opt/stll-cloud/node/${nodeVersion}/bin`;\n const bun = `/opt/stll-cloud/bun/${bunVersion}`;\n return `# Generated by stll-cloud-setup; managed cloud shell environment.\n# Remove managed entries before prepending, including repeated shell startup.\n_stll_cloud_remaining=\"\\${PATH-}\"\n_stll_cloud_result=''\n_stll_cloud_separator=''\nwhile :; do\n case \"$_stll_cloud_remaining\" in\n *:*) _stll_cloud_part=\"\\${_stll_cloud_remaining%%:*}\"; _stll_cloud_remaining=\"\\${_stll_cloud_remaining#*:}\"; _stll_cloud_more=yes ;;\n *) _stll_cloud_part=\"$_stll_cloud_remaining\"; _stll_cloud_more=no ;;\n esac\n case \"$_stll_cloud_part\" in\n ${quote(node)}|${quote(bun)}|/usr/local/bin) ;;\n *) _stll_cloud_result=\"$_stll_cloud_result$_stll_cloud_separator$_stll_cloud_part\"; _stll_cloud_separator=: ;;\n esac\n [ \"$_stll_cloud_more\" = yes ] || break\ndone\nexport PATH=${quote(`${node}:${bun}:/usr/local/bin`)}\"\\${_stll_cloud_separator:+:}$_stll_cloud_result\"\nunset _stll_cloud_remaining _stll_cloud_result _stll_cloud_separator _stll_cloud_part _stll_cloud_more\n${rust === undefined ? \"\" : `export RUSTUP_HOME=/opt/stll-cloud/rustup\\nexport CARGO_HOME=/opt/stll-cloud/cargo\\nexport RUSTUP_TOOLCHAIN=${quote(rust.channel)}\\nexport RUSTUP_AUTO_INSTALL=0\\n`}`;\n};\n\nconst userStartup = String.raw`\nset -euo pipefail\nfor name in .bashrc .profile .bash_profile .bash_login; do\n file=\"$HOME/$name\"\n if [[ ! -e \"$file\" && ! -L \"$file\" && \"$name\" != .bashrc && \"$name\" != .profile ]]; then continue; fi\n [[ ! -L \"$file\" ]] || { echo \"cloud-setup: shell startup file must not be a symlink: $name\" >&2; exit 1; }\n if [[ -e \"$file\" ]]; then\n [[ -f \"$file\" && \"$(stat -c '%h:%u' \"$file\")\" == \"1:$(id -u)\" ]] || { echo \"cloud-setup: shell startup file must be owned and single-link: $name\" >&2; exit 1; }\n fi\n temporary=\"$(mktemp \"$HOME/.stll-cloud-shell.XXXXXX\")\"\n trap 'rm -f -- \"$temporary\"' EXIT\n if [[ \"$name\" == .bashrc ]]; then\n printf '%s\\n' '# stll-cloud: early environment' '@SOURCE@' > \"$temporary\"\n fi\n if [[ -f \"$file\" ]]; then\n # Remove only exact managed blocks; preserve unrelated startup lines and permissions.\n awk '\n $0 == \"# stll-cloud: early environment\" || $0 == \"# stll-cloud: session environment\" {\n if ((getline following) <= 0 || following != \"@SOURCE@\") exit 1\n next\n }\n { print }\n ' \"$file\" >> \"$temporary\" || { echo \"cloud-setup: managed shell startup block differs: $name\" >&2; exit 1; }\n fi\n printf '%s\\n' '# stll-cloud: session environment' '@SOURCE@' >> \"$temporary\"\n if [[ -f \"$file\" ]] && cmp -s \"$temporary\" \"$file\"; then rm -- \"$temporary\"; continue; fi\n if [[ -f \"$file\" ]]; then chmod --reference=\"$file\" \"$temporary\"; else chmod 644 \"$temporary\"; fi\n mv -f -- \"$temporary\" \"$file\"\ndone\n`;\n\nexport const renderCloudShellInstall = (options: CloudShellOptions) => {\n const profile = renderCloudShellProfile(options);\n return `install_shell_environment() (\n # Subshell scope retains temporary for EXIT cleanup after a failed command.\n [[ ! -L ${quote(cloudShellProfilePath)} ]] || fail 'Managed shell profile must not be a symlink'\n if [[ -e ${quote(cloudShellProfilePath)} ]]; then\n [[ -f ${quote(cloudShellProfilePath)} && \"$(stat -c '%h:%u' ${quote(cloudShellProfilePath)})\" == 1:0 ]] || fail 'Managed shell profile must be a root-owned single-link file'\n fi\n temporary=\"$(mktemp)\"\n trap 'rm -f -- \"$temporary\"' EXIT\n cat > \"$temporary\" <<'STLL_CLOUD_PROFILE'\n${profile}STLL_CLOUD_PROFILE\n if ! cmp -s \"$temporary\" ${quote(cloudShellProfilePath)}; then install -m 644 \"$temporary\" ${quote(cloudShellProfilePath)}; fi\n runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" bash -c ${quote(userStartup.replaceAll(\"@SOURCE@\", cloudShellProfileSource))}\n)\nverify_shell_environment() {\n [[ -f ${quote(cloudShellProfilePath)} && ! -L ${quote(cloudShellProfilePath)} && \"$(stat -c '%h:%u' ${quote(cloudShellProfilePath)})\" == 1:0 ]] || fail 'Managed shell environment is unavailable; run install'\n [[ \"$(sha256sum -- ${quote(cloudShellProfilePath)} | cut -d ' ' -f1)\" == ${quote(createHash(\"sha256\").update(profile).digest(\"hex\"))} ]] || fail 'Managed shell environment differs; run install'\n}\n`;\n};\n","import { parse as parseToml } from \"smol-toml\";\n\nimport {\n cloudSetupArtifacts,\n getCloudSetupArtifact,\n getCloudSetupPackage,\n} from \"./cloud-setup-artifacts\";\nimport {\n type CloudExtraTool,\n cloudExtraTools,\n isCloudPackageTool,\n parseCloudRustNames,\n} from \"./cloud-setup-schema\";\nimport type { parseCloudSetup } from \"./cloud-setup-schema\";\nimport type { RustException } from \"./toolchain-rust\";\n\ntype ResolveCloudToolchainsOptions = {\n cloud: NonNullable<ReturnType<typeof parseCloudSetup>>;\n files: Readonly<Record<string, string>>;\n rust: string;\n rustExceptions: readonly RustException[];\n};\nconst record = (input: unknown): input is Record<string, unknown> =>\n typeof input === \"object\" && input !== null && !Array.isArray(input);\n/** Resolve the same tracked snapshot for generation and the mandatory drift check. */\nexport const resolveCloudToolchains = ({\n cloud,\n files,\n rust,\n rustExceptions,\n}: ResolveCloudToolchainsOptions) => {\n const source = files[\"rust-toolchain.toml\"];\n const selector = files[\"rust-toolchain\"];\n if (source !== undefined && selector !== undefined)\n throw new Error(\n \"cloud Rust requires one root rust-toolchain.toml or rust-toolchain file\",\n );\n let declared: Record<string, unknown> | undefined;\n if (source !== undefined || selector?.trimStart().startsWith(\"[\")) {\n const parsed = parseToml(source ?? selector ?? \"\");\n if (!record(parsed[\"toolchain\"]))\n throw new Error(\"cloud Rust requires [toolchain]\");\n declared = parsed[\"toolchain\"];\n if (\n Object.keys(declared).some(\n (key) => ![\"channel\", \"components\", \"targets\", \"profile\"].includes(key),\n )\n )\n throw new Error(\n \"cloud Rust supports only channel, components, targets and profile\",\n );\n if (declared[\"profile\"] !== undefined && declared[\"profile\"] !== \"minimal\")\n throw new Error(\n \"cloud Rust requires profile = minimal; declare required components explicitly\",\n );\n } else if (selector !== undefined) declared = { channel: selector.trim() };\n const rustEnabled = declared !== undefined || cloud.rust !== undefined;\n const channel =\n declared === undefined\n ? (cloud.rust?.toolchain ?? rust)\n : declared[\"channel\"];\n if (rustEnabled) {\n if (typeof channel !== \"string\" || !/^\\d+\\.\\d+\\.\\d+$/.test(channel))\n throw new Error(\"cloud Rust requires an exact stable toolchain\");\n if (channel !== rust && !rustExceptions.some(({ pin }) => pin === channel))\n throw new Error(\n `cloud Rust must use shared Rust ${rust} or a recorded rustExceptions pin`,\n );\n if (cloud.rust?.toolchain !== undefined && cloud.rust.toolchain !== channel)\n throw new Error(\n \"cloud.rust.toolchain conflicts with root Rust toolchain\",\n );\n }\n // Authorization permits a version; cloud provisioning selects extras explicitly.\n const additionalToolchains = cloud.rust?.additionalToolchains ?? [];\n for (const pin of additionalToolchains) {\n if (pin === channel)\n throw new Error(\n \"cloud.rust.additionalToolchains must not repeat the primary toolchain\",\n );\n if (\n pin !== rust &&\n !rustExceptions.some(({ pin: authorized }) => authorized === pin)\n )\n throw new Error(\n `cloud.rust.additionalToolchains ${pin} requires an authorized rustExceptions pin`,\n );\n }\n const components = [\n ...new Set([\n ...parseCloudRustNames(declared?.[\"components\"], \"components\"),\n ...(cloud.rust?.components ?? []),\n ]),\n ].sort();\n const targets = [\n ...new Set([\n ...parseCloudRustNames(declared?.[\"targets\"], \"targets\"),\n ...(cloud.rust?.targets ?? []),\n ]),\n ].sort();\n const resolveTool = (tool: CloudExtraTool, version: string) => {\n if (isCloudPackageTool(tool))\n return {\n type: \"package\",\n tool,\n release: getCloudSetupPackage(tool, version),\n } as const;\n if (tool === \"cargo-nextest\" && !rustEnabled)\n throw new Error(\"cloud.tools.cargo-nextest requires a Rust toolchain\");\n if (tool === \"wasm-bindgen-cli\") {\n const lock = files[\"Cargo.lock\"];\n if (lock === undefined)\n throw new Error(\"wasm-bindgen-cli requires tracked root Cargo.lock\");\n const packages = parseToml(lock)[\"package\"];\n if (!Array.isArray(packages))\n throw new Error(\n \"Cargo.lock requires package entries for wasm-bindgen-cli\",\n );\n const versions = new Set(\n packages.flatMap((entry: unknown) =>\n record(entry) && entry[\"name\"] === \"wasm-bindgen\"\n ? [entry[\"version\"]]\n : [],\n ),\n );\n if (versions.size !== 1 || !versions.has(version))\n throw new Error(\n `cloud.tools.wasm-bindgen-cli ${version} must equal the unique wasm-bindgen crate version in Cargo.lock (found ${[...versions].join(\", \") || \"none\"})`,\n );\n }\n return {\n type: \"artifact\",\n tool,\n release: getCloudSetupArtifact(tool, version),\n } as const;\n };\n const tools = cloudExtraTools.flatMap((tool) => {\n const version = cloud.tools?.[tool];\n return version === undefined ? [] : [resolveTool(tool, version)];\n });\n return {\n rust:\n rustEnabled && typeof channel === \"string\"\n ? {\n channel,\n additionalToolchains: [...additionalToolchains].sort(),\n components,\n targets,\n installer: cloudSetupArtifacts[\"rustup-init\"],\n }\n : undefined,\n tools,\n };\n};\n","import type { getCloudSetupArtifact } from \"./cloud-setup-artifacts\";\nimport { cloudRustComponentBinaries } from \"./cloud-setup-schema\";\nimport type { resolveCloudToolchains } from \"./cloud-setup-toolchains\";\n\nconst quote = (value: string) => `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\ntype ArtifactRelease = ReturnType<typeof getCloudSetupArtifact>;\nconst artifactSelection = (release: ArtifactRelease) => `case \"$ARCH\" in\n${([\"amd64\", \"arm64\"] as const).map((arch) => ` ${arch}) artifact_url=${quote(release[arch].url)}; artifact_sha=${quote(release[arch].sha256)} ;;`).join(\"\\n\")}\nesac`;\n\nconst helpers = String.raw`\nfetch_verified() {\n download_file \"$1\" \"$3\" 120\n printf '%s %s\\n' \"$2\" \"$3\" | sha256sum --strict -c - >/dev/null\n}\n`;\n\nconst rustInstall = (\n rust: NonNullable<ReturnType<typeof resolveCloudToolchains>[\"rust\"]>,\n) => {\n const args = [\n ...rust.components.flatMap((name) => [\"--component\", name]),\n ...rust.targets.flatMap((name) => [\"--target\", name]),\n ]\n .map(quote)\n .join(\" \");\n return String.raw`\nexport RUSTUP_HOME=/opt/stll-cloud/rustup\nexport CARGO_HOME=/opt/stll-cloud/cargo\nexport RUSTUP_TOOLCHAIN='@RUST@'\nexport RUSTUP_AUTO_INSTALL=0\nrust_run() {\n local mode=\"$1\"\n shift\n set -- runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" RUSTUP_HOME=\"$RUSTUP_HOME\" CARGO_HOME=\"$CARGO_HOME\" RUSTUP_AUTO_INSTALL=0 RUSTUP_TOOLCHAIN=@RUST@ RUSTUP_DIST_SERVER=https://static.rust-lang.org RUSTUP_UPDATE_ROOT=https://static.rust-lang.org/rustup PATH=\"$PATH\" \"$@\"\n case \"$mode\" in\n local) \"$@\" ;;\n network) network_run static.rust-lang.org 180 \"$@\" ;;\n *) fail 'Invalid Rust execution mode' ;;\n esac\n}\nprimary_rust_ready() {\n local directory\n for directory in \"$RUSTUP_HOME\" \"$CARGO_HOME\"; do\n [[ -d \"$directory\" && ! -L \"$directory\" && \"$(stat -c '%u' \"$directory\")\" == \"$OUTPUT_UID\" ]] || return 1\n done\n [[ -x \"$CARGO_HOME/bin/rustup\" ]] || return 1\n [[ \"$(rust_run local \"$CARGO_HOME/bin/rustup\" --version 2>/dev/null)\" == 'rustup @RUSTUP@ '* ]] || return 1\n [[ \"$(rust_run local \"$CARGO_HOME/bin/rustc\" +@RUST@ --version)\" == 'rustc @RUST@ '* ]] || return 1\n local host\n host=\"$(rust_run local \"$CARGO_HOME/bin/rustc\" +@RUST@ -vV | awk '$1 == \"host:\" { print $2 }')\" || return 1\n @VERIFY_COMPONENTS@\n @VERIFY_TARGETS@\n return 0\n}\nrust_ready() {\n local additional_version\n primary_rust_ready || return 1\n @VERIFY_ADDITIONAL_TOOLCHAINS@\n return 0\n}\nverify_rust() { rust_ready || fail 'Pinned Rust, components or targets are unavailable; run install'; }\ninstall_rust() (\n if ! command -v cc >/dev/null || ! command -v ld >/dev/null || [[ ! -f /usr/include/stdlib.h ]]; then\n apt_refresh_for build-essential\n apt_install build-essential\n fi\n local artifact_url artifact_sha additional_version\n # Subshell scope retains scratch for EXIT cleanup after a failed command.\n scratch=\"$(mktemp -d)\"\n trap 'rm -rf -- \"$scratch\"' EXIT\n for directory in \"$RUSTUP_HOME\" \"$CARGO_HOME\"; do\n [[ ! -L \"$directory\" ]] || fail 'Rust home must not be a symlink'\n if [[ -e \"$directory\" ]]; then\n [[ -d \"$directory\" && \"$(stat -c '%u' \"$directory\")\" == \"$OUTPUT_UID\" ]] || fail 'Rust home ownership differs from the invoking user'\n else\n install -d -m 755 -o \"$OUTPUT_UID\" -g \"$OUTPUT_GID\" \"$directory\"\n fi\n done\n if [[ ! -x \"$CARGO_HOME/bin/rustup\" ]] || [[ \"$(rust_run local \"$CARGO_HOME/bin/rustup\" --version 2>/dev/null)\" != 'rustup @RUSTUP@ '* ]]; then\n @RUSTUP_ARTIFACT@\n fetch_verified \"$artifact_url\" \"$artifact_sha\" \"$scratch/rustup-init\"\n chmod 755 \"$scratch\" \"$scratch/rustup-init\"\n rust_run network \"$scratch/rustup-init\" -y --no-modify-path --default-toolchain none --profile minimal\n fi\n rust_run local \"$CARGO_HOME/bin/rustup\" set auto-self-update disable\n if ! primary_rust_ready; then\n rust_run network \"$CARGO_HOME/bin/rustup\" toolchain install @RUST@ --profile minimal --no-self-update @RUST_ARGS@\n fi\n @INSTALL_ADDITIONAL_TOOLCHAINS@\n rust_run local \"$CARGO_HOME/bin/rustup\" default @RUST@\n verify_rust\n for tool in rustup cargo rustc rustdoc @RUST_PROXIES@; do\n # Launchers persist the system homes in fresh shells without profile sourcing.\n printf '%s\\n' '#!/bin/sh' 'export RUSTUP_HOME=/opt/stll-cloud/rustup' 'export CARGO_HOME=/opt/stll-cloud/cargo' 'export RUSTUP_AUTO_INSTALL=0' 'export RUSTUP_TOOLCHAIN=@RUST@' \"exec /opt/stll-cloud/cargo/bin/$tool \\\"\\$@\\\"\" > \"$scratch/$tool\"\n if ! cmp -s \"$scratch/$tool\" \"/usr/local/bin/$tool\"; then\n install -m 755 \"$scratch/$tool\" \"/usr/local/bin/$tool\"\n fi\n done\n)\n`\n .replace(\n \"@VERIFY_ADDITIONAL_TOOLCHAINS@\",\n rust.additionalToolchains\n .map(\n (pin) =>\n `additional_version=\"$(rust_run local \"$CARGO_HOME/bin/rustc\" +${pin} --version)\" || return 1\\n [[ \"$additional_version\" == 'rustc ${pin} '* ]] || return 1`,\n )\n .join(\"\\n \"),\n )\n .replace(\n \"@INSTALL_ADDITIONAL_TOOLCHAINS@\",\n rust.additionalToolchains\n .map(\n (pin) =>\n `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`,\n )\n .join(\"\\n \"),\n )\n .replaceAll(\"@RUSTUP@\", rust.installer.version)\n .replaceAll(\"@RUST@\", rust.channel)\n .replace(\"@RUSTUP_ARTIFACT@\", artifactSelection(rust.installer))\n .replace(\"@RUST_ARGS@\", args)\n .replace(\n \"@RUST_PROXIES@\",\n Object.entries(cloudRustComponentBinaries)\n .flatMap(([component, binaries]) =>\n rust.components.includes(component) ? Array.from(binaries) : [],\n )\n .join(\" \"),\n )\n .replace(\n \"@VERIFY_COMPONENTS@\",\n rust.components\n .map(\n (name) =>\n `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`,\n )\n .join(\"\\n \"),\n )\n .replace(\n \"@VERIFY_TARGETS@\",\n rust.targets\n .map(\n (name) =>\n `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`,\n )\n .join(\"\\n \"),\n );\n};\n\ntype CloudToolEntry = ReturnType<\n typeof resolveCloudToolchains\n>[\"tools\"][number];\n\n// Present packages are reused; apt never downgrades or replaces them.\nconst packageToolInstall = ({\n tool,\n release,\n}: Extract<CloudToolEntry, { type: \"package\" }>) => {\n const name = tool.replaceAll(\"-\", \"_\");\n return {\n name,\n text: `verify_${name}() {\n [[ -x ${quote(release.binary)} && \"$(${quote(release.binary)} --version 2>/dev/null)\" == ${quote(release.identity)}* ]] || return 1\n [[ \"$(dpkg-query -W -f='\\${Version}' ${quote(release.package)} 2>/dev/null)\" == ${quote(`${release.version}-`)}* ]]\n}\ninstall_${name}() {\n if ! verify_${name}; then\n apt_network update\n apt_install ${quote(release.package)}\n verify_${name} || fail ${quote(`Installed ${tool} version differs from its pin`)}\n fi\n}\n`,\n };\n};\n\nconst artifactToolInstall = ({\n tool,\n release,\n}: Extract<CloudToolEntry, { type: \"artifact\" }>) => {\n const directory = `/opt/stll-cloud/tools/${tool}/${release.version}`;\n const command = tool === \"wasm-bindgen-cli\" ? \"wasm-bindgen\" : tool;\n const versionPrefix = tool === \"gitleaks\" ? \"gitleaks version\" : command;\n const marker = `${versionPrefix} ${release.version}`;\n return {\n name: tool.replaceAll(\"-\", \"_\"),\n text: `verify_${tool.replaceAll(\"-\", \"_\")}() {\n ${Object.keys(release.amd64.binaries)\n .map((binary) => `[[ -x ${quote(`${directory}/${binary}`)} ]] || return 1`)\n .join(\"\\n \")}\n [[ \"$( ${quote(`${directory}/${command}`)} --version)\" == ${quote(marker)} || \"$( ${quote(`${directory}/${command}`)} --version)\" == ${quote(`${marker} `)}* ]]\n}\ninstall_${tool.replaceAll(\"-\", \"_\")}() (\n local artifact_url artifact_sha\n # Subshell scope retains scratch for EXIT cleanup after a failed command.\n if ! verify_${tool.replaceAll(\"-\", \"_\")}; then\n scratch=\"$(mktemp -d)\"\n trap 'rm -rf -- \"$scratch\"' EXIT\n ${artifactSelection(release)}\n fetch_verified \"$artifact_url\" \"$artifact_sha\" \"$scratch/archive.tar.gz\"\n tar -xzf \"$scratch/archive.tar.gz\" -C \"$scratch\"\n install -d -m 755 ${quote(directory)}\n case \"$ARCH\" in\n${([\"amd64\", \"arm64\"] as const)\n .map(\n (arch) =>\n ` ${arch})\\n${Object.entries(release[arch].binaries)\n .map(\n ([binary, path]) =>\n ` install -m 755 \"$scratch/${path}\" ${quote(`${directory}/${binary}`)}`,\n )\n .join(\"\\n\")}\\n ;;`,\n )\n .join(\"\\n\")}\n esac\n verify_${tool.replaceAll(\"-\", \"_\")} || fail ${quote(`Installed ${tool} version differs from its pin`)}\n fi\n${Object.keys(release.amd64.binaries)\n .map(\n (binary) =>\n ` ln -sfnT -- ${quote(`${directory}/${binary}`)} ${quote(`/usr/local/bin/${binary}`)}`,\n )\n .join(\"\\n\")}\n)\n`,\n };\n};\n\nexport const renderCloudToolInstall = ({\n rust,\n tools,\n}: ReturnType<typeof resolveCloudToolchains>) => {\n const installs = tools.map((entry) => {\n switch (entry.type) {\n case \"package\":\n return packageToolInstall(entry);\n case \"artifact\":\n return artifactToolInstall(entry);\n default: {\n const exhaustive: never = entry;\n throw new Error(`Unsupported cloud tool: ${String(exhaustive)}`);\n }\n }\n });\n return `${helpers}${rust === undefined ? \"\" : rustInstall(rust)}\\n${installs.map(({ text }) => text).join(\"\\n\")}\ninstall_tools() {\n ${rust === undefined ? \":\" : \"install_rust\"}\n ${installs.map(({ name }) => `install_${name}`).join(\"\\n \")}\n}\nverify_tools() {\n ${rust === undefined ? \":\" : \"verify_rust\"}\n ${installs.map(({ name }) => `verify_${name} || fail 'Pinned ${name} is unavailable; run install'`).join(\"\\n \")}\n}\n`;\n};\n","import { subset, validRange } from \"semver\";\n\nconst numericComponent = \"(?:0|[1-9]\\\\d*)\";\nconst policyPattern = new RegExp(`^${numericComponent}\\\\.x$`);\nconst selectorPattern = new RegExp(\n `^(${numericComponent})(?:\\\\.(?:x|${numericComponent}(?:\\\\.${numericComponent})?))?$`,\n);\n\n/** A Node policy selects the complete stable release series of one major. */\nexport const nodePolicyValid = (value: string) =>\n policyPattern.test(value) && validRange(value) !== null;\n\n/** Static selectors may narrow that series, but cannot float across majors. */\nexport const nodeSelectorMatches = (value: unknown, policy: string) => {\n if (!nodePolicyValid(policy) || typeof value !== \"string\") return false;\n const major = selectorPattern.exec(value)?.[1];\n return (\n major !== undefined &&\n major === policy.slice(0, -2) &&\n validRange(value) !== null\n );\n};\n\n/** Engines must support every stable release in the approved major series. */\nexport const nodeSupportRangeMatches = (policy: string, range: string) => {\n if (!nodePolicyValid(policy)) return false;\n try {\n return subset(policy, range);\n } catch {\n return false;\n }\n};\n","import { createHash } from \"node:crypto\";\nimport { valid } from \"semver\";\n\nimport { renderCloudServiceInstall } from \"./cloud-setup-install\";\nimport { renderCloudNetwork } from \"./cloud-setup-network\";\nimport { cloudServices, parseCloudSetup } from \"./cloud-setup-schema\";\nimport { renderCloudServiceStart } from \"./cloud-setup-services\";\nimport { renderCloudShellInstall } from \"./cloud-setup-shell\";\nimport { resolveCloudToolchains } from \"./cloud-setup-toolchains\";\nimport { renderCloudToolInstall } from \"./cloud-setup-tools-install\";\nimport { nodeSelectorMatches } from \"./toolchain-node\";\nimport type { RustException } from \"./toolchain-rust\";\nimport type { parseToolchainPolicy } from \"./toolchain-schema\";\n\nexport const cloudSetupPath = \".agents/cloud-setup.sh\";\nexport const cloudEnvironmentMarker =\n \"# Generated by stll-cloud-setup; disposable local test services.\";\n\ntype GenerateCloudSetupOptions = {\n policy: ReturnType<typeof parseToolchainPolicy>;\n cloud: NonNullable<ReturnType<typeof parseCloudSetup>>;\n nodeVersion: string;\n files?: Readonly<Record<string, string>>;\n rustExceptions?: readonly RustException[];\n};\n\nconst script = String.raw`#!/usr/bin/env bash\n# Generated by stll-cloud-setup. Regenerate with stll-cloud-setup.\n# Networked installation and offline service startup are separate lifecycle steps.\n# Cached filesystems may not preserve processes; run start at every session start.\n# Supported platform: Ubuntu 24.04 (noble), amd64/arm64, root or passwordless sudo.\nset -euo pipefail\n\nusage() { echo 'Usage: cloud-setup.sh install|start|session' >&2; exit 2; }\n[[ \"$#\" == 1 ]] || usage\ncase \"$1\" in install|start|session) MODE=\"$1\" ;; *) usage ;; esac\nfail() { echo \"cloud-setup: $*\" >&2; exit 1; }\ntrap 'echo \"cloud-setup: command failed at line $LINENO\" >&2' ERR\n# Each phase logs its start and duration so a stalled phase is visible in the task log.\nstep() {\n local name=\"$1\" started=\"$SECONDS\"\n shift\n echo \"cloud-setup: $name started\" >&2\n \"$@\"\n echo \"cloud-setup: $name done in $((SECONDS - started))s\" >&2\n}\n[[ -f /etc/os-release ]] || fail 'Ubuntu 24.04 is required'\n. /etc/os-release\n[[ \"$ID\" == ubuntu && \"$VERSION_ID\" == 24.04 && \"$VERSION_CODENAME\" == noble ]] || fail 'Only Ubuntu 24.04 (noble) is supported'\nSCRIPT=\"$(realpath -- \"$0\")\"\nREPO_ROOT=\"$(cd -- \"$(dirname -- \"$SCRIPT\")/..\" && pwd -P)\"\n[[ \"$SCRIPT\" == \"$REPO_ROOT/.agents/cloud-setup.sh\" ]] || fail 'Run the generated repository script'\nif [[ \"$(id -u)\" != 0 ]]; then\n command -v sudo >/dev/null && sudo -n true || fail 'Root or passwordless sudo is required'\n exec sudo -n -- bash \"$SCRIPT\" \"$MODE\"\nfi\nOUTPUT_UID=\"$(printenv SUDO_UID || id -u)\"\n[[ \"$OUTPUT_UID\" =~ ^[0-9]+$ ]] || fail 'Invalid invoking user'\nOUTPUT_GID=\"$(getent passwd \"$OUTPUT_UID\" | cut -d: -f4)\"\n[[ \"$OUTPUT_GID\" =~ ^[0-9]+$ ]] || fail 'Invoking user is unavailable'\nOUTPUT_USER=\"$(getent passwd \"$OUTPUT_UID\" | cut -d: -f1)\"\nOUTPUT_HOME=\"$(getent passwd \"$OUTPUT_UID\" | cut -d: -f6)\"\n[[ -n \"$OUTPUT_USER\" && \"$OUTPUT_HOME\" == /* && -d \"$OUTPUT_HOME\" ]] || fail 'Invoking user requires an existing home directory'\nroot() { \"$@\"; }\n# Service daemons outlive setup, so they inherit no descriptor beyond stdio: a cloud\n# runner can pass its terminal as extra descriptors and wait until every copy closes.\nservice_run() (\n for descriptor in \"/proc/$BASHPID/fd/\"*; do\n descriptor=\"$(basename -- \"$descriptor\")\"\n if [[ \"$descriptor\" =~ ^[0-9]+$ ]] && (( descriptor > 2 )); then eval \"exec $descriptor>&-\"; fi\n done\n exec runuser -u stll-cloud -- \"$@\"\n)\nBUN_VERSION='@BUN@'\nNODE_VERSION='@NODE@'\nNODE_DIR=\"/opt/stll-cloud/node/$NODE_VERSION\"\nBUN_DIR=\"/opt/stll-cloud/bun/$BUN_VERSION\"\nexport PATH=\"$NODE_DIR/bin:$BUN_DIR:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"\nBUN_CACHE=\"/var/cache/stll-cloud/bun/$OUTPUT_UID\"\n@ENV_ASSIGNMENTS@\n[[ -f \"$REPO_ROOT/.node-version\" && ! -L \"$REPO_ROOT/.node-version\" ]] || fail 'A regular root .node-version is required'\n[[ \"$(awk 'NF { if (++count > 1 || NF != 1) exit 1; value=$1 } END { if (count != 1) exit 1; print value }' \"$REPO_ROOT/.node-version\")\" == \"$NODE_VERSION\" ]] || fail 'Node selector changed; regenerate cloud-setup.sh'\ncd -- \"$REPO_ROOT\"\ncase \"$(uname -m)\" in\n x86_64) ARCH=amd64; NODE_ARCH=x64; BUN_ARCH=x64 ;;\n aarch64|arm64) ARCH=arm64; NODE_ARCH=arm64; BUN_ARCH=aarch64 ;;\n *) fail 'Only amd64 and arm64 are supported' ;;\nesac\n\n@NETWORK@\n\nnode_ready() {\n local node_version npm_version npx_version\n [[ -x \"$NODE_DIR/bin/node\" && -x \"$NODE_DIR/bin/npm\" && -x \"$NODE_DIR/bin/npx\" ]] || return 1\n node_version=\"$(\"$NODE_DIR/bin/node\" --version)\" || return 1\n [[ \"$node_version\" == \"v$NODE_VERSION\" ]] || return 1\n npm_version=\"$(\"$NODE_DIR/bin/npm\" --version)\" || return 1\n [[ \"$npm_version\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]] || return 1\n npx_version=\"$(\"$NODE_DIR/bin/npx\" --version)\" || return 1\n [[ \"$npx_version\" == \"$npm_version\" ]] || return 1\n}\nruntime_ready() {\n node_ready || fail 'Pinned Node, npm or npx is unavailable; run install'\n [[ -x \"$BUN_DIR/bun\" && \"$($BUN_DIR/bun --version)\" == \"$BUN_VERSION\" ]] || fail 'Pinned Bun is unavailable; run install'\n}\nbun_route() {\n local label=\"$1\" resolved version\n shift\n resolved=\"$(\"$@\" -c 'command -v bun')\" || fail \"Bun is unavailable through $label\"\n version=\"$(\"$@\" -c 'bun --version')\" || fail \"Bun at $resolved failed through $label\"\n [[ \"$version\" == \"$BUN_VERSION\" ]] || fail \"Bun at $resolved resolves version $version through $label; expected $BUN_VERSION\"\n}\nverify_bun_routes() {\n local configured_mise login_shell minimal_path mise_root root_mise shims\n # Test-only overrides keep route executables and image locations inside fixtures.\n login_shell=\"$(printenv STLL_CLOUD_TEST_LOGIN_SHELL || true)\"\n [[ -n \"$login_shell\" ]] || login_shell=bash\n minimal_path=\"$(printenv STLL_CLOUD_TEST_MINIMAL_PATH || true)\"\n [[ -n \"$minimal_path\" ]] || minimal_path=/usr/local/bin:/usr/bin:/bin\n root_mise=\"$(printenv STLL_CLOUD_TEST_ROOT_MISE || true)\"\n [[ -n \"$root_mise\" ]] || root_mise=/root/.local/share/mise\n # An absolute shell: a PATH entry such as a user-writable mise shims\n # directory must never supply the program that root runs.\n bun_route 'the setup PATH' env PATH=\"$PATH\" /bin/sh\n bun_route 'sh -c' /bin/sh\n bun_route 'bash -lc' \"$login_shell\" -l\n bun_route 'the minimal system PATH' env -i PATH=\"$minimal_path\" /bin/sh\n configured_mise=\"$(printenv MISE_DATA_DIR || true)\"\n for mise_root in \"$configured_mise\" \"$OUTPUT_HOME/.local/share/mise\" \"$root_mise\"; do\n [[ -n \"$mise_root\" ]] || continue\n shims=\"$mise_root/shims\"\n [[ -d \"$shims\" ]] || continue\n bun_route \"mise shims PATH $shims\" env PATH=\"$shims:$PATH\" /bin/sh\n done\n}\nreplace_image_buns() {\n local candidate configured_mise directory mise_root root_mise\n configured_mise=\"$(printenv MISE_DATA_DIR || true)\"\n root_mise=\"$(printenv STLL_CLOUD_TEST_ROOT_MISE || true)\"\n [[ -n \"$root_mise\" ]] || root_mise=/root/.local/share/mise\n for mise_root in \"$configured_mise\" \"$OUTPUT_HOME/.local/share/mise\" \"$root_mise\"; do\n [[ -n \"$mise_root\" ]] || continue\n if [[ -d \"$mise_root/installs/bun\" ]]; then\n while IFS= read -r -d '' candidate; do\n [[ -d \"$candidate\" ]] || ln -sfnT -- \"$BUN_DIR/bun\" \"$candidate\"\n done < <(find \"$mise_root/installs/bun\" \\( -type f -o -type l \\) \\( -name bun -o -name bunx \\) -print0)\n fi\n for candidate in \"$mise_root/shims/bun\" \"$mise_root/shims/bunx\"; do\n [[ -e \"$candidate\" || -L \"$candidate\" ]] || continue\n [[ -d \"$candidate\" ]] || ln -sfnT -- \"$BUN_DIR/bun\" \"$candidate\"\n done\n done\n while IFS= read -r directory; do\n [[ -n \"$directory\" ]] || directory=.\n for candidate in \"$directory/bun\" \"$directory/bunx\"; do\n [[ -e \"$candidate\" || -L \"$candidate\" ]] || continue\n [[ -d \"$candidate\" ]] && continue\n [[ \"$(readlink -f -- \"$candidate\")\" == \"$(readlink -f -- \"$BUN_DIR/bun\")\" ]] || ln -sfnT -- \"$BUN_DIR/bun\" \"$candidate\"\n done\n # The trailing newline lets read return the last PATH entry too.\n done < <(printf '%s\\n' \"$PATH\" | tr : '\\n')\n}\ninstall_runtimes() (\n if [[ ! -s /etc/ssl/certs/ca-certificates.crt ]]; then\n command -v update-ca-certificates >/dev/null || fail 'System CA certificate bundle is missing; restore ca-certificates in the base image offline before install'\n update-ca-certificates || fail 'System CA certificate bundle could not be repaired offline; restore ca-certificates in the base image before install'\n fi\n [[ -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'\n 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\n apt_refresh_for ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1\n DEBIAN_FRONTEND=noninteractive apt_install ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1\n fi\n local node_archive bun_archive bun_folder\n # Subshell scope retains scratch for EXIT cleanup after a failed command.\n scratch=\"$(mktemp -d)\"\n trap 'rm -rf -- \"$scratch\"' EXIT\n if ! node_ready; then\n node_archive=\"node-v$NODE_VERSION-linux-$NODE_ARCH.tar.xz\"\n download_file \"https://nodejs.org/dist/v$NODE_VERSION/$node_archive\" \"$scratch/$node_archive\" 120\n download_file \"https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt\" \"$scratch/node-sums\" 45\n (cd \"$scratch\"; awk -v name=\"$node_archive\" '$2 == name { print; count++ } END { if (count != 1) exit 1 }' node-sums | sha256sum --strict -c -)\n install -d -m 755 \"$NODE_DIR\"\n tar -xJf \"$scratch/$node_archive\" --strip-components=1 -C \"$NODE_DIR\"\n fi\n if [[ ! -x \"$BUN_DIR/bun\" ]] || [[ \"$($BUN_DIR/bun --version)\" != \"$BUN_VERSION\" ]]; then\n bun_folder=\"bun-linux-$BUN_ARCH\"\n bun_archive=\"$bun_folder.zip\"\n download_file \"https://github.com/oven-sh/bun/releases/download/bun-v$BUN_VERSION/$bun_archive\" \"$scratch/$bun_archive\" 120\n download_file \"https://github.com/oven-sh/bun/releases/download/bun-v$BUN_VERSION/SHASUMS256.txt\" \"$scratch/bun-sums\" 45\n (cd \"$scratch\"; awk -v name=\"$bun_archive\" '$2 == name || $2 == \"*\" name { print $1 \" \" name; count++ } END { if (count != 1) exit 1 }' bun-sums | sha256sum --strict -c -)\n unzip -q \"$scratch/$bun_archive\" -d \"$scratch/bun\"\n install -d -m 755 \"$BUN_DIR\"\n install -m 755 \"$scratch/bun/$bun_folder/bun\" \"$BUN_DIR/bun\"\n fi\n runtime_ready\n ln -sfnT -- \"$NODE_DIR/bin/node\" /usr/local/bin/node\n ln -sfnT -- \"$NODE_DIR/bin/npm\" /usr/local/bin/npm\n ln -sfnT -- \"$NODE_DIR/bin/npx\" /usr/local/bin/npx\n ln -sfnT -- \"$BUN_DIR/bun\" /usr/local/bin/bun\n replace_image_buns\n)\n\ndependency_install() {\n local directory download_hosts\n for directory in /var/cache/stll-cloud /var/cache/stll-cloud/bun; do\n [[ ! -L \"$directory\" ]] || fail 'Dependency cache parent must not be a symlink'\n if [[ -e \"$directory\" ]]; then\n [[ -d \"$directory\" && \"$(stat -c '%u' \"$directory\")\" == 0 ]] || fail 'Dependency cache parent must be root-owned'\n fi\n install -d -m 755 -o root -g root \"$directory\"\n done\n [[ ! -L \"$BUN_CACHE\" ]] || fail 'Dependency cache must not be a symlink'\n if [[ -e \"$BUN_CACHE\" ]]; then\n [[ -d \"$BUN_CACHE\" && \"$(stat -c '%u' \"$BUN_CACHE\")\" == \"$OUTPUT_UID\" ]] || fail 'Dependency cache ownership differs from the invoking user'\n fi\n install -d -m 700 -o \"$OUTPUT_UID\" -g \"$OUTPUT_GID\" \"$BUN_CACHE\"\n # Report hostnames only: lockfile/config URLs may contain credentials.\n # These are known install hosts; lifecycle scripts can contact other hosts.\n download_hosts=\"$(HOME=\"$OUTPUT_HOME\" \"$NODE_DIR/bin/node\" -e '\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\nconst hosts = new Set([\"registry.npmjs.org\"]);\nconst inputs = [process.env.BUN_CONFIG_REGISTRY ?? \"\", process.env.NPM_CONFIG_REGISTRY ?? \"\", process.env.npm_config_registry ?? \"\"];\nfor (const file of [\"bun.lock\", \".npmrc\", \"bunfig.toml\", path.join(process.env.HOME, \".npmrc\"), path.join(process.env.HOME, \".bunfig.toml\"), path.join(process.env.XDG_CONFIG_HOME ?? process.env.HOME, \".bunfig.toml\")]) {\n if (fs.existsSync(file)) inputs.push(fs.readFileSync(file, \"utf8\"));\n}\nfor (const input of inputs) {\n for (const match of input.matchAll(/(?:git\\+)?https?:\\/\\/[^\\s\"\\x27<>\\\\]+/g)) {\n try { hosts.add(new URL(match[0].replace(/^git\\+/, \"\")).hostname); } catch {}\n }\n if (/github:/.test(input)) { hosts.add(\"github.com\"); hosts.add(\"codeload.github.com\"); }\n}\nprocess.stdout.write([...hosts].sort().join(\",\"));\n')\"\n # Bun 1.4.3 socket inactivity timeout, in seconds; the outer bound includes scripts.\n network_run \"$download_hosts\" 240 runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" BUN_INSTALL_CACHE_DIR=\"$BUN_CACHE\" PATH=\"$PATH\" BUN_CONFIG_HTTP_IDLE_TIMEOUT=20 \"$BUN_DIR/bun\" @INSTALL_ARGS@\n}\n\n# The frozen install is the check: it reads every input the package manager\n# uses and changes nothing on a current tree, so no stamp stands in for it.\ninstall_dependencies() {\n dependency_install\n}\nsync_dependencies() {\n dependency_install || fail 'bun.lock mismatch; dependency installation failed'\n}\n\n@SUBMODULE_FUNCTION@@SERVICE_INSTALL@\n@SERVICE_START@\n\n@TOOL_INSTALL@\n\n@INPUT_VALIDATION@\n\n@ENV_FUNCTIONS@\n@ENVIRONMENT_VALUES@\n@SESSION_ENVIRONMENT@\n\n@PREPARE_FUNCTION@\n\nif [[ \"$MODE\" == install ]]; then\n step runtimes install_runtimes\n step services install_services\n step tools install_tools\n step shell install_shell_environment\n # Login routes read the installed profile, so they are checked after it.\n step routes verify_bun_routes\n@SUBMODULE_STEP@ step dependencies install_dependencies\n@PREPARE_STEP@\n exit 0\nfi\n@ENV_INITIALIZE@\nstart_environment() {\n step runtime-check runtime_ready\n step dependencies sync_dependencies\n step tool-check verify_tools\n step shell install_shell_environment\n step shell-check verify_shell_environment\n @ENV_VALIDATE@\n step state prepare_state\n step service-start start_services\n @ENV_WRITE@\n}\nif [[ \"$MODE\" == session ]]; then\n start_environment >&2\nelse\n start_environment\nfi\n@SESSION_ENVIRONMENT_CALL@\n`;\n\nconst environmentValuesFunction = String.raw`\nenvironment_values() {\n local emit=\"$1\"\n \"$emit\" NODE_ENV test\n if [[ -n \"$DATABASE_URL\" ]]; then\n \"$emit\" DATABASE_URL \"$DATABASE_URL\"\n \"$emit\" POSTGRES_HOST \"$POSTGRES_HOST\"\n \"$emit\" POSTGRES_USER \"$POSTGRES_USER\"\n \"$emit\" POSTGRES_PASSWORD \"$POSTGRES_PASSWORD\"\n \"$emit\" POSTGRES_DB_NAME \"$POSTGRES_DB_NAME\"\n \"$emit\" POSTGRES_ADDITIONAL_CONNECTION_DATA \"$POSTGRES_ADDITIONAL_CONNECTION_DATA\"\n fi\n if [[ -n \"$REDIS_URL\" ]]; then \"$emit\" REDIS_URL \"$REDIS_URL\"; fi\n}\n`;\n\nconst environmentFunctions = String.raw`\nvalidate_environment() {\n local part target=\"$REPO_ROOT\" env_path=\"$REPO_ROOT/$ENV_FILE\" first_line temporary\n while IFS= read -r part; do\n target=\"$target/$part\"\n [[ ! -L \"$target\" ]] || fail 'Environment path must not contain symbolic links'\n done < <(printf '%s\\n' \"$ENV_FILE\" | tr '/' '\\n')\n [[ -d \"$(dirname -- \"$env_path\")\" ]] || fail 'Environment parent directory is missing'\n if [[ -e \"$env_path\" ]]; then\n [[ -f \"$env_path\" ]] || fail 'Environment target must be a regular file'\n IFS= read -r first_line < \"$env_path\" || fail 'Refusing to overwrite an unowned environment file'\n [[ \"$first_line\" == \"$ENV_MARKER\" ]] || fail 'Refusing to overwrite an unowned environment file'\n fi\n}\nenvironment_file_value() { printf '%s=%s\\n' \"$1\" \"$2\"; }\nwrite_environment() {\n validate_environment\n local env_path=\"$REPO_ROOT/$ENV_FILE\" temporary\n temporary=\"$(mktemp \"$(dirname -- \"$env_path\")/.stll-cloud-env.XXXXXX\")\"\n chmod 600 \"$temporary\"\n {\n printf '%s\\n' \"$ENV_MARKER\"\n environment_values environment_file_value\n } > \"$temporary\"\n chown \"$OUTPUT_UID:$OUTPUT_GID\" \"$temporary\"\n mv -f -- \"$temporary\" \"$env_path\"\n}\n`;\n\nconst sessionEnvironmentFunction = String.raw`\nenvironment_shell_value() { printf 'export %s=%q\\n' \"$1\" \"$2\"; }\nemit_session_environment() {\n environment_values environment_shell_value\n}\n`;\n\nconst shellQuote = (value: string) => `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n\nconst renderWasmBindgenLockValidation = (version: string) =>\n `[[ -f 'Cargo.lock' && ! -L 'Cargo.lock' ]] && awk -v expected=${shellQuote(version)} '${String.raw`\nfunction validate_package() {\n if (in_package && name == \"wasm-bindgen\") {\n count++\n if (version != expected) mismatch = 1\n }\n}\n/^\\[\\[package\\]\\][[:space:]]*$/ {\n validate_package()\n in_package = 1\n name = \"\"\n version = \"\"\n next\n}\n/^\\[/ {\n validate_package()\n in_package = 0\n next\n}\nin_package && /^[[:space:]]*name[[:space:]]*=/ {\n name = $0\n sub(/^[^=]*=[[:space:]]*\"/, \"\", name)\n sub(/\"[[:space:]]*$/, \"\", name)\n}\nin_package && /^[[:space:]]*version[[:space:]]*=/ {\n version = $0\n sub(/^[^=]*=[[:space:]]*\"/, \"\", version)\n sub(/\"[[:space:]]*$/, \"\", version)\n}\nEND {\n validate_package()\n exit !(count >= 1 && !mismatch)\n}`}' 'Cargo.lock' || fail 'Cargo.lock wasm-bindgen version changed; regenerate cloud-setup.sh'`;\n\n// Offline and time-bounded: stdin is closed so a prompt cannot hold the\n// snapshot. timeout leads its own process group (its pid), but it stops\n// escalating once its direct child exits, so whatever is left in that group\n// afterwards (a descendant that ignored TERM) is killed unconditionally.\nconst renderPrepare = (\n prepare: { script: string; seconds: number } | undefined,\n files: Readonly<Record<string, string>>,\n) => {\n if (prepare === undefined) return \"\";\n const manifest = files[\"package.json\"];\n if (manifest === undefined)\n throw new Error(\"cloud.prepare requires a tracked root package.json\");\n const parsed: unknown = JSON.parse(manifest);\n const scripts =\n typeof parsed === \"object\" && parsed !== null && \"scripts\" in parsed\n ? parsed.scripts\n : undefined;\n if (\n typeof scripts !== \"object\" ||\n scripts === null ||\n !Object.hasOwn(scripts, prepare.script) ||\n typeof Reflect.get(scripts, prepare.script) !== \"string\"\n )\n throw new Error(\n `cloud.prepare.script ${prepare.script} is not a root package script`,\n );\n return [\n \"prepare_sources() {\",\n \" local leader status=0\",\n ` timeout --kill-after=10 ${prepare.seconds} runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" PATH=\"$PATH\" \"$BUN_DIR/bun\" run ${shellQuote(prepare.script)} </dev/null &`,\n \" leader=$!\",\n ' wait \"$leader\" || status=$?',\n ' kill -KILL -- \"-$leader\" 2>/dev/null || true',\n ' return \"$status\"',\n \"}\",\n ].join(\"\\n\");\n};\n\nexport const generateCloudSetup = ({\n policy,\n cloud,\n nodeVersion,\n files = {},\n rustExceptions = [],\n}: GenerateCloudSetupOptions) => {\n const selected = parseCloudSetup(cloud);\n if (selected === undefined) throw new Error(\"cloud declaration is required\");\n const exactNode = nodeVersion.trim();\n if (\n valid(exactNode) !== exactNode ||\n !nodeSelectorMatches(exactNode, policy.node)\n )\n throw new Error(\n \"cloud requires a tracked exact .node-version within the shared Node series\",\n );\n const toolchains = resolveCloudToolchains({\n cloud: selected,\n files,\n rust: policy.rust,\n rustExceptions,\n });\n const services = cloudServices.filter((service) =>\n selected.services.includes(service),\n );\n const replacements = new Map([\n [\"@INSTALL_ARGS@\", selected.install.replace(/^bun /, \"\")],\n [\"@NETWORK@\", renderCloudNetwork()],\n [\n \"@TOOL_INSTALL@\",\n renderCloudToolInstall(toolchains) +\n renderCloudShellInstall({\n nodeVersion: exactNode,\n bunVersion: policy.bun,\n rust: toolchains.rust,\n }),\n ],\n [\n \"@INPUT_VALIDATION@\",\n [\"rust-toolchain.toml\", \"rust-toolchain\"]\n .flatMap((file) => {\n const content = files[file];\n if (content === undefined)\n return [\n `[[ ! -e ${shellQuote(file)} && ! -L ${shellQuote(file)} ]] || fail ${shellQuote(`${file} appeared; regenerate cloud-setup.sh`)}`,\n ];\n const hash = createHash(\"sha256\").update(content).digest(\"hex\");\n return [\n `[[ -f ${shellQuote(file)} && ! -L ${shellQuote(file)} ]] && [[ \"$(sha256sum -- ${shellQuote(file)} | cut -d ' ' -f1)\" == ${shellQuote(hash)} ]] || fail ${shellQuote(`${file} changed; regenerate cloud-setup.sh`)}`,\n ];\n })\n .concat(\n selected.tools?.[\"wasm-bindgen-cli\"] === undefined\n ? []\n : [\n renderWasmBindgenLockValidation(\n selected.tools[\"wasm-bindgen-cli\"],\n ),\n ],\n )\n .join(\"\\n\"),\n ],\n [\"@BUN@\", policy.bun],\n [\"@NODE@\", exactNode],\n [\n \"@ENV_ASSIGNMENTS@\",\n selected.envFile === undefined\n ? \"\"\n : `ENV_FILE=${shellQuote(selected.envFile)}\\nENV_MARKER=${shellQuote(cloudEnvironmentMarker)}`,\n ],\n [\n \"@ENV_FUNCTIONS@\",\n selected.envFile === undefined ? \"\" : environmentFunctions,\n ],\n [\n \"@ENVIRONMENT_VALUES@\",\n selected.services.length === 0 ? \"\" : environmentValuesFunction,\n ],\n [\n \"@ENV_INITIALIZE@\",\n selected.services.length === 0\n ? \"\"\n : \"DATABASE_URL=''\\nPOSTGRES_HOST=''\\nPOSTGRES_USER=''\\nPOSTGRES_PASSWORD=''\\nPOSTGRES_DB_NAME=''\\nPOSTGRES_ADDITIONAL_CONNECTION_DATA=''\\nREDIS_URL=''\",\n ],\n [\n \"@ENV_VALIDATE@\",\n selected.envFile === undefined ? \"\" : \"validate_environment\",\n ],\n [\n \"@SESSION_ENVIRONMENT@\",\n selected.services.length === 0 ? \"\" : sessionEnvironmentFunction,\n ],\n [\n \"@SESSION_ENVIRONMENT_CALL@\",\n selected.services.length === 0\n ? \"\"\n : 'if [[ \"$MODE\" == session ]]; then emit_session_environment; fi',\n ],\n [\"@ENV_WRITE@\", selected.envFile === undefined ? \"\" : \"write_environment\"],\n [\"@PREPARE_FUNCTION@\", renderPrepare(selected.prepare, files)],\n [\n \"@SUBMODULE_FUNCTION@\",\n selected.submodules\n ? String.raw`install_submodules() {\n network_run github.com 240 runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" git submodule sync --recursive\n network_run github.com 240 runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" git submodule update --init --recursive --depth 1\n}`.concat(\"\\n\\n\")\n : \"\",\n ],\n [\n \"@SUBMODULE_STEP@\",\n selected.submodules ? \" step submodules install_submodules\\n\" : \"\",\n ],\n [\n \"@PREPARE_STEP@\",\n selected.prepare === undefined ? \"\" : \" step prepare prepare_sources\",\n ],\n [\n \"@SERVICE_INSTALL@\",\n renderCloudServiceInstall({\n services,\n postgres: policy.postgres,\n valkey: policy.valkey,\n valkeyArtifacts: policy.valkeyArtifacts,\n }),\n ],\n [\n \"@SERVICE_START@\",\n renderCloudServiceStart({\n services,\n postgres: policy.postgres,\n valkey: policy.valkey,\n }),\n ],\n ]);\n const rendered = script.replace(/@[A-Z0-9_]+@/g, (token) => {\n const value = replacements.get(token);\n if (value === undefined)\n throw new Error(`Missing cloud setup field: ${token}`);\n return value;\n });\n return `${rendered.replace(/[ \\t]+$/gm, \"\").trimEnd()}\\n`;\n};\n","import { isDeepStrictEqual } from \"node:util\";\nimport { parseDocument } from \"yaml\";\n\nimport { cloudSetupPath } from \"./cloud-setup\";\nimport { cloudShellProfilePath } from \"./cloud-setup-shell\";\n\nexport const cloudClaudeSettingsPath = \".claude/settings.json\";\nconst releasedSessionStartHook = (script: string) =>\n ({\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: `if [ \"\\${CLAUDE_CODE_REMOTE:-}\" = \"true\" ]; then\n ${script} start || exit \"$?\"\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n if [ ! -f ${cloudShellProfilePath} ]; then\n printf '%s\\\\n' 'cloud-setup: cloud shell profile is unavailable; run install' >&2\n exit 1\n fi\n printf '\\\\n' >> \"$CLAUDE_ENV_FILE\" || exit \"$?\"\n cat ${cloudShellProfilePath} >> \"$CLAUDE_ENV_FILE\"\n fi\nfi`,\n },\n ],\n }) as const;\n// Release 1.7.0 persisted this form; it rewrote the shared env file.\nconst releasedTemporaryFileHook = (script: string) =>\n ({\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: `if [ \"\\${CLAUDE_CODE_REMOTE:-}\" = \"true\" ]; then\n cloud_setup_incomplete() {\n 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.'\n printf '%s\\\\n' \"cloud-setup: $1\" >&2\n exit 0\n }\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n cloud_session_exports=\"$(${script} session)\" || cloud_setup_incomplete 'startup failed; run install'\n else\n ${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'\n exit 0\n fi\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n if [ ! -s ${cloudShellProfilePath} ]; then\n cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n fi\n cloud_shell_exports=\"$(cat ${cloudShellProfilePath})\" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'\n [ -n \"$cloud_shell_exports\" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n if [ -e \"$CLAUDE_ENV_FILE\" ] || [ -L \"$CLAUDE_ENV_FILE\" ]; then\n [ -f \"$CLAUDE_ENV_FILE\" ] && [ ! -L \"$CLAUDE_ENV_FILE\" ] || cloud_setup_incomplete 'session environment must be a regular file; check its path and rerun start'\n fi\n 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'\n if [ -e \"$CLAUDE_ENV_FILE\" ] || [ -L \"$CLAUDE_ENV_FILE\" ]; then\n 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'; }\n fi\n if [ -n \"$cloud_session_exports\" ]; then\n cloud_session_exports=\"$cloud_session_exports\n$cloud_shell_exports\"\n else\n cloud_session_exports=\"$cloud_shell_exports\"\n fi\n 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'; }\n 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'; }\n fi\nfi`,\n },\n ],\n }) as const;\n// SessionStart cannot block a session; successful stdout supplies model\n// context, so failures exit 0 with guidance. Hooks share CLAUDE_ENV_FILE and\n// may run concurrently, so this hook replaces only its own snapshot and\n// appends one stable source line to the shared file once.\nconst sessionStartHook = (script: string) =>\n ({\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: `if [ \"\\${CLAUDE_CODE_REMOTE:-}\" = \"true\" ]; then\n cloud_setup_incomplete() {\n 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.'\n printf '%s\\\\n' \"cloud-setup: $1\" >&2\n exit 0\n }\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n cloud_session_exports=\"$(${script} session)\" || cloud_setup_incomplete 'startup failed; run install'\n else\n ${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'\n exit 0\n fi\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n if [ ! -s ${cloudShellProfilePath} ]; then\n cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n fi\n cloud_shell_exports=\"$(cat ${cloudShellProfilePath})\" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'\n [ -n \"$cloud_shell_exports\" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n if [ -e \"$CLAUDE_ENV_FILE\" ] || [ -L \"$CLAUDE_ENV_FILE\" ]; then\n [ -f \"$CLAUDE_ENV_FILE\" ] && [ ! -L \"$CLAUDE_ENV_FILE\" ] || cloud_setup_incomplete 'session environment must be a regular file; check its path and rerun start'\n fi\n cloud_env_snapshot=\"\\${CLAUDE_ENV_FILE}.stll-cloud\"\n case \"$cloud_env_snapshot\" in\n *\"'\"*) cloud_setup_incomplete 'session environment path must not contain a single quote; check its path and rerun start' ;;\n esac\n if [ -n \"$cloud_session_exports\" ]; then\n cloud_session_exports=\"$cloud_session_exports\n$cloud_shell_exports\"\n else\n cloud_session_exports=\"$cloud_shell_exports\"\n fi\n cloud_env_temporary=\"$(umask 077; mktemp \"\\${cloud_env_snapshot}.XXXXXX\")\" || cloud_setup_incomplete 'session environment could not be prepared; check its write access and rerun start'\n printf '%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'; }\n mv -f -- \"$cloud_env_temporary\" \"$cloud_env_snapshot\" || { rm -f -- \"$cloud_env_temporary\"; cloud_setup_incomplete 'session environment could not be persisted; check its write access and rerun start'; }\n cloud_env_source=\". '$cloud_env_snapshot'\"\n if [ ! -f \"$CLAUDE_ENV_FILE\" ] || ! grep -Fqx -- \"$cloud_env_source\" \"$CLAUDE_ENV_FILE\"; then\n printf '\\\\n%s\\\\n' \"$cloud_env_source\" >> \"$CLAUDE_ENV_FILE\" || cloud_setup_incomplete 'session environment could not be persisted; check its write access and rerun start'\n fi\n fi\nfi`,\n },\n ],\n }) as const;\n// This exact form was persisted by the previous main-branch generator at 783bc97.\n// Keep it only so consumers of that release can regenerate to the current hook.\nconst currentMainSessionStartHook = (script: string) =>\n ({\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: `if [ \"\\${CLAUDE_CODE_REMOTE:-}\" = \"true\" ]; then\n cloud_setup_incomplete() {\n 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.'\n printf '%s\\\\n' \"cloud-setup: $1\" >&2\n exit 0\n }\n ${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n if [ ! -s ${cloudShellProfilePath} ]; then\n cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n fi\n cloud_shell_exports=\"$(cat ${cloudShellProfilePath})\" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'\n [ -n \"$cloud_shell_exports\" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n 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'\n fi\nfi`,\n },\n ],\n }) as const;\n// Hooks run in the session's working directory; resolve the script from the project root.\nexport const cloudSessionStartHook = sessionStartHook(\n `bash \"$CLAUDE_PROJECT_DIR/${cloudSetupPath}\"`,\n);\n// Releases 1.1.0, 1.3.1 and 1.7.0 persisted these exact forms in consumer\n// settings.\n// Remove after supported consumers regenerate with a release containing this hook.\nconst previousCloudSessionStartHooks = [\n releasedSessionStartHook(`bash ${cloudSetupPath}`),\n releasedSessionStartHook(`bash \"$CLAUDE_PROJECT_DIR/${cloudSetupPath}\"`),\n currentMainSessionStartHook(`bash \"$CLAUDE_PROJECT_DIR/${cloudSetupPath}\"`),\n releasedTemporaryFileHook(`bash \"$CLAUDE_PROJECT_DIR/${cloudSetupPath}\"`),\n];\nexport const cloudAttribution = { commit: \"\", pr: \"\" } as const;\n\nconst record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst array = (value: unknown): value is readonly unknown[] =>\n Array.isArray(value);\n\nconst parseSettings = (text: string) => {\n try {\n const settings: unknown = JSON.parse(text, (_key, value: unknown) => {\n if (\n typeof value === \"number\" &&\n (!Number.isFinite(value) ||\n (Number.isInteger(value) && !Number.isSafeInteger(value)))\n )\n throw new Error(\n \"settings contains a number that cannot be safely preserved\",\n );\n return value;\n });\n return settings;\n } catch (error) {\n if (error instanceof SyntaxError)\n throw new Error(\"settings must contain valid JSON\");\n throw error;\n }\n};\n\nconst readSettings = (text: string | undefined) => {\n const settings = text === undefined ? {} : parseSettings(text);\n if (\n text !== undefined &&\n parseDocument(text, { uniqueKeys: true }).errors.length > 0\n )\n throw new Error(\"settings contains duplicate or ambiguous JSON keys\");\n if (!record(settings)) throw new Error(\"settings must be a JSON object\");\n if (settings[\"disableAllHooks\"] === true)\n throw new Error(\"disableAllHooks prevents SessionStart from running\");\n const hooks = settings[\"hooks\"] === undefined ? {} : settings[\"hooks\"];\n if (!record(hooks)) throw new Error(\"hooks must be a JSON object\");\n const sessionStart =\n hooks[\"SessionStart\"] === undefined ? [] : hooks[\"SessionStart\"];\n if (\n !array(sessionStart) ||\n sessionStart.some((entry) => !record(entry) || !array(entry[\"hooks\"]))\n )\n throw new Error(\"hooks.SessionStart must be an array of hook groups\");\n return { settings, hooks, sessionStart };\n};\n\nconst cloudHookGroups = (sessionStart: readonly unknown[]) =>\n sessionStart.filter(\n (entry) =>\n record(entry) &&\n array(entry[\"hooks\"]) &&\n entry[\"hooks\"].some(\n (hook) =>\n record(hook) &&\n typeof hook[\"command\"] === \"string\" &&\n hook[\"command\"].includes(cloudSetupPath),\n ),\n );\n\nexport const cloudSessionStartFix =\n `preserve unrelated settings in ${cloudClaudeSettingsPath}, repair its JSON/hooks structure and set disableAllHooks to false if needed, and ensure hooks.SessionStart contains exactly this cloud setup entry (replace conflicting cloud setup entries):\\n` +\n JSON.stringify(cloudSessionStartHook, null, 2);\nexport const cloudAttributionFix =\n `preserve unrelated settings in ${cloudClaudeSettingsPath} and set its top-level attribution to exactly:\\n` +\n JSON.stringify({ attribution: cloudAttribution }, null, 2);\n\nconst sessionStartState = (sessionStart: readonly unknown[]) => {\n const groups = cloudHookGroups(sessionStart);\n const group = groups.at(0);\n if (group === undefined) return { type: \"missing\" } as const;\n if (groups.length === 1 && isDeepStrictEqual(group, cloudSessionStartHook))\n return { type: \"current\" } as const;\n if (\n groups.length === 1 &&\n previousCloudSessionStartHooks.some((hook) =>\n isDeepStrictEqual(group, hook),\n )\n )\n return { type: \"previous\", group } as const;\n return { type: \"conflict\" } as const;\n};\n\nconst attributionState = (settings: Record<string, unknown>) => {\n const attribution = settings[\"attribution\"];\n if (attribution === undefined) return \"missing\";\n return isDeepStrictEqual(attribution, cloudAttribution)\n ? \"current\"\n : \"conflict\";\n};\n\nconst mergeError = (reason: string, fix: string) =>\n new Error(\n `cannot safely merge ${cloudClaudeSettingsPath}: ${reason}; ${fix}`,\n );\n\nconst readMergeableSettings = (text: string | undefined) => {\n try {\n return readSettings(text);\n } catch (error) {\n throw mergeError(\n error instanceof Error ? error.message : String(error),\n cloudSessionStartFix,\n );\n }\n};\n\n/** Add the cloud hook and attribution; never overwrite conflicting values. */\nexport const mergeCloudClaudeSettings = (text: string | undefined) => {\n const { settings, hooks, sessionStart } = readMergeableSettings(text);\n const hook = sessionStartState(sessionStart);\n if (hook.type === \"conflict\")\n throw mergeError(\n \"existing cloud setup SessionStart hook differs\",\n cloudSessionStartFix,\n );\n const attribution = attributionState(settings);\n if (attribution === \"conflict\")\n throw mergeError(\"existing attribution differs\", cloudAttributionFix);\n if (\n hook.type === \"current\" &&\n attribution === \"current\" &&\n text !== undefined\n )\n return text;\n const mergedSessionStart = (() => {\n switch (hook.type) {\n case \"current\":\n return sessionStart;\n case \"missing\":\n return [...sessionStart, cloudSessionStartHook];\n case \"previous\":\n return sessionStart.map((entry) =>\n entry === hook.group ? cloudSessionStartHook : entry,\n );\n default: {\n const exhaustive: never = hook;\n throw new Error(`Unsupported hook state: ${String(exhaustive)}`);\n }\n }\n })();\n return `${JSON.stringify(\n {\n ...settings,\n attribution: cloudAttribution,\n hooks: { ...hooks, SessionStart: mergedSessionStart },\n },\n null,\n 2,\n )}\\n`;\n};\n\n/** Settings formatting and unrelated hooks do not affect the generated contract. */\nexport const hasCloudSessionStartHook = (text: string | undefined) => {\n if (text === undefined) return false;\n try {\n return (\n sessionStartState(readSettings(text).sessionStart).type === \"current\"\n );\n } catch {\n return false;\n }\n};\n\nexport const hasCloudAttribution = (text: string | undefined) => {\n if (text === undefined) return false;\n try {\n return attributionState(readSettings(text).settings) === \"current\";\n } catch {\n return false;\n }\n};\n","import path from \"node:path\";\nimport picomatch from \"picomatch\";\n\ntype WorkspaceContainsOptions = {\n directory: string;\n file: string;\n patterns: unknown;\n rootMembership: \"implicit\" | \"patterns\";\n};\n\n/** Match manifest directories with the same positive and negative workspace patterns. */\nexport const workspaceContains = ({\n directory,\n file,\n patterns,\n rootMembership,\n}: WorkspaceContainsOptions) => {\n const relative = path.posix.relative(directory, path.posix.dirname(file));\n if (relative === \"\" && rootMembership === \"implicit\") return true;\n if (relative === \"..\" || relative.startsWith(\"../\")) return false;\n if (!Array.isArray(patterns)) return false;\n const normalize = (pattern: string) => path.posix.normalize(pattern);\n const selected = patterns.filter(\n (value: unknown): value is string => typeof value === \"string\",\n );\n return (\n picomatch(\n selected.filter((pattern) => !pattern.startsWith(\"!\")).map(normalize),\n )(relative) &&\n !picomatch(\n selected\n .filter((pattern) => pattern.startsWith(\"!\"))\n .map((pattern) => normalize(pattern.slice(1))),\n )(relative)\n );\n};\n","const record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** Filename class recognized by Dependabot's Docker Compose fetcher. */\nexport const isComposeDefinitionPath = (file: string) =>\n /^\\.?(?:docker-)?compose(?:-[\\w]+)?(?:\\.[\\w-]+)?\\.ya?ml$/i.test(\n file.split(\"/\").at(-1) ?? \"\",\n );\n\n/** Candidate YAML files are classified by their document shape after reading. */\nexport const isKubernetesDefinitionPath = (file: string) =>\n /^[^.].*\\.ya?ml$/i.test(file.split(\"/\").at(-1) ?? \"\");\n\ntype ContainerImage = { image: unknown; path: (string | number)[] };\ntype ContainerDocument = {\n ecosystem: \"docker-compose\" | \"docker\";\n images: ContainerImage[];\n};\n\nexport const kubernetesPodSpecPaths = {\n Pod: [\"spec\"],\n Deployment: [\"spec\", \"template\", \"spec\"],\n DaemonSet: [\"spec\", \"template\", \"spec\"],\n StatefulSet: [\"spec\", \"template\", \"spec\"],\n ReplicaSet: [\"spec\", \"template\", \"spec\"],\n ReplicationController: [\"spec\", \"template\", \"spec\"],\n Job: [\"spec\", \"template\", \"spec\"],\n CronJob: [\"spec\", \"jobTemplate\", \"spec\", \"template\", \"spec\"],\n} as const;\n\n/** Shared semantic image enumeration for runtime checks and update-root generation. */\nexport const containerDocumentImages = (\n document: unknown,\n file: string,\n): ContainerDocument | undefined => {\n if (!record(document)) return undefined;\n const services = document[\"services\"];\n if (isComposeDefinitionPath(file) && record(services)) {\n const images: ContainerImage[] = [];\n for (const [name, service] of Object.entries(services)) {\n if (record(service) && service[\"image\"] !== undefined)\n images.push({\n image: service[\"image\"],\n path: [\"services\", name, \"image\"],\n });\n }\n return { ecosystem: \"docker-compose\", images };\n }\n if (\n typeof document[\"apiVersion\"] !== \"string\" ||\n typeof document[\"kind\"] !== \"string\"\n )\n return undefined;\n const images: ContainerImage[] = [];\n const visited = new Set<Record<string, unknown>>();\n const walkResource = (\n resource: Record<string, unknown>,\n prefix: (string | number)[],\n ) => {\n if (visited.has(resource)) return;\n visited.add(resource);\n if (\n typeof resource[\"apiVersion\"] !== \"string\" ||\n typeof resource[\"kind\"] !== \"string\"\n )\n return;\n if (resource[\"kind\"] === \"List\" && Array.isArray(resource[\"items\"])) {\n for (const [index, item] of resource[\"items\"].entries())\n if (record(item)) walkResource(item, [...prefix, \"items\", index]);\n return;\n }\n const specPath = Object.entries(kubernetesPodSpecPaths).find(\n ([kind]) => kind === resource[\"kind\"],\n )?.[1];\n if (specPath === undefined) return;\n let spec: unknown = resource;\n for (const key of specPath) spec = record(spec) ? spec[key] : undefined;\n if (!record(spec)) return;\n for (const key of [\"containers\", \"initContainers\", \"ephemeralContainers\"]) {\n const containers = spec[key];\n if (!Array.isArray(containers)) continue;\n for (const [index, container] of containers.entries()) {\n if (record(container) && container[\"image\"] !== undefined)\n images.push({\n image: container[\"image\"],\n path: [...prefix, ...specPath, key, index, \"image\"],\n });\n }\n }\n };\n walkResource(document, []);\n return images.length === 0 ? undefined : { ecosystem: \"docker\", images };\n};\n","import { cloudSetupPath } from \"./cloud-setup\";\nimport { cloudClaudeSettingsPath } from \"./cloud-setup-claude\";\nimport {\n isComposeDefinitionPath,\n isKubernetesDefinitionPath,\n} from \"./toolchain-container-inputs\";\n\nconst excludedInputPath = (file: string) =>\n file === \"\" ||\n file.split(\"/\").some((part) => part === \"node_modules\" || part === \"vendor\");\n\nexport const javascriptDependencyLockfiles = [\n \"bun.lock\",\n \"package-lock.json\",\n \"yarn.lock\",\n \"pnpm-lock.yaml\",\n] as const;\n\nexport const dependabotManifestEcosystems = {\n Gemfile: \"bundler\",\n \"Gemfile.lock\": \"bundler\",\n \"composer.json\": \"composer\",\n \"composer.lock\": \"composer\",\n} as const;\n\n/** Share ecosystem inventory with snapshot selection; no dependency graph reads are needed. */\nexport const dependabotManifestEcosystem = (file: string) => {\n if (excludedInputPath(file)) return undefined;\n const basename = file.split(\"/\").at(-1);\n for (const [name, ecosystem] of Object.entries(dependabotManifestEcosystems))\n if (basename === name) return ecosystem;\n return undefined;\n};\n\n/** Match project, environment, local, and fragment filenames recognized by mise. */\nexport const isMiseConfigPath = (file: string) =>\n !excludedInputPath(file) &&\n (/(?:^|\\/)\\.?mise(?:\\.[^./][^/]*)?\\.toml$/.test(file) ||\n /(?:^|\\/)(?:\\.?mise|\\.config\\/mise)\\/config(?:\\.[^./][^/]*)?\\.toml$/.test(\n file,\n ) ||\n /(?:^|\\/)(?:\\.?mise|\\.config\\/mise)\\/conf\\.d\\/[^./][^/]*\\.toml$/.test(\n file,\n ));\n\n/** GitHub action metadata may live at the repository root or in any directory. */\nexport const githubAutomationFileKind = (file: string) => {\n if (file === \"\") return undefined;\n if (/^\\.github\\/workflows\\/[^/]+\\.ya?ml$/.test(file)) return \"workflow\";\n if (/(?:^|\\/)action\\.ya?ml$/.test(file)) return \"action\";\n return undefined;\n};\n\n/** Dependabot updates workflows and repository-root action metadata. */\nexport const isDependabotGithubActionsPath = (file: string) => {\n const kind = githubAutomationFileKind(file);\n return kind === \"workflow\" || (kind === \"action\" && !file.includes(\"/\"));\n};\n\n/** Use one filename discriminator for reader selection and Python ecosystem decisions. */\nexport const pythonDependencyManifestKind = (file: string) => {\n if (excludedInputPath(file)) return undefined;\n const name = file.split(\"/\").at(-1);\n if (name === \"pyproject.toml\") return \"project\";\n if (name === \"Pipfile\") return \"pipfile\";\n if (name === \"Pipfile.lock\") return \"pipfile-lock\";\n if (name === \"setup.py\" || name === \"setup.cfg\") return \"setup\";\n if (name !== undefined && /^requirements[^/]*\\.(?:txt|in)$/.test(name))\n return \"requirements\";\n return undefined;\n};\n\nexport const isPythonDependencyManifest = (file: string) =>\n pythonDependencyManifestKind(file) !== undefined;\n\n/** Docker definition names use dot-delimited variants, excluding source and documentation. */\nexport const isDockerDefinitionPath = (file: string) => {\n if (excludedInputPath(file)) return false;\n const name = file.split(\"/\").at(-1) ?? \"\";\n if (\n /\\.(?:[cm]?[jt]sx?|mdx?|rst|txt|html?|py|rs|go|java|sh|c|cc|cpp|cxx|h|hpp|cs|rb|php|swift|kt|css|scss)$/i.test(\n name,\n )\n )\n return false;\n return /^(?:[^./]+\\.)*(?:dockerfile|containerfile)(?:\\.[^./]+)*$/i.test(name);\n};\n\nexport const isFormatterConfigPath = (file: string) => {\n const name = file.split(\"/\").at(-1) ?? \"\";\n return (\n /^\\.oxfmtrc(?:\\.jsonc?)?$/.test(name) ||\n /^oxfmt\\.config\\.[cm]?[jt]s$/.test(name) ||\n /^\\.prettierrc(?:\\.[^/]+)?$/.test(name) ||\n /^prettier\\.config\\.[cm]?[jt]s$/.test(name) ||\n name === \".prettierignore\" ||\n /^biome\\.jsonc?$/.test(name) ||\n /^\\.?dprint\\.jsonc?$/.test(name)\n );\n};\n\nexport const isLefthookConfigPath = (file: string) =>\n /^\\.?lefthook(?:-local)?\\.ya?ml$/.test(file);\n\n/** Executable shell files may have no suffix; the interpreter is then their discriminator. */\nexport const isShellScript = (file: string, text = \"\") =>\n !excludedInputPath(file) &&\n (/\\.(?:sh|bash|zsh)$/.test(file) ||\n /^#![ \\t]*(?:\\/(?:[^ \\t\\r\\n]+\\/)*(?:bash|dash|ksh|zsh|sh)|\\/usr\\/bin\\/env[ \\t]+(?:-S[ \\t]+)?(?:bash|dash|ksh|zsh|sh))(?=[ \\t\\r\\n]|$)/.test(\n text,\n ));\n\n/** Lockfiles establish ecosystem presence without reading their dependency graphs. */\nexport const toolchainInputKind = (file: string, text = \"\") => {\n if (\n file === \"bunfig.toml\" ||\n file === cloudSetupPath ||\n file === cloudClaudeSettingsPath ||\n file === \"Cargo.lock\" ||\n file === \".changeset/config.json\" ||\n isLefthookConfigPath(file)\n )\n return \"config\";\n if (githubAutomationFileKind(file) !== undefined) return \"config\";\n if (excludedInputPath(file)) return undefined;\n if (\n dependabotManifestEcosystem(file) !== undefined ||\n pythonDependencyManifestKind(file) === \"pipfile-lock\" ||\n javascriptDependencyLockfiles.some(\n (name) => file.split(\"/\").at(-1) === name,\n ) ||\n /(?:^|\\/)uv\\.lock$/.test(file) ||\n isFormatterConfigPath(file)\n )\n return \"presence\";\n if (\n githubAutomationFileKind(file) !== undefined ||\n isShellScript(file, text) ||\n /(?:^|\\/)ci-service-images\\.json$/.test(file) ||\n isMiseConfigPath(file) ||\n isPythonDependencyManifest(file) ||\n isDockerDefinitionPath(file) ||\n isComposeDefinitionPath(file) ||\n isKubernetesDefinitionPath(file) ||\n /(?:^|\\/)(?: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(\n file,\n )\n )\n return \"config\";\n return undefined;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"toolchain-inputs.mjs","names":["exhaustive","record","exhaustive","quote","record","parseToml","exhaustive","record","exhaustive"],"sources":["../src/cloud-setup-install.ts","../src/cloud-setup-network.ts","../src/archive-pins.ts","../src/cloud-setup-artifacts.ts","../src/cloud-setup-schema.ts","../src/cloud-setup-services.ts","../src/cloud-setup-shell.ts","../src/cloud-setup-toolchains.ts","../src/cloud-setup-tools-install.ts","../src/toolchain-node.ts","../src/cloud-setup.ts","../src/cloud-setup-claude.ts","../src/toolchain-workspaces.ts","../src/toolchain-container-inputs.ts","../src/toolchain-inputs.ts"],"sourcesContent":["import type { CloudService } from \"./cloud-setup-schema\";\nimport type { parseToolchainPolicy } from \"./toolchain-schema\";\n\ntype CloudServiceInstallOptions = {\n services: readonly CloudService[];\n postgres: string;\n valkey: string;\n valkeyArtifacts: ReturnType<typeof parseToolchainPolicy>[\"valkeyArtifacts\"];\n};\n\nconst packageInstall = String.raw`\n# Prevent package maintainer scripts from starting unmanaged system services.\napt_install() (\n # EXIT runs after function locals expire; this subshell owns the trap state.\n backup=''\n policy_state=untouched\n [[ ! -L /var/lock/stll-cloud-apt.lock ]] || fail 'Invalid package install lock'\n exec 8>/var/lock/stll-cloud-apt.lock\n flock -x -w 120 8 || fail 'Another package installation is active'\n [[ ! -L /usr/sbin/policy-rc.d ]] || fail 'Unsupported service-start policy symlink'\n [[ ! -e /usr/sbin/policy-rc.d || -f /usr/sbin/policy-rc.d ]] || fail 'Unsupported service-start policy file'\n backup=\"$(mktemp -d)\"\n cleanup_package_policy() {\n local status=$?\n trap - EXIT HUP INT TERM\n if [[ \"$policy_state\" == installed ]]; then\n if [[ -f \"$backup/original\" ]]; then\n if ! cp -p \"$backup/original\" /usr/sbin/policy-rc.d; then status=1; fi\n else\n if ! rm -f /usr/sbin/policy-rc.d; then status=1; fi\n fi\n fi\n rm -rf -- \"$backup\"\n exit \"$status\"\n }\n trap cleanup_package_policy EXIT\n trap 'exit 129' HUP\n trap 'exit 130' INT\n trap 'exit 143' TERM\n if [[ -e /usr/sbin/policy-rc.d ]]; then cp -p /usr/sbin/policy-rc.d \"$backup/original\"; fi\n policy_state=installed\n printf '%s\\n' '#!/bin/sh' 'exit 101' > /usr/sbin/policy-rc.d\n chmod 755 /usr/sbin/policy-rc.d\n # The network deadline covers downloads only; unpacking and maintainer scripts\n # (for example locale generation or cluster creation) run offline afterwards.\n DEBIAN_FRONTEND=noninteractive apt_network install -y --no-install-recommends --download-only \"$@\"\n local package pending\n for package in \"$@\"; do\n if [[ \"$package\" == */* ]]; then\n # apt rejects --no-download for local archives, so prove instead that\n # only local file: archives remain; --print-uris reads local state only.\n pending=\"$(set -o pipefail; DEBIAN_FRONTEND=noninteractive apt-get --print-uris -qq -y --no-install-recommends install \"$@\" | awk '$1 !~ /^\\047file:/')\"\n [[ -z \"$pending\" ]] || fail \"Package downloads remain after the bounded download step: $pending\"\n DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \"$@\"\n return\n fi\n done\n DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --no-download \"$@\"\n)\n\n`;\n\nconst postgresSourceLine =\n \"deb [signed-by=/usr/share/keyrings/stll-pgdg.asc] https://apt.postgresql.org/pub/repos/apt noble-pgdg main\";\nconst postgresSigningFingerprint = \"B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8\";\n\nconst postgresSources = String.raw`\npgdg_key_fingerprint() {\n gpg --batch --show-keys --with-colons \"$1\" | awk -F: '$1 == \"pub\" { primary = 1 } $1 == \"sub\" { primary = 0 } $1 == \"fpr\" && primary { print toupper($10); primary = 0 }'\n}\npgdg_sources_ready() {\n local managed=\"$1\" file mode records suite keyring override fingerprint selected_keyring=''\n shift\n PGDG_SOURCE_STATE=missing\n [[ ! -L \"$managed\" ]] || fail \"Managed PGDG source must not be a symlink: $managed\"\n for file in \"$@\"; do\n [[ -e \"$file\" ]] || continue\n [[ -f \"$file\" ]] || fail \"APT source must be a regular file: $file\"\n case \"$file\" in *.sources) mode=sources ;; *) mode=list ;; esac\n records=\"$(awk -v mode=\"$mode\" '\n function trim(value) { gsub(/^[[:space:]]+|[[:space:]]+$/, \"\", value); return value }\n function pgdg_uri(uri) {\n uri = tolower(uri)\n if (uri !~ /^[a-z][a-z0-9+.-]*:\\/\\//) return 0\n sub(/^[a-z][a-z0-9+.-]*:\\/\\//, \"\", uri)\n sub(/[\\/?#].*$/, \"\", uri)\n sub(/^.*@/, \"\", uri)\n sub(/:.*$/, \"\", uri)\n return uri == \"apt.postgresql.org\" || uri == \"apt.postgresql.org.\"\n }\n function contains_pgdg(value, tokens, count, token_index) {\n count = split(value, tokens, /[[:space:]]+/)\n for (token_index = 1; token_index <= count; token_index++) if (pgdg_uri(tokens[token_index])) return 1\n return 0\n }\n function unsafe_field(name) {\n return name ~ /^(trusted|allow-insecure|allow-weak|allow-downgrade-to-insecure)$/\n }\n function disabled_override(value) {\n value = tolower(trim(value))\n gsub(/^[\"\\047]|[\"\\047]$/, \"\", value)\n return value ~ /^(no|false|without|off|disable|0)$/\n }\n function stanza(override_index) {\n override = 0\n for (override_index = 1; override_index <= override_count; override_index++) {\n if (!disabled_override(override_values[override_index])) override = 1\n delete override_values[override_index]\n }\n if (tolower(trim(enabled)) != \"no\" && pgdg) print (trim(suites) == \"\" ? \"-\" : trim(suites)) \"\\t\" (trim(keyring) == \"\" ? \"-\" : trim(keyring)) \"\\t\" (override ? \"unsafe\" : \"safe\")\n enabled = \"\"; pgdg = 0; field = \"\"; suites = \"\"; keyring = \"\"; override = 0; override_count = 0\n }\n /^[[:space:]]*#/ { if (mode == \"list\" || $0 ~ /^#/) next }\n {\n line = $0\n if (mode == \"list\") {\n sub(/[[:space:]]*#.*$/, \"\", line)\n if (line !~ /^[[:space:]]*deb(-src)?[[:space:]]/ || !contains_pgdg(line)) next\n keyring = \"\"; override = 0\n if (match(line, /\\[[^]]*\\]/)) {\n options = substr(line, RSTART + 1, RLENGTH - 2)\n count = split(options, tokens, /[[:space:]]+/)\n for (token_index = 1; token_index <= count; token_index++) {\n if (tolower(tokens[token_index]) ~ /^signed-by=/) { keyring = tokens[token_index]; sub(/^[^=]*=/, \"\", keyring) }\n option_name = tolower(tokens[token_index]); sub(/=.*/, \"\", option_name)\n option_value = tokens[token_index]; sub(/^[^=]*=/, \"\", option_value)\n if (unsafe_field(option_name) && !disabled_override(option_value)) override = 1\n }\n sub(/\\[[^]]*\\]/, \"\", line)\n }\n count = split(line, tokens, /[[:space:]]+/)\n for (token_index = 1; token_index <= count; token_index++) if (pgdg_uri(tokens[token_index])) print (tokens[token_index + 1] == \"\" ? \"-\" : tokens[token_index + 1]) \"\\t\" (keyring == \"\" ? \"-\" : keyring) \"\\t\" (override ? \"unsafe\" : \"safe\")\n next\n }\n if (line ~ /^[[:space:]]*$/) { stanza(); next }\n if (line ~ /^[[:space:]]/) {\n if (field == \"uris\" && contains_pgdg(line)) pgdg = 1\n if (field == \"enabled\") enabled = enabled \" \" line\n if (field == \"suites\") suites = suites \" \" line\n if (field == \"signed-by\") keyring = keyring \" \" line\n if (unsafe_field(field)) override_values[override_count] = override_values[override_count] \" \" line\n next\n }\n field = tolower(line)\n sub(/:.*/, \"\", field)\n value = line\n sub(/^[^:]*:[[:space:]]*/, \"\", value)\n if (field == \"uris\" && contains_pgdg(value)) pgdg = 1\n if (field == \"enabled\") enabled = value\n if (field == \"suites\") suites = value\n if (field == \"signed-by\") keyring = value\n if (unsafe_field(field)) override_values[++override_count] = value\n }\n END { if (mode == \"sources\") stanza() }\n ' \"$file\")\" || fail \"Cannot inspect APT source: $file\"\n if [[ \"$file\" == \"$managed\" && -z \"$records\" ]]; then\n fail \"Managed PGDG source has no active PGDG entry: $file\"\n fi\n while IFS=$'\\t' read -r suite keyring override; do\n [[ -n \"$suite\" ]] || continue\n [[ \"$override\" == safe ]] || fail \"PGDG source enables an unsafe trust override: $file\"\n [[ \"$suite\" == noble-pgdg && \"$keyring\" == /* && ! \"$keyring\" =~ [[:space:],] ]] || fail \"PGDG source requires noble-pgdg and one Signed-By keyring: $file\"\n [[ -z \"$selected_keyring\" || \"$selected_keyring\" == \"$keyring\" ]] || fail \"Conflicting PGDG Signed-By keyrings: $file\"\n fingerprint=\"$(pgdg_key_fingerprint \"$keyring\")\" || fail \"Cannot verify PGDG Signed-By keyring: $file\"\n [[ \"$fingerprint\" == @PGDG_FINGERPRINT@ ]] || fail \"PGDG Signed-By fingerprint mismatch: $file\"\n selected_keyring=\"$keyring\"\n PGDG_SOURCE_STATE=reuse\n done <<< \"$records\"\n done\n}\n`;\n\nconst postgresInstall = String.raw`\n postgres_ready() {\n local binary\n for binary in postgres initdb pg_ctl psql createdb; do\n [[ -x \"/usr/lib/postgresql/@POSTGRES@/bin/$binary\" ]] || return 1\n done\n /usr/lib/postgresql/@POSTGRES@/bin/postgres --version | grep -Eq '^postgres \\(PostgreSQL\\) @POSTGRES@\\.'\n }\n if ! postgres_ready; then\n pgdg_sources_ready /etc/apt/sources.list.d/stll-pgdg.list /etc/apt/sources.list /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources\n if [[ \"$PGDG_SOURCE_STATE\" == missing ]]; then\n local key key_fingerprint\n key=\"$(mktemp)\"\n download_file https://www.postgresql.org/media/keys/ACCC4CF8.asc \"$key\" 45\n key_fingerprint=\"$(pgdg_key_fingerprint \"$key\")\"\n [[ \"$key_fingerprint\" == @PGDG_FINGERPRINT@ ]] || fail 'PostgreSQL signing key mismatch'\n install -d -m 755 /usr/share/keyrings\n install -m 644 \"$key\" /usr/share/keyrings/stll-pgdg.asc\n rm -- \"$key\"\n printf '%s\\n' '@PGDG_SOURCE@' > /etc/apt/sources.list.d/stll-pgdg.list\n fi\n apt_refresh_for postgresql-@POSTGRES@ postgresql-client-@POSTGRES@\n apt_install postgresql-@POSTGRES@ postgresql-client-@POSTGRES@\n fi\n postgres_ready || fail 'PostgreSQL toolchain is incomplete or differs from the policy major'\n`;\n\nconst valkeyInstall = String.raw`\n if ! command -v valkey-server >/dev/null || [[ \"$(valkey-server --version | sed -nE 's/.*v=([0-9.]+).*/\\1/p')\" != '@VALKEY@' ]] || ! command -v valkey-cli >/dev/null || [[ \"$(valkey-cli --version)\" != 'valkey-cli @VALKEY@' ]]; then\n local scratch server_url server_sha tools_url tools_sha package\n scratch=\"$(mktemp -d)\"\n chmod 755 \"$scratch\"\n case \"$ARCH\" in\n amd64) server_url='@AMD64_SERVER_URL@'; server_sha='@AMD64_SERVER_SHA@'; tools_url='@AMD64_TOOLS_URL@'; tools_sha='@AMD64_TOOLS_SHA@' ;;\n arm64) server_url='@ARM64_SERVER_URL@'; server_sha='@ARM64_SERVER_SHA@'; tools_url='@ARM64_TOOLS_URL@'; tools_sha='@ARM64_TOOLS_SHA@' ;;\n *) fail 'Unsupported Valkey architecture' ;;\n esac\n download_file \"$server_url\" \"$scratch/valkey-server.deb\" 120\n download_file \"$tools_url\" \"$scratch/valkey-tools.deb\" 120\n (cd \"$scratch\"; printf '%s %s\\n' \"$server_sha\" valkey-server.deb \"$tools_sha\" valkey-tools.deb | sha256sum --strict -c -)\n for package in valkey-server valkey-tools; do\n [[ \"$(dpkg-deb -f \"$scratch/$package.deb\" Package)\" == \"$package\" ]] || fail 'Valkey artifact package mismatch'\n [[ \"$(dpkg-deb -f \"$scratch/$package.deb\" Version)\" == '@VALKEY@-1.noble' ]] || fail 'Valkey artifact version mismatch'\n [[ \"$(dpkg-deb -f \"$scratch/$package.deb\" Architecture)\" == \"$ARCH\" ]] || fail 'Valkey artifact architecture mismatch'\n done\n apt_refresh_for \"$scratch/valkey-server.deb\" \"$scratch/valkey-tools.deb\"\n apt_install \"$scratch/valkey-server.deb\" \"$scratch/valkey-tools.deb\"\n rm -rf -- \"$scratch\"\n fi\n [[ \"$(valkey-server --version | sed -nE 's/.*v=([0-9.]+).*/\\1/p')\" == '@VALKEY@' ]] || fail 'Valkey version differs from policy'\n [[ \"$(valkey-cli --version)\" == 'valkey-cli @VALKEY@' ]] || fail 'Valkey client version differs from policy'\n`;\n\nconst state = String.raw`\nservice_account_ready() {\n local uid gid shell\n uid=\"$(id -u stll-cloud)\" || fail 'Service user is unavailable; run install'\n gid=\"$(id -g stll-cloud)\"\n shell=\"$(getent passwd stll-cloud | cut -d: -f7)\"\n [[ \"$uid\" =~ ^[1-9][0-9]*$ && \"$gid\" =~ ^[1-9][0-9]*$ && \"$shell\" == /usr/sbin/nologin ]] || fail 'Service user must be unprivileged with no login shell'\n}\nprepare_state() {\n service_account_ready\n [[ ! -L /var/lib/stll-cloud ]] || fail 'Service state root must not be a symlink'\n if [[ -e /var/lib/stll-cloud ]]; then\n [[ -d /var/lib/stll-cloud && \"$(stat -c '%u:%a' /var/lib/stll-cloud)\" == 0:755 ]] || fail 'Invalid service state root'\n else\n install -d -m 755 -o root -g root /var/lib/stll-cloud\n fi\n STATE=\"/var/lib/stll-cloud/$(printf '%s' \"$REPO_ROOT\" | sha256sum | cut -d' ' -f1)\"\n [[ ! -L \"$STATE\" ]] || fail 'Service state must not be a symlink'\n if [[ -e \"$STATE\" ]]; then\n [[ -d \"$STATE\" && \"$(stat -c '%u:%a' \"$STATE\")\" == 0:710 && \"$(stat -c '%g' \"$STATE\")\" == \"$(id -g stll-cloud)\" ]] || fail 'Invalid service state ownership'\n else\n install -d -m 710 -o root -g stll-cloud \"$STATE\"\n fi\n [[ ! -L \"$STATE/lock\" ]] || fail 'Service lock must not be a symlink'\n exec 9>\"$STATE/lock\"\n flock -x -w 10 9 || fail 'Another setup process owns the service state'\n}\n`;\n\nexport const renderCloudServiceInstall = ({\n services,\n postgres,\n valkey,\n valkeyArtifacts,\n}: CloudServiceInstallOptions) => {\n const parts = services.map((service) => {\n switch (service) {\n case \"postgres\":\n return postgresInstall\n .replaceAll(\"@POSTGRES@\", postgres)\n .replaceAll(\"@PGDG_SOURCE@\", postgresSourceLine)\n .replaceAll(\"@PGDG_FINGERPRINT@\", postgresSigningFingerprint);\n case \"valkey\": {\n const replacements = new Map([\n [\"@VALKEY@\", valkey],\n [\"@AMD64_SERVER_URL@\", valkeyArtifacts.amd64.server.url],\n [\"@AMD64_SERVER_SHA@\", valkeyArtifacts.amd64.server.sha256],\n [\"@AMD64_TOOLS_URL@\", valkeyArtifacts.amd64.tools.url],\n [\"@AMD64_TOOLS_SHA@\", valkeyArtifacts.amd64.tools.sha256],\n [\"@ARM64_SERVER_URL@\", valkeyArtifacts.arm64.server.url],\n [\"@ARM64_SERVER_SHA@\", valkeyArtifacts.arm64.server.sha256],\n [\"@ARM64_TOOLS_URL@\", valkeyArtifacts.arm64.tools.url],\n [\"@ARM64_TOOLS_SHA@\", valkeyArtifacts.arm64.tools.sha256],\n ]);\n return valkeyInstall.replace(/@[A-Z0-9_]+@/g, (token) => {\n const value = replacements.get(token);\n if (value === undefined)\n throw new Error(`Missing Valkey artifact field: ${token}`);\n return value;\n });\n }\n default: {\n const exhaustive: never = service;\n throw new Error(`Unsupported service: ${String(exhaustive)}`);\n }\n }\n });\n const user =\n services.length === 0\n ? \"\"\n : \" if ! id stll-cloud >/dev/null 2>&1; then useradd --system --user-group --no-create-home --shell /usr/sbin/nologin stll-cloud; fi\\n service_account_ready\\n\";\n return `${packageInstall}\\n${services.includes(\"postgres\") ? postgresSources.replaceAll(\"@PGDG_FINGERPRINT@\", postgresSigningFingerprint) : \"\"}\\n${services.length === 0 ? \"prepare_state() { :; }\\n\" : state}\\ninstall_services() {\\n${user}${parts.join(\"\")}\\n :\\n}\\n`;\n};\n","/** Shared deadlines cover retries and package-manager subprocesses. */\nexport const renderCloudNetwork = () => String.raw`\nrelease_log_holders() {\n # Processes left by package scripts may still hold a step log after the command exits.\n # Setup starts its own services later, so end them rather than let them write into a\n # deleted log for their whole lifetime.\n # One find over all descriptor links; no process per descriptor.\n local log=\"$1\" root=\"${\"$\"}{CLOUD_PROC_ROOT:-/proc}\" fd pid\n while IFS= read -r fd; do\n pid=\"${\"$\"}{fd%/fd/*}\"\n pid=\"${\"$\"}{pid##*/}\"\n [[ \"$pid\" =~ ^[0-9]+$ && \"$pid\" != \"$$\" ]] || continue\n kill -TERM \"$pid\" 2>/dev/null || true\n done < <(find \"$root\" -mindepth 3 -maxdepth 3 -path \"$root/[0-9]*/fd/*\" -lname \"$log\" 2>/dev/null)\n}\nnetwork_run() (\n local host=\"$1\" seconds=\"$2\" status=0\n shift 2\n network_log=\"$(mktemp)\" || return \"$?\"\n trap 'rm -f -- \"$network_log\"' EXIT\n trap 'exit 129' HUP\n trap 'exit 130' INT\n trap 'exit 143' TERM\n # Output goes to a file, never a pipe: package scripts may leave processes that keep\n # inherited descriptors open, and a pipe reader would wait for them past the command.\n # Input is never the terminal: timeout runs the command outside the foreground process\n # group, where apt restoring terminal settings on a terminal stdin stops it for good.\n timeout --signal=TERM --kill-after=5s \"$seconds\"s \"$@\" < /dev/null > \"$network_log\" 2>&1 || status=$?\n release_log_holders \"$network_log\"\n cat -- \"$network_log\" || fail 'Cannot capture network command output'\n [[ \"$status\" != 0 ]] || return 0\n if [[ \"$status\" == 124 || \"$status\" == 137 || \"$status\" == 28 ]] || grep -Eiq 'timed[[:space:]-]+out|time[[:space:]-]+out|timeout[[:space:]]+(was[[:space:]]+)?(reached|expired)|(connection|operation|socket)[[:space:]-]+timeout' \"$network_log\"; then\n fail \"download timed out: $host\"\n fi\n return \"$status\"\n)\ndownload_file() {\n local url=\"$1\" destination=\"$2\" seconds=\"$3\" host\n host=\"$(printf '%s\\n' \"$url\" | cut -d/ -f3 | sed 's/.*@//')\"\n [[ \"$url\" == https://* && -n \"$host\" ]] || fail 'Downloads require an HTTPS host'\n network_run \"$host\" \"$seconds\" curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' --tlsv1.2 --connect-timeout 20 --max-time \"$seconds\" --retry 3 --retry-all-errors --retry-max-time \"$seconds\" \"$url\" -o \"$destination\"\n}\napt_network() {\n local hosts\n # --print-uris reads configured indexes without contacting their servers.\n hosts=\"$(set -o pipefail; apt-get --print-uris update | awk -F/ '/^\\047https?:\\/\\// { host=$3; sub(/.*@/, \"\", host); if (!seen[host]++) { printf \"%s%s\", separator, host; separator=\",\" } }')\" || return \"$?\"\n [[ -n \"$hosts\" ]] || hosts='configured APT hosts'\n # APT_DEADLINE: whole-call seconds; callers that also unpack packages may extend it.\n network_run \"$hosts\" \"${\"$\"}{APT_DEADLINE:-180}\" apt-get -o Acquire::http::Timeout=20 -o Acquire::https::Timeout=20 -o Acquire::Retries=3 -o APT::Update::Error-Mode=any \"$@\"\n}\napt_refresh_for() {\n # Skip the refresh only when the install downloads nothing: then no package\n # source is contacted and stale cached indexes cannot point at missing files.\n local uris\n if uris=\"$(DEBIAN_FRONTEND=noninteractive apt-get --print-uris -qq -y --no-install-recommends install \"$@\" 2>/dev/null)\" && [[ -z \"$uris\" ]]; then\n return 0\n fi\n apt_network update\n}\n`;\n","import { valid } from \"semver\";\n\nexport type ArchivePins = Readonly<\n Record<string, { readonly amd64: string; readonly arm64: string }>\n>;\n\nconst record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** Parse a map from exact releases to their amd64 and arm64 archive SHA256 values. */\nexport const parseArchiveSha256 = (\n input: unknown,\n label: string,\n): ArchivePins => {\n if (input === undefined) return {};\n if (!record(input)) throw new Error(`${label} must be a version map`);\n const releases: Record<string, { amd64: string; arm64: string }> = {};\n for (const [version, value] of Object.entries(input)) {\n if (valid(version) !== version || !record(value))\n throw new Error(`${label} requires exact release keys`);\n const keys = Object.keys(value);\n if (keys.length !== 2 || !keys.includes(\"amd64\") || !keys.includes(\"arm64\"))\n throw new Error(`${label} ${version} requires amd64 and arm64 pins`);\n const amd64 = value[\"amd64\"];\n const arm64 = value[\"arm64\"];\n if (\n typeof amd64 !== \"string\" ||\n typeof arm64 !== \"string\" ||\n !/^[a-f0-9]{64}$/.test(amd64) ||\n !/^[a-f0-9]{64}$/.test(arm64)\n )\n throw new Error(`${label} ${version} requires lowercase SHA256 pins`);\n releases[version] = { amd64, arm64 };\n }\n return releases;\n};\n","type CloudSetupArtifact = {\n url: `https://${string}`;\n sha256: string;\n archive: \"binary\" | \"tar.gz\";\n binaries: Readonly<Record<string, string>>;\n};\n\ntype CloudSetupArtifactRelease = {\n version: string;\n amd64: CloudSetupArtifact;\n arm64: CloudSetupArtifact;\n};\n\nconst wasmBindgen0126 = {\n version: \"0.2.126\",\n amd64: {\n url: \"https://github.com/wasm-bindgen/wasm-bindgen/releases/download/0.2.126/wasm-bindgen-0.2.126-x86_64-unknown-linux-musl.tar.gz\",\n sha256: \"064948d58e2d6c0a745216477a639ba696216d6309aaa902939d1b865b1d869d\",\n archive: \"tar.gz\",\n binaries: {\n \"wasm-bindgen-test-runner\":\n \"wasm-bindgen-0.2.126-x86_64-unknown-linux-musl/wasm-bindgen-test-runner\",\n wasm2es6js: \"wasm-bindgen-0.2.126-x86_64-unknown-linux-musl/wasm2es6js\",\n \"wasm-bindgen\":\n \"wasm-bindgen-0.2.126-x86_64-unknown-linux-musl/wasm-bindgen\",\n },\n },\n arm64: {\n url: \"https://github.com/wasm-bindgen/wasm-bindgen/releases/download/0.2.126/wasm-bindgen-0.2.126-aarch64-unknown-linux-musl.tar.gz\",\n sha256: \"2245120254a9f6c9a9adf3601f3d52bb31309219e9ceab7696e74e24885c440a\",\n archive: \"tar.gz\",\n binaries: {\n \"wasm-bindgen-test-runner\":\n \"wasm-bindgen-0.2.126-aarch64-unknown-linux-musl/wasm-bindgen-test-runner\",\n wasm2es6js: \"wasm-bindgen-0.2.126-aarch64-unknown-linux-musl/wasm2es6js\",\n \"wasm-bindgen\":\n \"wasm-bindgen-0.2.126-aarch64-unknown-linux-musl/wasm-bindgen\",\n },\n },\n} as const satisfies CloudSetupArtifactRelease;\n\n/** Pinned upstream Linux artifacts, verified against their published SHA-256 sums. */\nexport const cloudSetupArtifacts = {\n \"rustup-init\": {\n version: \"1.29.1\",\n amd64: {\n url: \"https://static.rust-lang.org/rustup/archive/1.29.1/x86_64-unknown-linux-gnu/rustup-init\",\n sha256:\n \"dda7234360b7f578ca8b0ddcb80145646fa61a67c1720a5abc7051b35c9fcb71\",\n archive: \"binary\",\n binaries: {\n \"rustup-init\": \"rustup-init\",\n },\n },\n arm64: {\n url: \"https://static.rust-lang.org/rustup/archive/1.29.1/aarch64-unknown-linux-gnu/rustup-init\",\n sha256:\n \"15f6e4ce9f583b929c996c91562bad6d4454f3281de858b02cdfdef615fac433\",\n archive: \"binary\",\n binaries: {\n \"rustup-init\": \"rustup-init\",\n },\n },\n },\n gitleaks: {\n version: \"8.30.1\",\n amd64: {\n url: \"https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz\",\n sha256:\n \"551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb\",\n archive: \"tar.gz\",\n binaries: { gitleaks: \"gitleaks\" },\n },\n arm64: {\n url: \"https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_arm64.tar.gz\",\n sha256:\n \"e4a487ee7ccd7d3a7f7ec08657610aa3606637dab924210b3aee62570fb4b080\",\n archive: \"tar.gz\",\n binaries: { gitleaks: \"gitleaks\" },\n },\n },\n \"cargo-nextest\": {\n version: \"0.9.148\",\n amd64: {\n url: \"https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-0.9.148/cargo-nextest-0.9.148-x86_64-unknown-linux-musl.tar.gz\",\n sha256:\n \"bf92cb81450872d960ffa13857a83084d557ec0cdc141663d263bb23ef756f97\",\n archive: \"tar.gz\",\n binaries: {\n \"cargo-nextest\": \"cargo-nextest\",\n },\n },\n arm64: {\n url: \"https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-0.9.148/cargo-nextest-0.9.148-aarch64-unknown-linux-musl.tar.gz\",\n sha256:\n \"94676506ceaed01746d78cfe9ed124ee841b2932fd18d9d10f438a347bd9ba5e\",\n archive: \"tar.gz\",\n binaries: {\n \"cargo-nextest\": \"cargo-nextest\",\n },\n },\n },\n \"wasm-bindgen-cli\": {\n version: \"0.2.129\",\n amd64: {\n url: \"https://github.com/wasm-bindgen/wasm-bindgen/releases/download/0.2.129/wasm-bindgen-0.2.129-x86_64-unknown-linux-musl.tar.gz\",\n sha256:\n \"82d12bb940e2d4e72e0d5605387fc1b8ca179044e012b620f0ce4e7440e8320e\",\n archive: \"tar.gz\",\n binaries: {\n \"wasm-bindgen-test-runner\":\n \"wasm-bindgen-0.2.129-x86_64-unknown-linux-musl/wasm-bindgen-test-runner\",\n wasm2es6js: \"wasm-bindgen-0.2.129-x86_64-unknown-linux-musl/wasm2es6js\",\n \"wasm-bindgen\":\n \"wasm-bindgen-0.2.129-x86_64-unknown-linux-musl/wasm-bindgen\",\n },\n },\n arm64: {\n url: \"https://github.com/wasm-bindgen/wasm-bindgen/releases/download/0.2.129/wasm-bindgen-0.2.129-aarch64-unknown-linux-musl.tar.gz\",\n sha256:\n \"2ed4351c35dd9440308bbb02767d47ea278efe851a52465300f3c94f5b6c2a87\",\n archive: \"tar.gz\",\n binaries: {\n \"wasm-bindgen-test-runner\":\n \"wasm-bindgen-0.2.129-aarch64-unknown-linux-musl/wasm-bindgen-test-runner\",\n wasm2es6js:\n \"wasm-bindgen-0.2.129-aarch64-unknown-linux-musl/wasm2es6js\",\n \"wasm-bindgen\":\n \"wasm-bindgen-0.2.129-aarch64-unknown-linux-musl/wasm-bindgen\",\n },\n },\n },\n uv: {\n version: \"0.13.1\",\n amd64: {\n url: \"https://github.com/astral-sh/uv/releases/download/0.13.1/uv-x86_64-unknown-linux-musl.tar.gz\",\n sha256:\n \"6c86040a8f045ab9adc9e3ec4cdafa03fd00e9a988ed2bf28971c7fc2d0debd0\",\n archive: \"tar.gz\",\n binaries: {\n uv: \"uv-x86_64-unknown-linux-musl/uv\",\n uvx: \"uv-x86_64-unknown-linux-musl/uvx\",\n },\n },\n arm64: {\n url: \"https://github.com/astral-sh/uv/releases/download/0.13.1/uv-aarch64-unknown-linux-musl.tar.gz\",\n sha256:\n \"345a8308e4d1835cdfaadf692836fd3137a6d45864773f05ad7bf59442b1ba16\",\n archive: \"tar.gz\",\n binaries: {\n uv: \"uv-aarch64-unknown-linux-musl/uv\",\n uvx: \"uv-aarch64-unknown-linux-musl/uvx\",\n },\n },\n },\n} as const satisfies Record<string, CloudSetupArtifactRelease>;\n\nexport type CloudSetupArtifactTool = keyof typeof cloudSetupArtifacts;\nexport type CloudSetupArchitecture = keyof Omit<\n (typeof cloudSetupArtifacts)[CloudSetupArtifactTool],\n \"version\"\n>;\n\n/** Explicit releases whose CLI must match a project's wasm-bindgen crate exactly. */\nexport const wasmBindgenArtifactReleases = [\n wasmBindgen0126,\n cloudSetupArtifacts[\"wasm-bindgen-cli\"],\n] as const;\n\n/** Every supported version participates in lookup and catalog validation. */\nexport const cloudSetupArtifactVersions = {\n \"rustup-init\": [cloudSetupArtifacts[\"rustup-init\"]],\n \"cargo-nextest\": [cloudSetupArtifacts[\"cargo-nextest\"]],\n \"wasm-bindgen-cli\": wasmBindgenArtifactReleases,\n uv: [cloudSetupArtifacts.uv],\n gitleaks: [cloudSetupArtifacts.gitleaks],\n} as const satisfies Record<\n CloudSetupArtifactTool,\n readonly CloudSetupArtifactRelease[]\n>;\n\n/** A new version requires an explicit, verified catalog entry; never build from source. */\nexport const getCloudSetupArtifact = (\n tool: CloudSetupArtifactTool,\n version: string,\n) => {\n const releases = cloudSetupArtifactVersions[tool];\n const artifact = releases.find((release) => release.version === version);\n if (artifact === undefined)\n throw new Error(\n `Unsupported ${tool} version ${version}; supported versions: ${releases.map((release) => release.version).join(\", \")}`,\n );\n return artifact;\n};\n\ntype CloudSetupPackage = {\n version: string;\n package: string;\n binary: `/${string}`;\n identity: string;\n};\n\n/** Ubuntu 24.04 packages; apt resolves them from the image's configured sources. */\nexport const cloudSetupPackages = {\n // GNU time reports \"UNKNOWN\" as its version; dpkg records the upstream release.\n time: {\n version: \"1.9\",\n package: \"time\",\n binary: \"/usr/bin/time\",\n identity: \"time (GNU Time) \",\n },\n} as const satisfies Record<string, CloudSetupPackage>;\n\nexport type CloudSetupPackageTool = keyof typeof cloudSetupPackages;\n\n/** Ubuntu 24.04 ships one release per package; other versions are unsupported. */\nexport const getCloudSetupPackage = (\n tool: CloudSetupPackageTool,\n version: string,\n) => {\n const release = cloudSetupPackages[tool];\n if (release.version !== version)\n throw new Error(\n `Unsupported ${tool} version ${version}; supported versions: ${release.version}`,\n );\n return release;\n};\n","import { type ArchivePins, parseArchiveSha256 } from \"./archive-pins\";\nimport {\n cloudSetupArtifacts,\n type CloudSetupArtifactTool,\n cloudSetupPackages,\n type CloudSetupPackageTool,\n} from \"./cloud-setup-artifacts\";\n\nexport const cloudServices = [\"postgres\", \"valkey\"] as const;\nexport type CloudService = (typeof cloudServices)[number];\nexport type CloudArtifactTool = Exclude<CloudSetupArtifactTool, \"rustup-init\">;\nexport const cloudArtifactTools = Object.keys(cloudSetupArtifacts).filter(\n (tool): tool is CloudArtifactTool =>\n tool !== \"rustup-init\" && Object.hasOwn(cloudSetupArtifacts, tool),\n);\nexport const cloudPackageTools = Object.keys(cloudSetupPackages).filter(\n (tool): tool is CloudSetupPackageTool =>\n Object.hasOwn(cloudSetupPackages, tool),\n);\nexport type CloudExtraTool = CloudArtifactTool | CloudSetupPackageTool;\nexport const cloudExtraTools = [...cloudArtifactTools, ...cloudPackageTools];\nexport const isCloudPackageTool = (\n tool: string,\n): tool is CloudSetupPackageTool =>\n cloudPackageTools.some((candidate) => candidate === tool);\n\nconst object = (input: unknown): input is Record<string, unknown> =>\n typeof input === \"object\" && input !== null && !Array.isArray(input);\nconst exactPin = (input: unknown): input is string =>\n typeof input === \"string\" &&\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)$/.test(input);\n// Upstream releases of distribution packages may omit the patch component.\nconst exactToolPin = (tool: CloudExtraTool, input: unknown): input is string =>\n isCloudPackageTool(tool)\n ? typeof input === \"string\" &&\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:\\.(?:0|[1-9]\\d*))?$/.test(input)\n : exactPin(input);\n\nexport const cloudRustComponentBinaries = {\n clippy: [\"cargo-clippy\", \"clippy-driver\"],\n rustfmt: [\"rustfmt\", \"cargo-fmt\"],\n \"rust-src\": [],\n \"rust-analyzer\": [\"rust-analyzer\"],\n} as const;\nexport const parseCloudRustNames = (\n input: unknown,\n kind: \"components\" | \"targets\",\n) => {\n const label = `cloud Rust ${kind}`;\n if (input === undefined) return [];\n if (!Array.isArray(input)) throw new Error(`${label} must be an array`);\n const result = input.map((value: unknown) => {\n if (typeof value !== \"string\" || !/^[a-z][a-z0-9_-]*$/.test(value))\n throw new Error(`${label} requires canonical names`);\n if (\n kind === \"components\" &&\n !Object.hasOwn(cloudRustComponentBinaries, value)\n )\n throw new Error(`${label} contains an unsupported component: ${value}`);\n return value;\n });\n if (new Set(result).size !== result.length)\n throw new Error(`${label} contains duplicates`);\n return result;\n};\nconst parseRust = (input: unknown) => {\n if (input === undefined) return undefined;\n if (\n !object(input) ||\n Object.keys(input).some(\n (key) =>\n ![\n \"toolchain\",\n \"components\",\n \"targets\",\n \"additionalToolchains\",\n ].includes(key),\n )\n )\n throw new Error(\n \"cloud.rust accepts only toolchain, components, targets and additionalToolchains\",\n );\n const toolchain = input[\"toolchain\"];\n if (toolchain !== undefined && !exactPin(toolchain))\n throw new Error(\"cloud.rust.toolchain must be an exact stable release\");\n const additional = input[\"additionalToolchains\"];\n if (additional !== undefined && !Array.isArray(additional))\n throw new Error(\n \"cloud.rust.additionalToolchains requires exact stable releases\",\n );\n const additionalToolchains =\n additional === undefined\n ? []\n : Array.from(additional, (pin: unknown) => {\n if (!exactPin(pin))\n throw new Error(\n \"cloud.rust.additionalToolchains requires exact stable releases\",\n );\n return pin;\n });\n if (new Set(additionalToolchains).size !== additionalToolchains.length)\n throw new Error(\"cloud.rust.additionalToolchains contains duplicates\");\n return {\n additionalToolchains,\n ...(toolchain === undefined ? {} : { toolchain }),\n components: parseCloudRustNames(input[\"components\"], \"components\"),\n targets: parseCloudRustNames(input[\"targets\"], \"targets\"),\n };\n};\nconst parseTools = (input: unknown) => {\n if (input === undefined) return undefined;\n if (\n !object(input) ||\n Object.keys(input).some(\n (key) => !cloudExtraTools.some((tool) => tool === key),\n )\n )\n throw new Error(`cloud.tools accepts only ${cloudExtraTools.join(\", \")}`);\n const result: Partial<Record<CloudExtraTool, string>> = {};\n for (const tool of cloudExtraTools) {\n const pin = input[tool];\n if (pin === undefined) {\n if (Object.hasOwn(input, tool))\n throw new Error(`cloud.tools.${tool} must be an exact stable release`);\n continue;\n }\n if (!exactToolPin(tool, pin))\n throw new Error(`cloud.tools.${tool} must be an exact stable release`);\n result[tool] = pin;\n }\n return result;\n};\n\n// A repository that selects a Node patch or Bun release the shared policy\n// does not pin records the official archive SHA256 values itself, bound to\n// that exact release.\nconst cloudRuntimes = [\"node\", \"bun\"] as const;\nconst parseRuntimeArchives = (input: unknown) => {\n if (input === undefined) return undefined;\n if (\n !object(input) ||\n Object.keys(input).some(\n (key) => !cloudRuntimes.some((runtime) => runtime === key),\n )\n )\n throw new Error(\"cloud.runtimeArchiveSha256 accepts only node and bun\");\n const result: Partial<Record<(typeof cloudRuntimes)[number], ArchivePins>> =\n {};\n for (const runtime of cloudRuntimes) {\n if (!Object.hasOwn(input, runtime)) continue;\n const label = `cloud.runtimeArchiveSha256.${runtime}`;\n const pins = parseArchiveSha256(input[runtime], label);\n if (Object.keys(pins).length !== 1)\n throw new Error(`${label} pins exactly one release`);\n result[runtime] = pins;\n }\n return result;\n};\n\nexport const cloudInstallCommand = \"bun install --frozen-lockfile\";\n// Lifecycle scripts (postinstall code generation) can outlast a cloud setup\n// budget; a repository opts out and lets tasks generate what they need.\nexport const cloudInstallCommands = [\n cloudInstallCommand,\n `${cloudInstallCommand} --ignore-scripts`,\n] as const;\nexport type CloudInstallCommand = (typeof cloudInstallCommands)[number];\n\nconst cloudInstall = (value: unknown): value is CloudInstallCommand =>\n cloudInstallCommands.some((command) => value === command);\n\nconst cloudService = (value: unknown): value is CloudService =>\n cloudServices.some((service) => value === service);\n\nconst parseEnvFile = (input: object) => {\n if (!(\"envFile\" in input) || typeof input.envFile !== \"string\")\n throw new Error(\n \"cloud.envFile must be a canonical repository-relative path\",\n );\n const envFile = input.envFile;\n if (\n envFile.startsWith(\"/\") ||\n /^[A-Za-z]:/.test(envFile) ||\n envFile.includes(\"\\\\\") ||\n /\\p{Cc}/u.test(envFile) ||\n envFile\n .split(\"/\")\n .some((part) => part === \"\" || part === \".\" || part === \"..\")\n )\n throw new Error(\n \"cloud.envFile must be a canonical repository-relative path\",\n );\n return envFile;\n};\n\n// One package script the install snapshot runs after dependencies, for\n// derived sources a repository's tasks need but its install skips (for\n// example with --ignore-scripts). It is offline work, so it gets a hard\n// time bound instead of a network allowance.\nexport const cloudPrepareMaxSeconds = 900;\nconst cloudPrepareScript = /^[a-z0-9][a-z0-9:._-]*$/;\n\nconst parsePrepare = (input: unknown) => {\n if (input === undefined) return undefined;\n if (typeof input !== \"object\" || input === null || Array.isArray(input))\n throw new Error(\"cloud.prepare must be an object\");\n for (const key of Object.keys(input))\n if (key !== \"script\" && key !== \"seconds\")\n throw new Error(`unsupported cloud.prepare key: ${key}`);\n const script = \"script\" in input ? input.script : undefined;\n if (typeof script !== \"string\" || !cloudPrepareScript.test(script))\n throw new Error(\"cloud.prepare.script must name a package script\");\n const seconds = \"seconds\" in input ? input.seconds : undefined;\n if (\n typeof seconds !== \"number\" ||\n !Number.isInteger(seconds) ||\n seconds < 1 ||\n seconds > cloudPrepareMaxSeconds\n )\n throw new Error(\n `cloud.prepare.seconds must be an integer from 1 to ${cloudPrepareMaxSeconds}`,\n );\n return { script, seconds } as const;\n};\n\n/** Parse an explicit declaration without assuming services for undeclared repositories. */\nexport const parseCloudSetup = (input: unknown) => {\n if (input === undefined) return undefined;\n if (typeof input !== \"object\" || input === null || Array.isArray(input))\n throw new Error(\"cloud must be an object\");\n for (const key of Object.keys(input))\n if (\n key !== \"services\" &&\n key !== \"install\" &&\n key !== \"envFile\" &&\n key !== \"rust\" &&\n key !== \"tools\" &&\n key !== \"prepare\" &&\n key !== \"submodules\" &&\n key !== \"runtimeArchiveSha256\"\n )\n throw new Error(`unsupported cloud key: ${key}`);\n const rust = parseRust(\"rust\" in input ? input.rust : undefined);\n const tools = parseTools(\"tools\" in input ? input.tools : undefined);\n const prepare = parsePrepare(\"prepare\" in input ? input.prepare : undefined);\n const runtimeArchiveSha256 = parseRuntimeArchives(\n \"runtimeArchiveSha256\" in input ? input.runtimeArchiveSha256 : undefined,\n );\n const submodules = \"submodules\" in input ? input.submodules : false;\n if (typeof submodules !== \"boolean\")\n throw new Error(\"cloud.submodules must be a boolean when provided\");\n const extensions = {\n ...(rust === undefined ? {} : { rust }),\n ...(tools === undefined ? {} : { tools }),\n ...(prepare === undefined ? {} : { prepare }),\n ...(runtimeArchiveSha256 === undefined ? {} : { runtimeArchiveSha256 }),\n };\n const selected = \"services\" in input ? input.services : [];\n if (!Array.isArray(selected))\n throw new Error(\"cloud.services must be an array when provided\");\n if (!(\"install\" in input) || !cloudInstall(input.install))\n throw new Error(\n `cloud.install must be exactly one of: ${cloudInstallCommands.join(\", \")}`,\n );\n const install = input.install;\n const seen = new Set<CloudService>();\n const services = Array.from(selected, (service: unknown) => {\n if (!cloudService(service))\n throw new Error(\"cloud.services contains an unsupported service\");\n if (seen.has(service))\n throw new Error(`cloud.services contains duplicate service: ${service}`);\n seen.add(service);\n return service;\n });\n if (services.length === 0 && \"envFile\" in input)\n throw new Error(\"cloud.envFile is not allowed without services\");\n return {\n services,\n install,\n ...(submodules ? { submodules } : {}),\n ...extensions,\n ...(services.length === 0 ? {} : { envFile: parseEnvFile(input) }),\n } as const;\n};\n","import type { CloudService } from \"./cloud-setup-schema\";\n\ntype CloudServiceStartOptions = {\n services: readonly CloudService[];\n postgres: string;\n valkey: string;\n};\n\nconst common = String.raw`\nservice_file() {\n local file=\"$1\" owner=\"$2\"\n [[ ! -L \"$file\" ]] || fail \"Service state must not contain symbolic links\"\n if [[ -e \"$file\" ]]; then\n [[ -f \"$file\" && \"$(stat -c '%u:%a' \"$file\")\" == \"$owner:600\" ]] || fail \"Invalid service state file\"\n fi\n}\nservice_directory() {\n local directory=\"$1\"\n [[ ! -L \"$directory\" ]] || fail \"Service directory must not be a symbolic link\"\n if [[ -e \"$directory\" ]]; then\n [[ -d \"$directory\" && \"$(stat -c '%u:%a' \"$directory\")\" == \"$SERVICE_UID:700\" ]] || fail \"Invalid service directory\"\n else\n root install -d -m 700 -o stll-cloud -g stll-cloud \"$directory\"\n fi\n}\nservice_password() {\n local file=\"$1\"\n service_file \"$file\" 0\n if [[ ! -e \"$file\" ]]; then\n (umask 077; openssl rand -hex 32 > \"$file\")\n root chown root:root \"$file\"\n fi\n [[ \"$(cat \"$file\")\" =~ ^[0-9a-f]{64}$ ]] || fail \"Invalid service credential state\"\n}\nservice_process_matches() {\n local pid=\"$1\" executable=\"$2\" owner actual expected\n [[ \"$pid\" =~ ^[1-9][0-9]*$ && -d \"/proc/$pid\" ]] || return 1\n owner=\"$(stat -c '%u' \"/proc/$pid\" 2>/dev/null)\" || return 2\n [[ \"$owner\" =~ ^[0-9]+$ ]] || return 2\n [[ \"$owner\" == \"$SERVICE_UID\" ]] || return 1\n # Read the executable link as its verified owner: container root may lack the ptrace\n # capability that reading another user's /proc/<pid>/exe requires.\n actual=\"$(service_run readlink -f \"/proc/$pid/exe\" 2>/dev/null)\" || return 2\n expected=\"$(readlink -f \"$executable\")\" || return 2\n [[ -n \"$actual\" && -n \"$expected\" && \"$actual\" != *' (deleted)' ]] || return 2\n [[ \"$actual\" == \"$expected\" ]]\n}\nservice_process() {\n service_process_matches \"$1\" \"$2\" || fail \"Managed service process identity differs from the recorded state\"\n}\nservice_prune_pid() {\n local file=\"$1\" executable=\"$2\" service=\"$3\" pid identity\n [[ -e \"$file\" ]] || return 0\n pid=\"$(head -n 1 \"$file\")\"\n # PostgreSQL encodes a standalone backend with a negative PID.\n if [[ \"$service\" == postgres ]]; then pid=\"$(printf '%s' \"$pid\" | sed 's/^-//')\"; fi\n if service_process_matches \"$pid\" \"$executable\"; then return 0; else identity=$?; fi\n [[ \"$identity\" != 2 ]] || fail \"Cannot verify recorded live service process; retaining its PID file\"\n # Let PostgreSQL check orphan shared memory before removing a dead-PID lock.\n if [[ \"$service\" == postgres && \"$pid\" =~ ^[1-9][0-9]*$ && ! -d \"/proc/$pid\" ]]; then return 0; fi\n if [[ \"$service\" == postgres ]]; then\n [[ \"$pid\" =~ ^[1-9][0-9]*$ && \"$SERVICE_UID\" != 0 ]] || fail \"Cannot safely recover PostgreSQL PID state\"\n # The root controller is not our nonroot postgres. Preserve the remaining\n # lock rows so PostgreSQL's EPERM/ancestor path still checks orphan memory.\n root sed -i \"1s/.*/$$/\" \"$file\"\n return 0\n fi\n # Restored state can name an unrelated live process; never signal that PID.\n root rm -- \"$file\"\n}\n`;\n\nconst postgresStart = String.raw`\n local pg_bin='/usr/lib/postgresql/@POSTGRES@/bin' pg_data=\"$STATE/postgres\" pg_password pg_details pg_pid pg_version pg_state='already running'\n service_password \"$STATE/postgres.password\"\n pg_password=\"$(cat \"$STATE/postgres.password\")\"\n service_directory \"$pg_data\"\n for file in PG_VERSION postmaster.pid postgresql.conf pg_hba.conf pg_ident.conf postgresql.auto.conf; do\n service_file \"$pg_data/$file\" \"$SERVICE_UID\"\n done\n if [[ ! -e \"$pg_data/PG_VERSION\" ]]; then\n [[ -z \"$(ls -A \"$pg_data\")\" ]] || fail \"PostgreSQL data directory is not initialized\"\n service_file \"$STATE/postgres.init-password\" \"$SERVICE_UID\"\n (umask 077; printf '%s\\n' \"$pg_password\" > \"$STATE/postgres.init-password\")\n root chown stll-cloud:stll-cloud \"$STATE/postgres.init-password\"\n service_run env PGHOST=127.0.0.1 PGHOSTADDR=127.0.0.1 \"$pg_bin/initdb\" -D \"$pg_data\" --username=stll_cloud --auth-host=scram-sha-256 --auth-local=scram-sha-256 --pwfile=\"$STATE/postgres.init-password\" --encoding=UTF8 --locale=C --set=unix_socket_directories= >/dev/null || fail \"PostgreSQL initialization failed\"\n root rm \"$STATE/postgres.init-password\"\n fi\n [[ -f \"$pg_data/PG_VERSION\" && \"$(cat \"$pg_data/PG_VERSION\")\" == '@POSTGRES@' ]] || fail \"PostgreSQL data has a different major version\"\n service_prune_pid \"$pg_data/postmaster.pid\" \"$pg_bin/postgres\" postgres\n if ! service_run env PGHOST=127.0.0.1 PGHOSTADDR=127.0.0.1 \"$pg_bin/pg_ctl\" -D \"$pg_data\" status >/dev/null 2>&1; then\n service_run env PGHOST=127.0.0.1 PGHOSTADDR=127.0.0.1 \"$pg_bin/pg_ctl\" -D \"$pg_data\" -l \"$pg_data/cloud.log\" -o \"-h 127.0.0.1 -p 55432 -c unix_socket_directories=\" -t 10 -w start >/dev/null || fail \"PostgreSQL start failed; port 55432 must be available\"\n pg_state=started\n fi\n pg_details=\"$(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 current_setting('data_directory'), current_setting('listen_addresses'), current_setting('port'), current_setting('server_version_num'), current_setting('unix_socket_directories')\")\" || fail \"PostgreSQL authenticated readiness failed\"\n pg_version=\"$(printf '%s\\n' \"$pg_details\" | cut -d '|' -f4)\"\n [[ \"$pg_details\" == \"$pg_data|127.0.0.1|55432|$pg_version|\" && \"$pg_version\" =~ ^[0-9]{6}$ ]] || fail \"PostgreSQL endpoint does not match managed data and listener\"\n (( pg_version / 10000 == @POSTGRES@ )) || fail \"PostgreSQL endpoint has a different major version\"\n pg_pid=\"$(head -n 1 \"$pg_data/postmaster.pid\")\"\n service_process \"$pg_pid\" \"$pg_bin/postgres\"\n [[ \"$(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\"\n POSTGRES_HOST='127.0.0.1:55432'\n POSTGRES_USER='stll_cloud'\n POSTGRES_PASSWORD=\"$pg_password\"\n POSTGRES_DB_NAME='cloud_test'\n POSTGRES_ADDITIONAL_CONNECTION_DATA=''\n DATABASE_URL=\"postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/$POSTGRES_DB_NAME$POSTGRES_ADDITIONAL_CONNECTION_DATA\"\n printf 'postgres: %s\\n' \"$pg_state\"\n`;\n\nconst valkeyStart = String.raw`\n local vk_data=\"$STATE/valkey\" vk_password vk_config vk_info vk_pid vk_expected ready=0 vk_state='already running'\n service_password \"$STATE/valkey.password\"\n vk_password=\"$(cat \"$STATE/valkey.password\")\"\n service_directory \"$vk_data\"\n vk_config=\"$vk_data/valkey.conf\"\n service_file \"$vk_config\" \"$SERVICE_UID\"\n for file in valkey.pid valkey.log dump.rdb; do\n [[ ! -L \"$vk_data/$file\" ]] || fail \"Valkey state must not contain symbolic links\"\n if [[ -e \"$vk_data/$file\" ]]; then\n [[ -f \"$vk_data/$file\" && \"$(stat -c '%u' \"$vk_data/$file\")\" == \"$SERVICE_UID\" ]] || fail \"Invalid Valkey state file\"\n fi\n done\n vk_expected=\"$(printf '%s\\n' 'bind 127.0.0.1' 'port 56379' 'protected-mode yes' 'daemonize yes' \"requirepass $vk_password\" \"dir $vk_data\" \"pidfile $vk_data/valkey.pid\" \"logfile $vk_data/valkey.log\" 'save \"\"' 'appendonly no')\"\n if [[ ! -e \"$vk_config\" ]]; then\n (umask 077; printf '%s\\n' \"$vk_expected\" > \"$vk_config\")\n root chown stll-cloud:stll-cloud \"$vk_config\"\n fi\n [[ \"$(cat \"$vk_config\")\" == \"$vk_expected\" ]] || fail \"Valkey configuration differs from managed settings\"\n service_prune_pid \"$vk_data/valkey.pid\" \"$(command -v valkey-server)\" valkey\n if [[ ! -e \"$vk_data/valkey.pid\" ]]; then\n service_run valkey-server \"$vk_config\" >/dev/null || fail \"Valkey start failed; port 56379 must be available\"\n vk_state=started\n fi\n for ((attempt=0; attempt<20; attempt++)); do\n if vk_info=\"$(VALKEYCLI_AUTH=\"$vk_password\" timeout 0.2 valkey-cli -h 127.0.0.1 -p 56379 --raw INFO server 2>/dev/null)\"; then\n if [[ \"$vk_info\" == *$'valkey_version:@VALKEY@\\r\\n'* && \"$vk_info\" == *\"config_file:$vk_config\"$'\\r\\n'* ]]; then ready=1; break; fi\n fi\n sleep 0.25\n done\n [[ \"$ready\" == 1 ]] || fail \"Valkey authenticated readiness or managed version/configuration check failed\"\n [[ -f \"$vk_data/valkey.pid\" ]] || fail \"Valkey managed process identifier is unavailable\"\n vk_pid=\"$(cat \"$vk_data/valkey.pid\")\"\n service_process \"$vk_pid\" \"$(command -v valkey-server)\"\n [[ \"$vk_info\" == *\"process_id:$vk_pid\"$'\\r\\n'* ]] || fail \"Valkey endpoint has a different process identifier\"\n [[ \"$(VALKEYCLI_AUTH=\"$vk_password\" timeout 2 valkey-cli -h 127.0.0.1 -p 56379 --raw CONFIG GET bind)\" == $'bind\\n127.0.0.1' ]] || fail \"Valkey endpoint must bind only loopback\"\n [[ \"$(VALKEYCLI_AUTH=\"$vk_password\" timeout 2 valkey-cli -h 127.0.0.1 -p 56379 --raw CONFIG GET dir)\" == \"$(printf 'dir\\n%s' \"$vk_data\")\" ]] || fail \"Valkey endpoint has a different data directory\"\n REDIS_URL=\"redis://:$vk_password@127.0.0.1:56379/0\"\n printf 'valkey: %s\\n' \"$vk_state\"\n`;\n\n/** Render only declared services; installation and environment-file ownership stay with the caller. */\nexport const renderCloudServiceStart = ({\n services,\n postgres,\n valkey,\n}: CloudServiceStartOptions): string => {\n if (!/^[1-9][0-9]*$/.test(postgres) || !/^\\d+\\.\\d+\\.\\d+$/.test(valkey))\n throw new Error(\"Invalid cloud service runtime policy\");\n if (services.length === 0) return \"start_services() { :; }\\n\";\n const bodies = services.map((service) => {\n switch (service) {\n case \"postgres\":\n return postgresStart.replaceAll(\"@POSTGRES@\", postgres);\n case \"valkey\":\n return valkeyStart.replaceAll(\"@VALKEY@\", valkey);\n default: {\n const exhaustive: never = service;\n throw new Error(`Unsupported cloud service: ${String(exhaustive)}`);\n }\n }\n });\n return `${common}\\nstart_services() {\\n local SERVICE_UID file attempt\\n SERVICE_UID=\"$(id -u stll-cloud)\"\\n [[ -d \"$STATE\" && ! -L \"$STATE\" && \"$(stat -c '%u' \"$STATE\")\" == 0 ]] || fail \"Invalid cloud service state directory\"\\n${bodies.join(\"\")}\\n}\\n`;\n};\n","import { createHash } from \"node:crypto\";\n\nimport type { resolveCloudToolchains } from \"./cloud-setup-toolchains\";\n\nexport const cloudShellProfilePath = \"/etc/profile.d/stll-cloud.sh\";\nexport const cloudShellProfileSource = `. ${cloudShellProfilePath}`;\n\nconst quote = (value: string) => `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\ntype CloudShellOptions = {\n nodeVersion: string;\n bunVersion: string;\n rust: ReturnType<typeof resolveCloudToolchains>[\"rust\"];\n};\n\nexport const renderCloudShellProfile = ({\n nodeVersion,\n bunVersion,\n rust,\n}: CloudShellOptions) => {\n const node = `/opt/stll-cloud/node/${nodeVersion}/bin`;\n const bun = `/opt/stll-cloud/bun/${bunVersion}`;\n return `# Generated by stll-cloud-setup; managed cloud shell environment.\n# Remove managed entries before prepending, including repeated shell startup.\n_stll_cloud_remaining=\"\\${PATH-}\"\n_stll_cloud_result=''\n_stll_cloud_separator=''\nwhile :; do\n case \"$_stll_cloud_remaining\" in\n *:*) _stll_cloud_part=\"\\${_stll_cloud_remaining%%:*}\"; _stll_cloud_remaining=\"\\${_stll_cloud_remaining#*:}\"; _stll_cloud_more=yes ;;\n *) _stll_cloud_part=\"$_stll_cloud_remaining\"; _stll_cloud_more=no ;;\n esac\n case \"$_stll_cloud_part\" in\n ${quote(node)}|${quote(bun)}|/usr/local/bin) ;;\n *) _stll_cloud_result=\"$_stll_cloud_result$_stll_cloud_separator$_stll_cloud_part\"; _stll_cloud_separator=: ;;\n esac\n [ \"$_stll_cloud_more\" = yes ] || break\ndone\nexport PATH=${quote(`${node}:${bun}:/usr/local/bin`)}\"\\${_stll_cloud_separator:+:}$_stll_cloud_result\"\nunset _stll_cloud_remaining _stll_cloud_result _stll_cloud_separator _stll_cloud_part _stll_cloud_more\n${rust === undefined ? \"\" : `export RUSTUP_HOME=/opt/stll-cloud/rustup\\nexport CARGO_HOME=/opt/stll-cloud/cargo\\nexport RUSTUP_TOOLCHAIN=${quote(rust.channel)}\\nexport RUSTUP_AUTO_INSTALL=0\\n`}`;\n};\n\nconst userStartup = String.raw`\nset -euo pipefail\nfor name in .bashrc .profile .bash_profile .bash_login; do\n file=\"$HOME/$name\"\n if [[ ! -e \"$file\" && ! -L \"$file\" && \"$name\" != .bashrc && \"$name\" != .profile ]]; then continue; fi\n [[ ! -L \"$file\" ]] || { echo \"cloud-setup: shell startup file must not be a symlink: $name\" >&2; exit 1; }\n if [[ -e \"$file\" ]]; then\n [[ -f \"$file\" && \"$(stat -c '%h:%u' \"$file\")\" == \"1:$(id -u)\" ]] || { echo \"cloud-setup: shell startup file must be owned and single-link: $name\" >&2; exit 1; }\n fi\n temporary=\"$(mktemp \"$HOME/.stll-cloud-shell.XXXXXX\")\"\n trap 'rm -f -- \"$temporary\"' EXIT\n if [[ \"$name\" == .bashrc ]]; then\n printf '%s\\n' '# stll-cloud: early environment' '@SOURCE@' > \"$temporary\"\n fi\n if [[ -f \"$file\" ]]; then\n # Remove only exact managed blocks; preserve unrelated startup lines and permissions.\n awk '\n $0 == \"# stll-cloud: early environment\" || $0 == \"# stll-cloud: session environment\" {\n if ((getline following) <= 0 || following != \"@SOURCE@\") exit 1\n next\n }\n { print }\n ' \"$file\" >> \"$temporary\" || { echo \"cloud-setup: managed shell startup block differs: $name\" >&2; exit 1; }\n fi\n printf '%s\\n' '# stll-cloud: session environment' '@SOURCE@' >> \"$temporary\"\n if [[ -f \"$file\" ]] && cmp -s \"$temporary\" \"$file\"; then rm -- \"$temporary\"; continue; fi\n if [[ -f \"$file\" ]]; then chmod --reference=\"$file\" \"$temporary\"; else chmod 644 \"$temporary\"; fi\n mv -f -- \"$temporary\" \"$file\"\ndone\n`;\n\nexport const renderCloudShellInstall = (options: CloudShellOptions) => {\n const profile = renderCloudShellProfile(options);\n return `install_shell_environment() (\n # Subshell scope retains temporary for EXIT cleanup after a failed command.\n [[ ! -L ${quote(cloudShellProfilePath)} ]] || fail 'Managed shell profile must not be a symlink'\n if [[ -e ${quote(cloudShellProfilePath)} ]]; then\n [[ -f ${quote(cloudShellProfilePath)} && \"$(stat -c '%h:%u' ${quote(cloudShellProfilePath)})\" == 1:0 ]] || fail 'Managed shell profile must be a root-owned single-link file'\n fi\n temporary=\"$(mktemp)\"\n trap 'rm -f -- \"$temporary\"' EXIT\n cat > \"$temporary\" <<'STLL_CLOUD_PROFILE'\n${profile}STLL_CLOUD_PROFILE\n if ! cmp -s \"$temporary\" ${quote(cloudShellProfilePath)}; then install -m 644 \"$temporary\" ${quote(cloudShellProfilePath)}; fi\n runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" bash -c ${quote(userStartup.replaceAll(\"@SOURCE@\", cloudShellProfileSource))}\n)\nverify_shell_environment() {\n [[ -f ${quote(cloudShellProfilePath)} && ! -L ${quote(cloudShellProfilePath)} && \"$(stat -c '%h:%u' ${quote(cloudShellProfilePath)})\" == 1:0 ]] || fail 'Managed shell environment is unavailable; run install'\n [[ \"$(sha256sum -- ${quote(cloudShellProfilePath)} | cut -d ' ' -f1)\" == ${quote(createHash(\"sha256\").update(profile).digest(\"hex\"))} ]] || fail 'Managed shell environment differs; run install'\n}\n`;\n};\n","import { parse as parseToml } from \"smol-toml\";\n\nimport {\n cloudSetupArtifacts,\n getCloudSetupArtifact,\n getCloudSetupPackage,\n} from \"./cloud-setup-artifacts\";\nimport {\n type CloudExtraTool,\n cloudExtraTools,\n isCloudPackageTool,\n parseCloudRustNames,\n} from \"./cloud-setup-schema\";\nimport type { parseCloudSetup } from \"./cloud-setup-schema\";\nimport type { RustException } from \"./toolchain-rust\";\n\ntype ResolveCloudToolchainsOptions = {\n cloud: NonNullable<ReturnType<typeof parseCloudSetup>>;\n files: Readonly<Record<string, string>>;\n rust: string;\n rustExceptions: readonly RustException[];\n};\nconst record = (input: unknown): input is Record<string, unknown> =>\n typeof input === \"object\" && input !== null && !Array.isArray(input);\n/** Resolve the same tracked snapshot for generation and the mandatory drift check. */\nexport const resolveCloudToolchains = ({\n cloud,\n files,\n rust,\n rustExceptions,\n}: ResolveCloudToolchainsOptions) => {\n const source = files[\"rust-toolchain.toml\"];\n const selector = files[\"rust-toolchain\"];\n if (source !== undefined && selector !== undefined)\n throw new Error(\n \"cloud Rust requires one root rust-toolchain.toml or rust-toolchain file\",\n );\n let declared: Record<string, unknown> | undefined;\n if (source !== undefined || selector?.trimStart().startsWith(\"[\")) {\n const parsed = parseToml(source ?? selector ?? \"\");\n if (!record(parsed[\"toolchain\"]))\n throw new Error(\"cloud Rust requires [toolchain]\");\n declared = parsed[\"toolchain\"];\n if (\n Object.keys(declared).some(\n (key) => ![\"channel\", \"components\", \"targets\", \"profile\"].includes(key),\n )\n )\n throw new Error(\n \"cloud Rust supports only channel, components, targets and profile\",\n );\n if (declared[\"profile\"] !== undefined && declared[\"profile\"] !== \"minimal\")\n throw new Error(\n \"cloud Rust requires profile = minimal; declare required components explicitly\",\n );\n } else if (selector !== undefined) declared = { channel: selector.trim() };\n const rustEnabled = declared !== undefined || cloud.rust !== undefined;\n const channel =\n declared === undefined\n ? (cloud.rust?.toolchain ?? rust)\n : declared[\"channel\"];\n if (rustEnabled) {\n if (typeof channel !== \"string\" || !/^\\d+\\.\\d+\\.\\d+$/.test(channel))\n throw new Error(\"cloud Rust requires an exact stable toolchain\");\n if (channel !== rust && !rustExceptions.some(({ pin }) => pin === channel))\n throw new Error(\n `cloud Rust must use shared Rust ${rust} or a recorded rustExceptions pin`,\n );\n if (cloud.rust?.toolchain !== undefined && cloud.rust.toolchain !== channel)\n throw new Error(\n \"cloud.rust.toolchain conflicts with root Rust toolchain\",\n );\n }\n // Authorization permits a version; cloud provisioning selects extras explicitly.\n const additionalToolchains = cloud.rust?.additionalToolchains ?? [];\n for (const pin of additionalToolchains) {\n if (pin === channel)\n throw new Error(\n \"cloud.rust.additionalToolchains must not repeat the primary toolchain\",\n );\n if (\n pin !== rust &&\n !rustExceptions.some(({ pin: authorized }) => authorized === pin)\n )\n throw new Error(\n `cloud.rust.additionalToolchains ${pin} requires an authorized rustExceptions pin`,\n );\n }\n const components = [\n ...new Set([\n ...parseCloudRustNames(declared?.[\"components\"], \"components\"),\n ...(cloud.rust?.components ?? []),\n ]),\n ].sort();\n const targets = [\n ...new Set([\n ...parseCloudRustNames(declared?.[\"targets\"], \"targets\"),\n ...(cloud.rust?.targets ?? []),\n ]),\n ].sort();\n const resolveTool = (tool: CloudExtraTool, version: string) => {\n if (isCloudPackageTool(tool))\n return {\n type: \"package\",\n tool,\n release: getCloudSetupPackage(tool, version),\n } as const;\n if (tool === \"cargo-nextest\" && !rustEnabled)\n throw new Error(\"cloud.tools.cargo-nextest requires a Rust toolchain\");\n if (tool === \"wasm-bindgen-cli\") {\n const lock = files[\"Cargo.lock\"];\n if (lock === undefined)\n throw new Error(\"wasm-bindgen-cli requires tracked root Cargo.lock\");\n const packages = parseToml(lock)[\"package\"];\n if (!Array.isArray(packages))\n throw new Error(\n \"Cargo.lock requires package entries for wasm-bindgen-cli\",\n );\n const versions = new Set(\n packages.flatMap((entry: unknown) =>\n record(entry) && entry[\"name\"] === \"wasm-bindgen\"\n ? [entry[\"version\"]]\n : [],\n ),\n );\n if (versions.size !== 1 || !versions.has(version))\n throw new Error(\n `cloud.tools.wasm-bindgen-cli ${version} must equal the unique wasm-bindgen crate version in Cargo.lock (found ${[...versions].join(\", \") || \"none\"})`,\n );\n }\n return {\n type: \"artifact\",\n tool,\n release: getCloudSetupArtifact(tool, version),\n } as const;\n };\n const tools = cloudExtraTools.flatMap((tool) => {\n const version = cloud.tools?.[tool];\n return version === undefined ? [] : [resolveTool(tool, version)];\n });\n return {\n rust:\n rustEnabled && typeof channel === \"string\"\n ? {\n channel,\n additionalToolchains: [...additionalToolchains].sort(),\n components,\n targets,\n installer: cloudSetupArtifacts[\"rustup-init\"],\n }\n : undefined,\n tools,\n };\n};\n","import type { getCloudSetupArtifact } from \"./cloud-setup-artifacts\";\nimport { cloudRustComponentBinaries } from \"./cloud-setup-schema\";\nimport type { resolveCloudToolchains } from \"./cloud-setup-toolchains\";\n\nconst quote = (value: string) => `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\ntype ArtifactRelease = ReturnType<typeof getCloudSetupArtifact>;\nconst artifactSelection = (release: ArtifactRelease) => `case \"$ARCH\" in\n${([\"amd64\", \"arm64\"] as const).map((arch) => ` ${arch}) artifact_url=${quote(release[arch].url)}; artifact_sha=${quote(release[arch].sha256)} ;;`).join(\"\\n\")}\nesac`;\n\nconst helpers = String.raw`\nfetch_verified() {\n download_file \"$1\" \"$3\" 120\n printf '%s %s\\n' \"$2\" \"$3\" | sha256sum --strict -c - >/dev/null\n}\n`;\n\nconst rustInstall = (\n rust: NonNullable<ReturnType<typeof resolveCloudToolchains>[\"rust\"]>,\n) => {\n const args = [\n ...rust.components.flatMap((name) => [\"--component\", name]),\n ...rust.targets.flatMap((name) => [\"--target\", name]),\n ]\n .map(quote)\n .join(\" \");\n return String.raw`\nexport RUSTUP_HOME=/opt/stll-cloud/rustup\nexport CARGO_HOME=/opt/stll-cloud/cargo\nexport RUSTUP_TOOLCHAIN='@RUST@'\nexport RUSTUP_AUTO_INSTALL=0\nrust_run() {\n local mode=\"$1\"\n shift\n set -- runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" RUSTUP_HOME=\"$RUSTUP_HOME\" CARGO_HOME=\"$CARGO_HOME\" RUSTUP_AUTO_INSTALL=0 RUSTUP_TOOLCHAIN=@RUST@ RUSTUP_DIST_SERVER=https://static.rust-lang.org RUSTUP_UPDATE_ROOT=https://static.rust-lang.org/rustup PATH=\"$PATH\" \"$@\"\n case \"$mode\" in\n local) \"$@\" ;;\n network) network_run static.rust-lang.org 180 \"$@\" ;;\n *) fail 'Invalid Rust execution mode' ;;\n esac\n}\nprimary_rust_ready() {\n local directory\n for directory in \"$RUSTUP_HOME\" \"$CARGO_HOME\"; do\n [[ -d \"$directory\" && ! -L \"$directory\" && \"$(stat -c '%u' \"$directory\")\" == \"$OUTPUT_UID\" ]] || return 1\n done\n [[ -x \"$CARGO_HOME/bin/rustup\" ]] || return 1\n [[ \"$(rust_run local \"$CARGO_HOME/bin/rustup\" --version 2>/dev/null)\" == 'rustup @RUSTUP@ '* ]] || return 1\n [[ \"$(rust_run local \"$CARGO_HOME/bin/rustc\" +@RUST@ --version)\" == 'rustc @RUST@ '* ]] || return 1\n local host\n host=\"$(rust_run local \"$CARGO_HOME/bin/rustc\" +@RUST@ -vV | awk '$1 == \"host:\" { print $2 }')\" || return 1\n @VERIFY_COMPONENTS@\n @VERIFY_TARGETS@\n return 0\n}\nrust_ready() {\n local additional_version\n primary_rust_ready || return 1\n @VERIFY_ADDITIONAL_TOOLCHAINS@\n return 0\n}\nverify_rust() { rust_ready || fail 'Pinned Rust, components or targets are unavailable; run install'; }\ninstall_rust() (\n if ! command -v cc >/dev/null || ! command -v ld >/dev/null || [[ ! -f /usr/include/stdlib.h ]]; then\n apt_refresh_for build-essential\n apt_install build-essential\n fi\n local artifact_url artifact_sha additional_version\n # Subshell scope retains scratch for EXIT cleanup after a failed command.\n scratch=\"$(mktemp -d)\"\n trap 'rm -rf -- \"$scratch\"' EXIT\n for directory in \"$RUSTUP_HOME\" \"$CARGO_HOME\"; do\n [[ ! -L \"$directory\" ]] || fail 'Rust home must not be a symlink'\n if [[ -e \"$directory\" ]]; then\n [[ -d \"$directory\" && \"$(stat -c '%u' \"$directory\")\" == \"$OUTPUT_UID\" ]] || fail 'Rust home ownership differs from the invoking user'\n else\n install -d -m 755 -o \"$OUTPUT_UID\" -g \"$OUTPUT_GID\" \"$directory\"\n fi\n done\n if [[ ! -x \"$CARGO_HOME/bin/rustup\" ]] || [[ \"$(rust_run local \"$CARGO_HOME/bin/rustup\" --version 2>/dev/null)\" != 'rustup @RUSTUP@ '* ]]; then\n @RUSTUP_ARTIFACT@\n fetch_verified \"$artifact_url\" \"$artifact_sha\" \"$scratch/rustup-init\"\n chmod 755 \"$scratch\" \"$scratch/rustup-init\"\n rust_run network \"$scratch/rustup-init\" -y --no-modify-path --default-toolchain none --profile minimal\n fi\n rust_run local \"$CARGO_HOME/bin/rustup\" set auto-self-update disable\n if ! primary_rust_ready; then\n rust_run network \"$CARGO_HOME/bin/rustup\" toolchain install @RUST@ --profile minimal --no-self-update @RUST_ARGS@\n fi\n @INSTALL_ADDITIONAL_TOOLCHAINS@\n rust_run local \"$CARGO_HOME/bin/rustup\" default @RUST@\n verify_rust\n for tool in rustup cargo rustc rustdoc @RUST_PROXIES@; do\n # Launchers persist the system homes in fresh shells without profile sourcing.\n printf '%s\\n' '#!/bin/sh' 'export RUSTUP_HOME=/opt/stll-cloud/rustup' 'export CARGO_HOME=/opt/stll-cloud/cargo' 'export RUSTUP_AUTO_INSTALL=0' 'export RUSTUP_TOOLCHAIN=@RUST@' \"exec /opt/stll-cloud/cargo/bin/$tool \\\"\\$@\\\"\" > \"$scratch/$tool\"\n if ! cmp -s \"$scratch/$tool\" \"/usr/local/bin/$tool\"; then\n install -m 755 \"$scratch/$tool\" \"/usr/local/bin/$tool\"\n fi\n done\n)\n`\n .replace(\n \"@VERIFY_ADDITIONAL_TOOLCHAINS@\",\n rust.additionalToolchains\n .map(\n (pin) =>\n `additional_version=\"$(rust_run local \"$CARGO_HOME/bin/rustc\" +${pin} --version)\" || return 1\\n [[ \"$additional_version\" == 'rustc ${pin} '* ]] || return 1`,\n )\n .join(\"\\n \"),\n )\n .replace(\n \"@INSTALL_ADDITIONAL_TOOLCHAINS@\",\n rust.additionalToolchains\n .map(\n (pin) =>\n `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`,\n )\n .join(\"\\n \"),\n )\n .replaceAll(\"@RUSTUP@\", rust.installer.version)\n .replaceAll(\"@RUST@\", rust.channel)\n .replace(\"@RUSTUP_ARTIFACT@\", artifactSelection(rust.installer))\n .replace(\"@RUST_ARGS@\", args)\n .replace(\n \"@RUST_PROXIES@\",\n Object.entries(cloudRustComponentBinaries)\n .flatMap(([component, binaries]) =>\n rust.components.includes(component) ? Array.from(binaries) : [],\n )\n .join(\" \"),\n )\n .replace(\n \"@VERIFY_COMPONENTS@\",\n rust.components\n .map(\n (name) =>\n `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`,\n )\n .join(\"\\n \"),\n )\n .replace(\n \"@VERIFY_TARGETS@\",\n rust.targets\n .map(\n (name) =>\n `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`,\n )\n .join(\"\\n \"),\n );\n};\n\ntype CloudToolEntry = ReturnType<\n typeof resolveCloudToolchains\n>[\"tools\"][number];\n\n// Present packages are reused; apt never downgrades or replaces them.\nconst packageToolInstall = ({\n tool,\n release,\n}: Extract<CloudToolEntry, { type: \"package\" }>) => {\n const name = tool.replaceAll(\"-\", \"_\");\n return {\n name,\n text: `verify_${name}() {\n [[ -x ${quote(release.binary)} && \"$(${quote(release.binary)} --version 2>/dev/null)\" == ${quote(release.identity)}* ]] || return 1\n [[ \"$(dpkg-query -W -f='\\${Version}' ${quote(release.package)} 2>/dev/null)\" == ${quote(`${release.version}-`)}* ]]\n}\ninstall_${name}() {\n if ! verify_${name}; then\n apt_network update\n apt_install ${quote(release.package)}\n verify_${name} || fail ${quote(`Installed ${tool} version differs from its pin`)}\n fi\n}\n`,\n };\n};\n\nconst artifactToolInstall = ({\n tool,\n release,\n}: Extract<CloudToolEntry, { type: \"artifact\" }>) => {\n const directory = `/opt/stll-cloud/tools/${tool}/${release.version}`;\n const command = tool === \"wasm-bindgen-cli\" ? \"wasm-bindgen\" : tool;\n const versionPrefix = tool === \"gitleaks\" ? \"gitleaks version\" : command;\n const marker = `${versionPrefix} ${release.version}`;\n return {\n name: tool.replaceAll(\"-\", \"_\"),\n text: `verify_${tool.replaceAll(\"-\", \"_\")}() {\n ${Object.keys(release.amd64.binaries)\n .map((binary) => `[[ -x ${quote(`${directory}/${binary}`)} ]] || return 1`)\n .join(\"\\n \")}\n [[ \"$( ${quote(`${directory}/${command}`)} --version)\" == ${quote(marker)} || \"$( ${quote(`${directory}/${command}`)} --version)\" == ${quote(`${marker} `)}* ]]\n}\ninstall_${tool.replaceAll(\"-\", \"_\")}() (\n local artifact_url artifact_sha\n # Subshell scope retains scratch for EXIT cleanup after a failed command.\n if ! verify_${tool.replaceAll(\"-\", \"_\")}; then\n scratch=\"$(mktemp -d)\"\n trap 'rm -rf -- \"$scratch\"' EXIT\n ${artifactSelection(release)}\n fetch_verified \"$artifact_url\" \"$artifact_sha\" \"$scratch/archive.tar.gz\"\n tar -xzf \"$scratch/archive.tar.gz\" -C \"$scratch\"\n install -d -m 755 ${quote(directory)}\n case \"$ARCH\" in\n${([\"amd64\", \"arm64\"] as const)\n .map(\n (arch) =>\n ` ${arch})\\n${Object.entries(release[arch].binaries)\n .map(\n ([binary, path]) =>\n ` install -m 755 \"$scratch/${path}\" ${quote(`${directory}/${binary}`)}`,\n )\n .join(\"\\n\")}\\n ;;`,\n )\n .join(\"\\n\")}\n esac\n verify_${tool.replaceAll(\"-\", \"_\")} || fail ${quote(`Installed ${tool} version differs from its pin`)}\n fi\n${Object.keys(release.amd64.binaries)\n .map(\n (binary) =>\n ` ln -sfnT -- ${quote(`${directory}/${binary}`)} ${quote(`/usr/local/bin/${binary}`)}`,\n )\n .join(\"\\n\")}\n)\n`,\n };\n};\n\nexport const renderCloudToolInstall = ({\n rust,\n tools,\n}: ReturnType<typeof resolveCloudToolchains>) => {\n const installs = tools.map((entry) => {\n switch (entry.type) {\n case \"package\":\n return packageToolInstall(entry);\n case \"artifact\":\n return artifactToolInstall(entry);\n default: {\n const exhaustive: never = entry;\n throw new Error(`Unsupported cloud tool: ${String(exhaustive)}`);\n }\n }\n });\n return `${helpers}${rust === undefined ? \"\" : rustInstall(rust)}\\n${installs.map(({ text }) => text).join(\"\\n\")}\ninstall_tools() {\n ${rust === undefined ? \":\" : \"install_rust\"}\n ${installs.map(({ name }) => `install_${name}`).join(\"\\n \")}\n}\nverify_tools() {\n ${rust === undefined ? \":\" : \"verify_rust\"}\n ${installs.map(({ name }) => `verify_${name} || fail 'Pinned ${name} is unavailable; run install'`).join(\"\\n \")}\n}\n`;\n};\n","import { subset, validRange } from \"semver\";\n\nconst numericComponent = \"(?:0|[1-9]\\\\d*)\";\nconst policyPattern = new RegExp(`^${numericComponent}\\\\.x$`);\nconst selectorPattern = new RegExp(\n `^(${numericComponent})(?:\\\\.(?:x|${numericComponent}(?:\\\\.${numericComponent})?))?$`,\n);\n\n/** A Node policy selects the complete stable release series of one major. */\nexport const nodePolicyValid = (value: string) =>\n policyPattern.test(value) && validRange(value) !== null;\n\n/** Static selectors may narrow that series, but cannot float across majors. */\nexport const nodeSelectorMatches = (value: unknown, policy: string) => {\n if (!nodePolicyValid(policy) || typeof value !== \"string\") return false;\n const major = selectorPattern.exec(value)?.[1];\n return (\n major !== undefined &&\n major === policy.slice(0, -2) &&\n validRange(value) !== null\n );\n};\n\n/** Engines must support every stable release in the approved major series. */\nexport const nodeSupportRangeMatches = (policy: string, range: string) => {\n if (!nodePolicyValid(policy)) return false;\n try {\n return subset(policy, range);\n } catch {\n return false;\n }\n};\n","import { createHash } from \"node:crypto\";\nimport { valid } from \"semver\";\n\nimport type { ArchivePins } from \"./archive-pins\";\nimport { renderCloudServiceInstall } from \"./cloud-setup-install\";\nimport { renderCloudNetwork } from \"./cloud-setup-network\";\nimport { cloudServices, parseCloudSetup } from \"./cloud-setup-schema\";\nimport { renderCloudServiceStart } from \"./cloud-setup-services\";\nimport { renderCloudShellInstall } from \"./cloud-setup-shell\";\nimport { resolveCloudToolchains } from \"./cloud-setup-toolchains\";\nimport { renderCloudToolInstall } from \"./cloud-setup-tools-install\";\nimport { nodeSelectorMatches } from \"./toolchain-node\";\nimport type { RustException } from \"./toolchain-rust\";\nimport type { parseToolchainPolicy } from \"./toolchain-schema\";\n\nexport const cloudSetupPath = \".agents/cloud-setup.sh\";\nexport const cloudEnvironmentMarker =\n \"# Generated by stll-cloud-setup; disposable local test services.\";\n\ntype GenerateCloudSetupOptions = {\n policy: ReturnType<typeof parseToolchainPolicy>;\n cloud: NonNullable<ReturnType<typeof parseCloudSetup>>;\n nodeVersion: string;\n files?: Readonly<Record<string, string>>;\n rustExceptions?: readonly RustException[];\n};\n\nconst script = String.raw`#!/usr/bin/env bash\n# Generated by stll-cloud-setup. Regenerate with stll-cloud-setup.\n# Networked installation and offline service startup are separate lifecycle steps.\n# Cached filesystems may not preserve processes; run start at every session start.\n# Supported platform: Ubuntu 24.04 (noble), amd64/arm64, root or passwordless sudo.\nset -euo pipefail\n\nusage() { echo 'Usage: cloud-setup.sh install|start|session' >&2; exit 2; }\n[[ \"$#\" == 1 ]] || usage\ncase \"$1\" in install|start|session) MODE=\"$1\" ;; *) usage ;; esac\nfail() { echo \"cloud-setup: $*\" >&2; exit 1; }\ntrap 'echo \"cloud-setup: command failed at line $LINENO\" >&2' ERR\n# Each phase logs its start and duration so a stalled phase is visible in the task log.\nstep() {\n local name=\"$1\" started=\"$SECONDS\"\n shift\n echo \"cloud-setup: $name started\" >&2\n \"$@\"\n echo \"cloud-setup: $name done in $((SECONDS - started))s\" >&2\n}\n[[ -f /etc/os-release ]] || fail 'Ubuntu 24.04 is required'\n. /etc/os-release\n[[ \"$ID\" == ubuntu && \"$VERSION_ID\" == 24.04 && \"$VERSION_CODENAME\" == noble ]] || fail 'Only Ubuntu 24.04 (noble) is supported'\nSCRIPT=\"$(realpath -- \"$0\")\"\nREPO_ROOT=\"$(cd -- \"$(dirname -- \"$SCRIPT\")/..\" && pwd -P)\"\n[[ \"$SCRIPT\" == \"$REPO_ROOT/.agents/cloud-setup.sh\" ]] || fail 'Run the generated repository script'\nif [[ \"$(id -u)\" != 0 ]]; then\n command -v sudo >/dev/null && sudo -n true || fail 'Root or passwordless sudo is required'\n exec sudo -n -- bash \"$SCRIPT\" \"$MODE\"\nfi\nOUTPUT_UID=\"$(printenv SUDO_UID || id -u)\"\n[[ \"$OUTPUT_UID\" =~ ^[0-9]+$ ]] || fail 'Invalid invoking user'\nOUTPUT_GID=\"$(getent passwd \"$OUTPUT_UID\" | cut -d: -f4)\"\n[[ \"$OUTPUT_GID\" =~ ^[0-9]+$ ]] || fail 'Invoking user is unavailable'\nOUTPUT_USER=\"$(getent passwd \"$OUTPUT_UID\" | cut -d: -f1)\"\nOUTPUT_HOME=\"$(getent passwd \"$OUTPUT_UID\" | cut -d: -f6)\"\n[[ -n \"$OUTPUT_USER\" && \"$OUTPUT_HOME\" == /* && -d \"$OUTPUT_HOME\" ]] || fail 'Invoking user requires an existing home directory'\nroot() { \"$@\"; }\n# Service daemons outlive setup, so they inherit no descriptor beyond stdio: a cloud\n# runner can pass its terminal as extra descriptors and wait until every copy closes.\nservice_run() (\n for descriptor in \"/proc/$BASHPID/fd/\"*; do\n descriptor=\"$(basename -- \"$descriptor\")\"\n if [[ \"$descriptor\" =~ ^[0-9]+$ ]] && (( descriptor > 2 )); then eval \"exec $descriptor>&-\"; fi\n done\n exec runuser -u stll-cloud -- \"$@\"\n)\nBUN_VERSION='@BUN@'\nNODE_VERSION='@NODE@'\nNODE_DIR=\"/opt/stll-cloud/node/$NODE_VERSION\"\nBUN_DIR=\"/opt/stll-cloud/bun/$BUN_VERSION\"\nexport PATH=\"$NODE_DIR/bin:$BUN_DIR:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"\nBUN_CACHE=\"/var/cache/stll-cloud/bun/$OUTPUT_UID\"\n@ENV_ASSIGNMENTS@\n[[ -f \"$REPO_ROOT/.node-version\" && ! -L \"$REPO_ROOT/.node-version\" ]] || fail 'A regular root .node-version is required'\n[[ \"$(awk 'NF { if (++count > 1 || NF != 1) exit 1; value=$1 } END { if (count != 1) exit 1; print value }' \"$REPO_ROOT/.node-version\")\" == \"$NODE_VERSION\" ]] || fail 'Node selector changed; regenerate cloud-setup.sh'\ncd -- \"$REPO_ROOT\"\ncase \"$(uname -m)\" in\n x86_64) ARCH=amd64; NODE_ARCH=x64; BUN_ARCH=x64; NODE_SHA256='@NODE_AMD64_SHA@'; BUN_SHA256='@BUN_AMD64_SHA@' ;;\n aarch64|arm64) ARCH=arm64; NODE_ARCH=arm64; BUN_ARCH=aarch64; NODE_SHA256='@NODE_ARM64_SHA@'; BUN_SHA256='@BUN_ARM64_SHA@' ;;\n *) fail 'Only amd64 and arm64 are supported' ;;\nesac\n\n@NETWORK@\n\nnode_ready() {\n local node_version npm_version npx_version\n [[ -x \"$NODE_DIR/bin/node\" && -x \"$NODE_DIR/bin/npm\" && -x \"$NODE_DIR/bin/npx\" ]] || return 1\n node_version=\"$(\"$NODE_DIR/bin/node\" --version)\" || return 1\n [[ \"$node_version\" == \"v$NODE_VERSION\" ]] || return 1\n npm_version=\"$(\"$NODE_DIR/bin/npm\" --version)\" || return 1\n [[ \"$npm_version\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]] || return 1\n npx_version=\"$(\"$NODE_DIR/bin/npx\" --version)\" || return 1\n [[ \"$npx_version\" == \"$npm_version\" ]] || return 1\n}\nruntime_ready() {\n node_ready || fail 'Pinned Node, npm or npx is unavailable; run install'\n [[ -x \"$BUN_DIR/bun\" && \"$($BUN_DIR/bun --version)\" == \"$BUN_VERSION\" ]] || fail 'Pinned Bun is unavailable; run install'\n}\nbun_route() {\n local label=\"$1\" resolved version\n shift\n resolved=\"$(\"$@\" -c 'command -v bun')\" || fail \"Bun is unavailable through $label\"\n version=\"$(\"$@\" -c 'bun --version')\" || fail \"Bun at $resolved failed through $label\"\n [[ \"$version\" == \"$BUN_VERSION\" ]] || fail \"Bun at $resolved resolves version $version through $label; expected $BUN_VERSION\"\n}\nverify_bun_routes() {\n local configured_mise login_shell minimal_path mise_root root_mise shims\n # Test-only overrides keep route executables and image locations inside fixtures.\n login_shell=\"$(printenv STLL_CLOUD_TEST_LOGIN_SHELL || true)\"\n [[ -n \"$login_shell\" ]] || login_shell=bash\n minimal_path=\"$(printenv STLL_CLOUD_TEST_MINIMAL_PATH || true)\"\n [[ -n \"$minimal_path\" ]] || minimal_path=/usr/local/bin:/usr/bin:/bin\n root_mise=\"$(printenv STLL_CLOUD_TEST_ROOT_MISE || true)\"\n [[ -n \"$root_mise\" ]] || root_mise=/root/.local/share/mise\n # An absolute shell: a PATH entry such as a user-writable mise shims\n # directory must never supply the program that root runs.\n bun_route 'the setup PATH' env PATH=\"$PATH\" /bin/sh\n bun_route 'sh -c' /bin/sh\n bun_route 'bash -lc' \"$login_shell\" -l\n bun_route 'the minimal system PATH' env -i PATH=\"$minimal_path\" /bin/sh\n configured_mise=\"$(printenv MISE_DATA_DIR || true)\"\n for mise_root in \"$configured_mise\" \"$OUTPUT_HOME/.local/share/mise\" \"$root_mise\"; do\n [[ -n \"$mise_root\" ]] || continue\n shims=\"$mise_root/shims\"\n [[ -d \"$shims\" ]] || continue\n bun_route \"mise shims PATH $shims\" env PATH=\"$shims:$PATH\" /bin/sh\n done\n}\nreplace_image_buns() {\n local candidate configured_mise directory mise_root root_mise\n configured_mise=\"$(printenv MISE_DATA_DIR || true)\"\n root_mise=\"$(printenv STLL_CLOUD_TEST_ROOT_MISE || true)\"\n [[ -n \"$root_mise\" ]] || root_mise=/root/.local/share/mise\n for mise_root in \"$configured_mise\" \"$OUTPUT_HOME/.local/share/mise\" \"$root_mise\"; do\n [[ -n \"$mise_root\" ]] || continue\n if [[ -d \"$mise_root/installs/bun\" ]]; then\n while IFS= read -r -d '' candidate; do\n [[ -d \"$candidate\" ]] || ln -sfnT -- \"$BUN_DIR/bun\" \"$candidate\"\n done < <(find \"$mise_root/installs/bun\" \\( -type f -o -type l \\) \\( -name bun -o -name bunx \\) -print0)\n fi\n for candidate in \"$mise_root/shims/bun\" \"$mise_root/shims/bunx\"; do\n [[ -e \"$candidate\" || -L \"$candidate\" ]] || continue\n [[ -d \"$candidate\" ]] || ln -sfnT -- \"$BUN_DIR/bun\" \"$candidate\"\n done\n done\n while IFS= read -r directory; do\n [[ -n \"$directory\" ]] || directory=.\n for candidate in \"$directory/bun\" \"$directory/bunx\"; do\n [[ -e \"$candidate\" || -L \"$candidate\" ]] || continue\n [[ -d \"$candidate\" ]] && continue\n [[ \"$(readlink -f -- \"$candidate\")\" == \"$(readlink -f -- \"$BUN_DIR/bun\")\" ]] || ln -sfnT -- \"$BUN_DIR/bun\" \"$candidate\"\n done\n # The trailing newline lets read return the last PATH entry too.\n done < <(printf '%s\\n' \"$PATH\" | tr : '\\n')\n}\ninstall_runtimes() (\n if [[ ! -s /etc/ssl/certs/ca-certificates.crt ]]; then\n command -v update-ca-certificates >/dev/null || fail 'System CA certificate bundle is missing; restore ca-certificates in the base image offline before install'\n update-ca-certificates || fail 'System CA certificate bundle could not be repaired offline; restore ca-certificates in the base image before install'\n fi\n [[ -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'\n 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\n apt_refresh_for ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1\n DEBIAN_FRONTEND=noninteractive apt_install ca-certificates curl unzip xz-utils openssl gnupg util-linux libatomic1\n fi\n local node_archive bun_archive bun_folder\n # Subshell scope retains scratch for EXIT cleanup after a failed command.\n scratch=\"$(mktemp -d)\"\n trap 'rm -rf -- \"$scratch\"' EXIT\n if ! node_ready; then\n node_archive=\"node-v$NODE_VERSION-linux-$NODE_ARCH.tar.xz\"\n download_file \"https://nodejs.org/dist/v$NODE_VERSION/$node_archive\" \"$scratch/$node_archive\" 120\n (cd \"$scratch\"; printf '%s %s\\n' \"$NODE_SHA256\" \"$node_archive\" | sha256sum --strict -c -)\n download_file \"https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt\" \"$scratch/node-sums\" 45\n (cd \"$scratch\"; awk -v name=\"$node_archive\" '$2 == name { print; count++ } END { if (count != 1) exit 1 }' node-sums | sha256sum --strict -c -)\n install -d -m 755 \"$NODE_DIR\"\n tar -xJf \"$scratch/$node_archive\" --strip-components=1 -C \"$NODE_DIR\"\n fi\n if [[ ! -x \"$BUN_DIR/bun\" ]] || [[ \"$($BUN_DIR/bun --version)\" != \"$BUN_VERSION\" ]]; then\n bun_folder=\"bun-linux-$BUN_ARCH\"\n bun_archive=\"$bun_folder.zip\"\n download_file \"https://github.com/oven-sh/bun/releases/download/bun-v$BUN_VERSION/$bun_archive\" \"$scratch/$bun_archive\" 120\n (cd \"$scratch\"; printf '%s %s\\n' \"$BUN_SHA256\" \"$bun_archive\" | sha256sum --strict -c -)\n download_file \"https://github.com/oven-sh/bun/releases/download/bun-v$BUN_VERSION/SHASUMS256.txt\" \"$scratch/bun-sums\" 45\n (cd \"$scratch\"; awk -v name=\"$bun_archive\" '$2 == name || $2 == \"*\" name { print $1 \" \" name; count++ } END { if (count != 1) exit 1 }' bun-sums | sha256sum --strict -c -)\n unzip -q \"$scratch/$bun_archive\" -d \"$scratch/bun\"\n install -d -m 755 \"$BUN_DIR\"\n install -m 755 \"$scratch/bun/$bun_folder/bun\" \"$BUN_DIR/bun\"\n fi\n runtime_ready\n ln -sfnT -- \"$NODE_DIR/bin/node\" /usr/local/bin/node\n ln -sfnT -- \"$NODE_DIR/bin/npm\" /usr/local/bin/npm\n ln -sfnT -- \"$NODE_DIR/bin/npx\" /usr/local/bin/npx\n ln -sfnT -- \"$BUN_DIR/bun\" /usr/local/bin/bun\n replace_image_buns\n)\n\ndependency_install() {\n local directory download_hosts\n for directory in /var/cache/stll-cloud /var/cache/stll-cloud/bun; do\n [[ ! -L \"$directory\" ]] || fail 'Dependency cache parent must not be a symlink'\n if [[ -e \"$directory\" ]]; then\n [[ -d \"$directory\" && \"$(stat -c '%u' \"$directory\")\" == 0 ]] || fail 'Dependency cache parent must be root-owned'\n fi\n install -d -m 755 -o root -g root \"$directory\"\n done\n [[ ! -L \"$BUN_CACHE\" ]] || fail 'Dependency cache must not be a symlink'\n if [[ -e \"$BUN_CACHE\" ]]; then\n [[ -d \"$BUN_CACHE\" && \"$(stat -c '%u' \"$BUN_CACHE\")\" == \"$OUTPUT_UID\" ]] || fail 'Dependency cache ownership differs from the invoking user'\n fi\n install -d -m 700 -o \"$OUTPUT_UID\" -g \"$OUTPUT_GID\" \"$BUN_CACHE\"\n # Report hostnames only: lockfile/config URLs may contain credentials.\n # These are known install hosts; lifecycle scripts can contact other hosts.\n download_hosts=\"$(HOME=\"$OUTPUT_HOME\" \"$NODE_DIR/bin/node\" -e '\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\nconst hosts = new Set([\"registry.npmjs.org\"]);\nconst inputs = [process.env.BUN_CONFIG_REGISTRY ?? \"\", process.env.NPM_CONFIG_REGISTRY ?? \"\", process.env.npm_config_registry ?? \"\"];\nfor (const file of [\"bun.lock\", \".npmrc\", \"bunfig.toml\", path.join(process.env.HOME, \".npmrc\"), path.join(process.env.HOME, \".bunfig.toml\"), path.join(process.env.XDG_CONFIG_HOME ?? process.env.HOME, \".bunfig.toml\")]) {\n if (fs.existsSync(file)) inputs.push(fs.readFileSync(file, \"utf8\"));\n}\nfor (const input of inputs) {\n for (const match of input.matchAll(/(?:git\\+)?https?:\\/\\/[^\\s\"\\x27<>\\\\]+/g)) {\n try { hosts.add(new URL(match[0].replace(/^git\\+/, \"\")).hostname); } catch {}\n }\n if (/github:/.test(input)) { hosts.add(\"github.com\"); hosts.add(\"codeload.github.com\"); }\n}\nprocess.stdout.write([...hosts].sort().join(\",\"));\n')\"\n # Bun 1.4.3 socket inactivity timeout, in seconds; the outer bound includes scripts.\n network_run \"$download_hosts\" 240 runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" BUN_INSTALL_CACHE_DIR=\"$BUN_CACHE\" PATH=\"$PATH\" BUN_CONFIG_HTTP_IDLE_TIMEOUT=20 \"$BUN_DIR/bun\" @INSTALL_ARGS@\n}\n\n# The frozen install is the check: it reads every input the package manager\n# uses and changes nothing on a current tree, so no stamp stands in for it.\ninstall_dependencies() {\n dependency_install\n}\nsync_dependencies() {\n dependency_install || fail 'bun.lock mismatch; dependency installation failed'\n}\n\n@SUBMODULE_FUNCTION@@SERVICE_INSTALL@\n@SERVICE_START@\n\n@TOOL_INSTALL@\n\n@INPUT_VALIDATION@\n\n@ENV_FUNCTIONS@\n@ENVIRONMENT_VALUES@\n@SESSION_ENVIRONMENT@\n\n@PREPARE_FUNCTION@\n\nif [[ \"$MODE\" == install ]]; then\n step runtimes install_runtimes\n step services install_services\n step tools install_tools\n step shell install_shell_environment\n # Login routes read the installed profile, so they are checked after it.\n step routes verify_bun_routes\n@SUBMODULE_STEP@ step dependencies install_dependencies\n@PREPARE_STEP@\n exit 0\nfi\n@ENV_INITIALIZE@\nstart_environment() {\n step runtime-check runtime_ready\n step dependencies sync_dependencies\n step tool-check verify_tools\n step shell install_shell_environment\n step shell-check verify_shell_environment\n @ENV_VALIDATE@\n step state prepare_state\n step service-start start_services\n @ENV_WRITE@\n}\nif [[ \"$MODE\" == session ]]; then\n start_environment >&2\nelse\n start_environment\nfi\n@SESSION_ENVIRONMENT_CALL@\n`;\n\nconst environmentValuesFunction = String.raw`\nenvironment_values() {\n local emit=\"$1\"\n \"$emit\" NODE_ENV test\n if [[ -n \"$DATABASE_URL\" ]]; then\n \"$emit\" DATABASE_URL \"$DATABASE_URL\"\n \"$emit\" POSTGRES_HOST \"$POSTGRES_HOST\"\n \"$emit\" POSTGRES_USER \"$POSTGRES_USER\"\n \"$emit\" POSTGRES_PASSWORD \"$POSTGRES_PASSWORD\"\n \"$emit\" POSTGRES_DB_NAME \"$POSTGRES_DB_NAME\"\n \"$emit\" POSTGRES_ADDITIONAL_CONNECTION_DATA \"$POSTGRES_ADDITIONAL_CONNECTION_DATA\"\n fi\n if [[ -n \"$REDIS_URL\" ]]; then \"$emit\" REDIS_URL \"$REDIS_URL\"; fi\n}\n`;\n\nconst environmentFunctions = String.raw`\nvalidate_environment() {\n local part target=\"$REPO_ROOT\" env_path=\"$REPO_ROOT/$ENV_FILE\" first_line temporary\n while IFS= read -r part; do\n target=\"$target/$part\"\n [[ ! -L \"$target\" ]] || fail 'Environment path must not contain symbolic links'\n done < <(printf '%s\\n' \"$ENV_FILE\" | tr '/' '\\n')\n [[ -d \"$(dirname -- \"$env_path\")\" ]] || fail 'Environment parent directory is missing'\n if [[ -e \"$env_path\" ]]; then\n [[ -f \"$env_path\" ]] || fail 'Environment target must be a regular file'\n IFS= read -r first_line < \"$env_path\" || fail 'Refusing to overwrite an unowned environment file'\n [[ \"$first_line\" == \"$ENV_MARKER\" ]] || fail 'Refusing to overwrite an unowned environment file'\n fi\n}\nenvironment_file_value() { printf '%s=%s\\n' \"$1\" \"$2\"; }\nwrite_environment() {\n validate_environment\n local env_path=\"$REPO_ROOT/$ENV_FILE\" temporary\n temporary=\"$(mktemp \"$(dirname -- \"$env_path\")/.stll-cloud-env.XXXXXX\")\"\n chmod 600 \"$temporary\"\n {\n printf '%s\\n' \"$ENV_MARKER\"\n environment_values environment_file_value\n } > \"$temporary\"\n chown \"$OUTPUT_UID:$OUTPUT_GID\" \"$temporary\"\n mv -f -- \"$temporary\" \"$env_path\"\n}\n`;\n\nconst sessionEnvironmentFunction = String.raw`\nenvironment_shell_value() { printf 'export %s=%q\\n' \"$1\" \"$2\"; }\nemit_session_environment() {\n environment_values environment_shell_value\n}\n`;\n\nconst shellQuote = (value: string) => `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n\nconst renderWasmBindgenLockValidation = (version: string) =>\n `[[ -f 'Cargo.lock' && ! -L 'Cargo.lock' ]] && awk -v expected=${shellQuote(version)} '${String.raw`\nfunction validate_package() {\n if (in_package && name == \"wasm-bindgen\") {\n count++\n if (version != expected) mismatch = 1\n }\n}\n/^\\[\\[package\\]\\][[:space:]]*$/ {\n validate_package()\n in_package = 1\n name = \"\"\n version = \"\"\n next\n}\n/^\\[/ {\n validate_package()\n in_package = 0\n next\n}\nin_package && /^[[:space:]]*name[[:space:]]*=/ {\n name = $0\n sub(/^[^=]*=[[:space:]]*\"/, \"\", name)\n sub(/\"[[:space:]]*$/, \"\", name)\n}\nin_package && /^[[:space:]]*version[[:space:]]*=/ {\n version = $0\n sub(/^[^=]*=[[:space:]]*\"/, \"\", version)\n sub(/\"[[:space:]]*$/, \"\", version)\n}\nEND {\n validate_package()\n exit !(count >= 1 && !mismatch)\n}`}' 'Cargo.lock' || fail 'Cargo.lock wasm-bindgen version changed; regenerate cloud-setup.sh'`;\n\n// Offline and time-bounded: stdin is closed so a prompt cannot hold the\n// snapshot. timeout leads its own process group (its pid), but it stops\n// escalating once its direct child exits, so whatever is left in that group\n// afterwards (a descendant that ignored TERM) is killed unconditionally.\nconst renderPrepare = (\n prepare: { script: string; seconds: number } | undefined,\n files: Readonly<Record<string, string>>,\n) => {\n if (prepare === undefined) return \"\";\n const manifest = files[\"package.json\"];\n if (manifest === undefined)\n throw new Error(\"cloud.prepare requires a tracked root package.json\");\n const parsed: unknown = JSON.parse(manifest);\n const scripts =\n typeof parsed === \"object\" && parsed !== null && \"scripts\" in parsed\n ? parsed.scripts\n : undefined;\n if (\n typeof scripts !== \"object\" ||\n scripts === null ||\n !Object.hasOwn(scripts, prepare.script) ||\n typeof Reflect.get(scripts, prepare.script) !== \"string\"\n )\n throw new Error(\n `cloud.prepare.script ${prepare.script} is not a root package script`,\n );\n return [\n \"prepare_sources() {\",\n \" local leader status=0\",\n ` timeout --kill-after=10 ${prepare.seconds} runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" PATH=\"$PATH\" \"$BUN_DIR/bun\" run ${shellQuote(prepare.script)} </dev/null &`,\n \" leader=$!\",\n ' wait \"$leader\" || status=$?',\n ' kill -KILL -- \"-$leader\" 2>/dev/null || true',\n ' return \"$status\"',\n \"}\",\n ].join(\"\\n\");\n};\n\nconst runtimeArchiveManifests = {\n node: (version: string) =>\n `https://nodejs.org/dist/v${version}/SHASUMS256.txt`,\n bun: (version: string) =>\n `https://github.com/oven-sh/bun/releases/download/bun-v${version}/SHASUMS256.txt`,\n} as const;\n\n// Shared pins cover the policy releases; a repository on another accepted\n// release declares that release's pins itself. One source per release.\nconst runtimeArchivePins = ({\n runtime,\n version,\n shared,\n declared,\n}: {\n runtime: keyof typeof runtimeArchiveManifests;\n version: string;\n shared: ArchivePins;\n declared: ArchivePins | undefined;\n}) => {\n const key = `cloud.runtimeArchiveSha256.${runtime}`;\n const sharedPins = shared[version];\n if (declared !== undefined) {\n if (sharedPins !== undefined)\n throw new Error(\n `the shared policy pins ${runtime} ${version} archives; remove ${key}`,\n );\n const pins = declared[version];\n if (pins === undefined)\n throw new Error(\n `${key} pins ${Object.keys(declared).join(\", \")}, but the repository selects ${runtime} ${version}; update it with the amd64 and arm64 values from ${runtimeArchiveManifests[runtime](version)}`,\n );\n return pins;\n }\n if (sharedPins === undefined)\n throw new Error(\n `the shared policy has no ${runtime} ${version} archive SHA256 pins; declare ${key} for ${version} with the amd64 and arm64 values from ${runtimeArchiveManifests[runtime](version)}`,\n );\n return sharedPins;\n};\n\nexport const generateCloudSetup = ({\n policy,\n cloud,\n nodeVersion,\n files = {},\n rustExceptions = [],\n}: GenerateCloudSetupOptions) => {\n const selected = parseCloudSetup(cloud);\n if (selected === undefined) throw new Error(\"cloud declaration is required\");\n const exactNode = nodeVersion.trim();\n if (\n valid(exactNode) !== exactNode ||\n !nodeSelectorMatches(exactNode, policy.node)\n )\n throw new Error(\n \"cloud requires a tracked exact .node-version within the shared Node series\",\n );\n // Callers resolve the repository's Bun (at or above the shared minimum)\n // into policy.bun before generation.\n const bunVersion = policy.bun;\n const nodeArchiveSha256 = runtimeArchivePins({\n runtime: \"node\",\n version: exactNode,\n shared: policy.nodeArchiveSha256,\n declared: selected.runtimeArchiveSha256?.node,\n });\n const bunArchiveSha256 = runtimeArchivePins({\n runtime: \"bun\",\n version: bunVersion,\n shared: policy.bunArchiveSha256,\n declared: selected.runtimeArchiveSha256?.bun,\n });\n const toolchains = resolveCloudToolchains({\n cloud: selected,\n files,\n rust: policy.rust,\n rustExceptions,\n });\n const services = cloudServices.filter((service) =>\n selected.services.includes(service),\n );\n const replacements = new Map([\n [\"@INSTALL_ARGS@\", selected.install.replace(/^bun /, \"\")],\n [\"@NETWORK@\", renderCloudNetwork()],\n [\n \"@TOOL_INSTALL@\",\n renderCloudToolInstall(toolchains) +\n renderCloudShellInstall({\n nodeVersion: exactNode,\n bunVersion,\n rust: toolchains.rust,\n }),\n ],\n [\n \"@INPUT_VALIDATION@\",\n [\"rust-toolchain.toml\", \"rust-toolchain\"]\n .flatMap((file) => {\n const content = files[file];\n if (content === undefined)\n return [\n `[[ ! -e ${shellQuote(file)} && ! -L ${shellQuote(file)} ]] || fail ${shellQuote(`${file} appeared; regenerate cloud-setup.sh`)}`,\n ];\n const hash = createHash(\"sha256\").update(content).digest(\"hex\");\n return [\n `[[ -f ${shellQuote(file)} && ! -L ${shellQuote(file)} ]] && [[ \"$(sha256sum -- ${shellQuote(file)} | cut -d ' ' -f1)\" == ${shellQuote(hash)} ]] || fail ${shellQuote(`${file} changed; regenerate cloud-setup.sh`)}`,\n ];\n })\n .concat(\n selected.tools?.[\"wasm-bindgen-cli\"] === undefined\n ? []\n : [\n renderWasmBindgenLockValidation(\n selected.tools[\"wasm-bindgen-cli\"],\n ),\n ],\n )\n .join(\"\\n\"),\n ],\n [\"@BUN@\", bunVersion],\n [\"@NODE@\", exactNode],\n [\"@NODE_AMD64_SHA@\", nodeArchiveSha256.amd64],\n [\"@NODE_ARM64_SHA@\", nodeArchiveSha256.arm64],\n [\"@BUN_AMD64_SHA@\", bunArchiveSha256.amd64],\n [\"@BUN_ARM64_SHA@\", bunArchiveSha256.arm64],\n [\n \"@ENV_ASSIGNMENTS@\",\n selected.envFile === undefined\n ? \"\"\n : `ENV_FILE=${shellQuote(selected.envFile)}\\nENV_MARKER=${shellQuote(cloudEnvironmentMarker)}`,\n ],\n [\n \"@ENV_FUNCTIONS@\",\n selected.envFile === undefined ? \"\" : environmentFunctions,\n ],\n [\n \"@ENVIRONMENT_VALUES@\",\n selected.services.length === 0 ? \"\" : environmentValuesFunction,\n ],\n [\n \"@ENV_INITIALIZE@\",\n selected.services.length === 0\n ? \"\"\n : \"DATABASE_URL=''\\nPOSTGRES_HOST=''\\nPOSTGRES_USER=''\\nPOSTGRES_PASSWORD=''\\nPOSTGRES_DB_NAME=''\\nPOSTGRES_ADDITIONAL_CONNECTION_DATA=''\\nREDIS_URL=''\",\n ],\n [\n \"@ENV_VALIDATE@\",\n selected.envFile === undefined ? \"\" : \"validate_environment\",\n ],\n [\n \"@SESSION_ENVIRONMENT@\",\n selected.services.length === 0 ? \"\" : sessionEnvironmentFunction,\n ],\n [\n \"@SESSION_ENVIRONMENT_CALL@\",\n selected.services.length === 0\n ? \"\"\n : 'if [[ \"$MODE\" == session ]]; then emit_session_environment; fi',\n ],\n [\"@ENV_WRITE@\", selected.envFile === undefined ? \"\" : \"write_environment\"],\n [\"@PREPARE_FUNCTION@\", renderPrepare(selected.prepare, files)],\n [\n \"@SUBMODULE_FUNCTION@\",\n selected.submodules\n ? String.raw`install_submodules() {\n network_run github.com 240 runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" git submodule sync --recursive\n network_run github.com 240 runuser -u \"$OUTPUT_USER\" -- env HOME=\"$OUTPUT_HOME\" git submodule update --init --recursive --depth 1\n}`.concat(\"\\n\\n\")\n : \"\",\n ],\n [\n \"@SUBMODULE_STEP@\",\n selected.submodules ? \" step submodules install_submodules\\n\" : \"\",\n ],\n [\n \"@PREPARE_STEP@\",\n selected.prepare === undefined ? \"\" : \" step prepare prepare_sources\",\n ],\n [\n \"@SERVICE_INSTALL@\",\n renderCloudServiceInstall({\n services,\n postgres: policy.postgres,\n valkey: policy.valkey,\n valkeyArtifacts: policy.valkeyArtifacts,\n }),\n ],\n [\n \"@SERVICE_START@\",\n renderCloudServiceStart({\n services,\n postgres: policy.postgres,\n valkey: policy.valkey,\n }),\n ],\n ]);\n const rendered = script.replace(/@[A-Z0-9_]+@/g, (token) => {\n const value = replacements.get(token);\n if (value === undefined)\n throw new Error(`Missing cloud setup field: ${token}`);\n return value;\n });\n return `${rendered.replace(/[ \\t]+$/gm, \"\").trimEnd()}\\n`;\n};\n","import { isDeepStrictEqual } from \"node:util\";\nimport { parseDocument } from \"yaml\";\n\nimport { cloudSetupPath } from \"./cloud-setup\";\nimport { cloudShellProfilePath } from \"./cloud-setup-shell\";\n\nexport const cloudClaudeSettingsPath = \".claude/settings.json\";\nconst releasedSessionStartHook = (script: string) =>\n ({\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: `if [ \"\\${CLAUDE_CODE_REMOTE:-}\" = \"true\" ]; then\n ${script} start || exit \"$?\"\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n if [ ! -f ${cloudShellProfilePath} ]; then\n printf '%s\\\\n' 'cloud-setup: cloud shell profile is unavailable; run install' >&2\n exit 1\n fi\n printf '\\\\n' >> \"$CLAUDE_ENV_FILE\" || exit \"$?\"\n cat ${cloudShellProfilePath} >> \"$CLAUDE_ENV_FILE\"\n fi\nfi`,\n },\n ],\n }) as const;\n// Release 1.7.0 persisted this form; it rewrote the shared env file.\nconst releasedTemporaryFileHook = (script: string) =>\n ({\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: `if [ \"\\${CLAUDE_CODE_REMOTE:-}\" = \"true\" ]; then\n cloud_setup_incomplete() {\n 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.'\n printf '%s\\\\n' \"cloud-setup: $1\" >&2\n exit 0\n }\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n cloud_session_exports=\"$(${script} session)\" || cloud_setup_incomplete 'startup failed; run install'\n else\n ${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'\n exit 0\n fi\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n if [ ! -s ${cloudShellProfilePath} ]; then\n cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n fi\n cloud_shell_exports=\"$(cat ${cloudShellProfilePath})\" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'\n [ -n \"$cloud_shell_exports\" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n if [ -e \"$CLAUDE_ENV_FILE\" ] || [ -L \"$CLAUDE_ENV_FILE\" ]; then\n [ -f \"$CLAUDE_ENV_FILE\" ] && [ ! -L \"$CLAUDE_ENV_FILE\" ] || cloud_setup_incomplete 'session environment must be a regular file; check its path and rerun start'\n fi\n 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'\n if [ -e \"$CLAUDE_ENV_FILE\" ] || [ -L \"$CLAUDE_ENV_FILE\" ]; then\n 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'; }\n fi\n if [ -n \"$cloud_session_exports\" ]; then\n cloud_session_exports=\"$cloud_session_exports\n$cloud_shell_exports\"\n else\n cloud_session_exports=\"$cloud_shell_exports\"\n fi\n 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'; }\n 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'; }\n fi\nfi`,\n },\n ],\n }) as const;\n// SessionStart cannot block a session; successful stdout supplies model\n// context, so failures exit 0 with guidance. Hooks share CLAUDE_ENV_FILE and\n// may run concurrently, so this hook replaces only its own snapshot and\n// appends one stable source line to the shared file once.\nconst sessionStartHook = (script: string) =>\n ({\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: `if [ \"\\${CLAUDE_CODE_REMOTE:-}\" = \"true\" ]; then\n cloud_setup_incomplete() {\n 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.'\n printf '%s\\\\n' \"cloud-setup: $1\" >&2\n exit 0\n }\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n cloud_session_exports=\"$(${script} session)\" || cloud_setup_incomplete 'startup failed; run install'\n else\n ${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'\n exit 0\n fi\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n if [ ! -s ${cloudShellProfilePath} ]; then\n cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n fi\n cloud_shell_exports=\"$(cat ${cloudShellProfilePath})\" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'\n [ -n \"$cloud_shell_exports\" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n if [ -e \"$CLAUDE_ENV_FILE\" ] || [ -L \"$CLAUDE_ENV_FILE\" ]; then\n [ -f \"$CLAUDE_ENV_FILE\" ] && [ ! -L \"$CLAUDE_ENV_FILE\" ] || cloud_setup_incomplete 'session environment must be a regular file; check its path and rerun start'\n fi\n cloud_env_snapshot=\"\\${CLAUDE_ENV_FILE}.stll-cloud\"\n case \"$cloud_env_snapshot\" in\n *\"'\"*) cloud_setup_incomplete 'session environment path must not contain a single quote; check its path and rerun start' ;;\n esac\n if [ -n \"$cloud_session_exports\" ]; then\n cloud_session_exports=\"$cloud_session_exports\n$cloud_shell_exports\"\n else\n cloud_session_exports=\"$cloud_shell_exports\"\n fi\n cloud_env_temporary=\"$(umask 077; mktemp \"\\${cloud_env_snapshot}.XXXXXX\")\" || cloud_setup_incomplete 'session environment could not be prepared; check its write access and rerun start'\n printf '%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'; }\n mv -f -- \"$cloud_env_temporary\" \"$cloud_env_snapshot\" || { rm -f -- \"$cloud_env_temporary\"; cloud_setup_incomplete 'session environment could not be persisted; check its write access and rerun start'; }\n cloud_env_source=\". '$cloud_env_snapshot'\"\n if [ ! -f \"$CLAUDE_ENV_FILE\" ] || ! grep -Fqx -- \"$cloud_env_source\" \"$CLAUDE_ENV_FILE\"; then\n printf '\\\\n%s\\\\n' \"$cloud_env_source\" >> \"$CLAUDE_ENV_FILE\" || cloud_setup_incomplete 'session environment could not be persisted; check its write access and rerun start'\n fi\n fi\nfi`,\n },\n ],\n }) as const;\n// This exact form was persisted by the previous main-branch generator at 783bc97.\n// Keep it only so consumers of that release can regenerate to the current hook.\nconst currentMainSessionStartHook = (script: string) =>\n ({\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: `if [ \"\\${CLAUDE_CODE_REMOTE:-}\" = \"true\" ]; then\n cloud_setup_incomplete() {\n 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.'\n printf '%s\\\\n' \"cloud-setup: $1\" >&2\n exit 0\n }\n ${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'\n if [ -n \"\\${CLAUDE_ENV_FILE:-}\" ]; then\n if [ ! -s ${cloudShellProfilePath} ]; then\n cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n fi\n cloud_shell_exports=\"$(cat ${cloudShellProfilePath})\" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'\n [ -n \"$cloud_shell_exports\" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'\n 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'\n fi\nfi`,\n },\n ],\n }) as const;\n// Hooks run in the session's working directory; resolve the script from the project root.\nexport const cloudSessionStartHook = sessionStartHook(\n `bash \"$CLAUDE_PROJECT_DIR/${cloudSetupPath}\"`,\n);\n// Releases 1.1.0, 1.3.1 and 1.7.0 persisted these exact forms in consumer\n// settings.\n// Remove after supported consumers regenerate with a release containing this hook.\nconst previousCloudSessionStartHooks = [\n releasedSessionStartHook(`bash ${cloudSetupPath}`),\n releasedSessionStartHook(`bash \"$CLAUDE_PROJECT_DIR/${cloudSetupPath}\"`),\n currentMainSessionStartHook(`bash \"$CLAUDE_PROJECT_DIR/${cloudSetupPath}\"`),\n releasedTemporaryFileHook(`bash \"$CLAUDE_PROJECT_DIR/${cloudSetupPath}\"`),\n];\nexport const cloudAttribution = { commit: \"\", pr: \"\" } as const;\n\nconst record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst array = (value: unknown): value is readonly unknown[] =>\n Array.isArray(value);\n\nconst parseSettings = (text: string) => {\n try {\n const settings: unknown = JSON.parse(text, (_key, value: unknown) => {\n if (\n typeof value === \"number\" &&\n (!Number.isFinite(value) ||\n (Number.isInteger(value) && !Number.isSafeInteger(value)))\n )\n throw new Error(\n \"settings contains a number that cannot be safely preserved\",\n );\n return value;\n });\n return settings;\n } catch (error) {\n if (error instanceof SyntaxError)\n throw new Error(\"settings must contain valid JSON\");\n throw error;\n }\n};\n\nconst readSettings = (text: string | undefined) => {\n const settings = text === undefined ? {} : parseSettings(text);\n if (\n text !== undefined &&\n parseDocument(text, { uniqueKeys: true }).errors.length > 0\n )\n throw new Error(\"settings contains duplicate or ambiguous JSON keys\");\n if (!record(settings)) throw new Error(\"settings must be a JSON object\");\n if (settings[\"disableAllHooks\"] === true)\n throw new Error(\"disableAllHooks prevents SessionStart from running\");\n const hooks = settings[\"hooks\"] === undefined ? {} : settings[\"hooks\"];\n if (!record(hooks)) throw new Error(\"hooks must be a JSON object\");\n const sessionStart =\n hooks[\"SessionStart\"] === undefined ? [] : hooks[\"SessionStart\"];\n if (\n !array(sessionStart) ||\n sessionStart.some((entry) => !record(entry) || !array(entry[\"hooks\"]))\n )\n throw new Error(\"hooks.SessionStart must be an array of hook groups\");\n return { settings, hooks, sessionStart };\n};\n\nconst cloudHookGroups = (sessionStart: readonly unknown[]) =>\n sessionStart.filter(\n (entry) =>\n record(entry) &&\n array(entry[\"hooks\"]) &&\n entry[\"hooks\"].some(\n (hook) =>\n record(hook) &&\n typeof hook[\"command\"] === \"string\" &&\n hook[\"command\"].includes(cloudSetupPath),\n ),\n );\n\nexport const cloudSessionStartFix =\n `preserve unrelated settings in ${cloudClaudeSettingsPath}, repair its JSON/hooks structure and set disableAllHooks to false if needed, and ensure hooks.SessionStart contains exactly this cloud setup entry (replace conflicting cloud setup entries):\\n` +\n JSON.stringify(cloudSessionStartHook, null, 2);\nexport const cloudAttributionFix =\n `preserve unrelated settings in ${cloudClaudeSettingsPath} and set its top-level attribution to exactly:\\n` +\n JSON.stringify({ attribution: cloudAttribution }, null, 2);\n\nconst sessionStartState = (sessionStart: readonly unknown[]) => {\n const groups = cloudHookGroups(sessionStart);\n const group = groups.at(0);\n if (group === undefined) return { type: \"missing\" } as const;\n if (groups.length === 1 && isDeepStrictEqual(group, cloudSessionStartHook))\n return { type: \"current\" } as const;\n if (\n groups.length === 1 &&\n previousCloudSessionStartHooks.some((hook) =>\n isDeepStrictEqual(group, hook),\n )\n )\n return { type: \"previous\", group } as const;\n return { type: \"conflict\" } as const;\n};\n\nconst attributionState = (settings: Record<string, unknown>) => {\n const attribution = settings[\"attribution\"];\n if (attribution === undefined) return \"missing\";\n return isDeepStrictEqual(attribution, cloudAttribution)\n ? \"current\"\n : \"conflict\";\n};\n\nconst mergeError = (reason: string, fix: string) =>\n new Error(\n `cannot safely merge ${cloudClaudeSettingsPath}: ${reason}; ${fix}`,\n );\n\nconst readMergeableSettings = (text: string | undefined) => {\n try {\n return readSettings(text);\n } catch (error) {\n throw mergeError(\n error instanceof Error ? error.message : String(error),\n cloudSessionStartFix,\n );\n }\n};\n\n/** Add the cloud hook and attribution; never overwrite conflicting values. */\nexport const mergeCloudClaudeSettings = (text: string | undefined) => {\n const { settings, hooks, sessionStart } = readMergeableSettings(text);\n const hook = sessionStartState(sessionStart);\n if (hook.type === \"conflict\")\n throw mergeError(\n \"existing cloud setup SessionStart hook differs\",\n cloudSessionStartFix,\n );\n const attribution = attributionState(settings);\n if (attribution === \"conflict\")\n throw mergeError(\"existing attribution differs\", cloudAttributionFix);\n if (\n hook.type === \"current\" &&\n attribution === \"current\" &&\n text !== undefined\n )\n return text;\n const mergedSessionStart = (() => {\n switch (hook.type) {\n case \"current\":\n return sessionStart;\n case \"missing\":\n return [...sessionStart, cloudSessionStartHook];\n case \"previous\":\n return sessionStart.map((entry) =>\n entry === hook.group ? cloudSessionStartHook : entry,\n );\n default: {\n const exhaustive: never = hook;\n throw new Error(`Unsupported hook state: ${String(exhaustive)}`);\n }\n }\n })();\n return `${JSON.stringify(\n {\n ...settings,\n attribution: cloudAttribution,\n hooks: { ...hooks, SessionStart: mergedSessionStart },\n },\n null,\n 2,\n )}\\n`;\n};\n\n/** Settings formatting and unrelated hooks do not affect the generated contract. */\nexport const hasCloudSessionStartHook = (text: string | undefined) => {\n if (text === undefined) return false;\n try {\n return (\n sessionStartState(readSettings(text).sessionStart).type === \"current\"\n );\n } catch {\n return false;\n }\n};\n\nexport const hasCloudAttribution = (text: string | undefined) => {\n if (text === undefined) return false;\n try {\n return attributionState(readSettings(text).settings) === \"current\";\n } catch {\n return false;\n }\n};\n","import path from \"node:path\";\nimport picomatch from \"picomatch\";\n\ntype WorkspaceContainsOptions = {\n directory: string;\n file: string;\n patterns: unknown;\n rootMembership: \"implicit\" | \"patterns\";\n};\n\n/** Match manifest directories with the same positive and negative workspace patterns. */\nexport const workspaceContains = ({\n directory,\n file,\n patterns,\n rootMembership,\n}: WorkspaceContainsOptions) => {\n const relative = path.posix.relative(directory, path.posix.dirname(file));\n if (relative === \"\" && rootMembership === \"implicit\") return true;\n if (relative === \"..\" || relative.startsWith(\"../\")) return false;\n if (!Array.isArray(patterns)) return false;\n const normalize = (pattern: string) => path.posix.normalize(pattern);\n const selected = patterns.filter(\n (value: unknown): value is string => typeof value === \"string\",\n );\n return (\n picomatch(\n selected.filter((pattern) => !pattern.startsWith(\"!\")).map(normalize),\n )(relative) &&\n !picomatch(\n selected\n .filter((pattern) => pattern.startsWith(\"!\"))\n .map((pattern) => normalize(pattern.slice(1))),\n )(relative)\n );\n};\n","const record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** Filename class recognized by Dependabot's Docker Compose fetcher. */\nexport const isComposeDefinitionPath = (file: string) =>\n /^\\.?(?:docker-)?compose(?:-[\\w]+)?(?:\\.[\\w-]+)?\\.ya?ml$/i.test(\n file.split(\"/\").at(-1) ?? \"\",\n );\n\n/** Candidate YAML files are classified by their document shape after reading. */\nexport const isKubernetesDefinitionPath = (file: string) =>\n /^[^.].*\\.ya?ml$/i.test(file.split(\"/\").at(-1) ?? \"\");\n\ntype ContainerImage = { image: unknown; path: (string | number)[] };\ntype ContainerDocument = {\n ecosystem: \"docker-compose\" | \"docker\";\n images: ContainerImage[];\n};\n\nexport const kubernetesPodSpecPaths = {\n Pod: [\"spec\"],\n Deployment: [\"spec\", \"template\", \"spec\"],\n DaemonSet: [\"spec\", \"template\", \"spec\"],\n StatefulSet: [\"spec\", \"template\", \"spec\"],\n ReplicaSet: [\"spec\", \"template\", \"spec\"],\n ReplicationController: [\"spec\", \"template\", \"spec\"],\n Job: [\"spec\", \"template\", \"spec\"],\n CronJob: [\"spec\", \"jobTemplate\", \"spec\", \"template\", \"spec\"],\n} as const;\n\n/** Shared semantic image enumeration for runtime checks and update-root generation. */\nexport const containerDocumentImages = (\n document: unknown,\n file: string,\n): ContainerDocument | undefined => {\n if (!record(document)) return undefined;\n const services = document[\"services\"];\n if (isComposeDefinitionPath(file) && record(services)) {\n const images: ContainerImage[] = [];\n for (const [name, service] of Object.entries(services)) {\n if (record(service) && service[\"image\"] !== undefined)\n images.push({\n image: service[\"image\"],\n path: [\"services\", name, \"image\"],\n });\n }\n return { ecosystem: \"docker-compose\", images };\n }\n if (\n typeof document[\"apiVersion\"] !== \"string\" ||\n typeof document[\"kind\"] !== \"string\"\n )\n return undefined;\n const images: ContainerImage[] = [];\n const visited = new Set<Record<string, unknown>>();\n const walkResource = (\n resource: Record<string, unknown>,\n prefix: (string | number)[],\n ) => {\n if (visited.has(resource)) return;\n visited.add(resource);\n if (\n typeof resource[\"apiVersion\"] !== \"string\" ||\n typeof resource[\"kind\"] !== \"string\"\n )\n return;\n if (resource[\"kind\"] === \"List\" && Array.isArray(resource[\"items\"])) {\n for (const [index, item] of resource[\"items\"].entries())\n if (record(item)) walkResource(item, [...prefix, \"items\", index]);\n return;\n }\n const specPath = Object.entries(kubernetesPodSpecPaths).find(\n ([kind]) => kind === resource[\"kind\"],\n )?.[1];\n if (specPath === undefined) return;\n let spec: unknown = resource;\n for (const key of specPath) spec = record(spec) ? spec[key] : undefined;\n if (!record(spec)) return;\n for (const key of [\"containers\", \"initContainers\", \"ephemeralContainers\"]) {\n const containers = spec[key];\n if (!Array.isArray(containers)) continue;\n for (const [index, container] of containers.entries()) {\n if (record(container) && container[\"image\"] !== undefined)\n images.push({\n image: container[\"image\"],\n path: [...prefix, ...specPath, key, index, \"image\"],\n });\n }\n }\n };\n walkResource(document, []);\n return images.length === 0 ? undefined : { ecosystem: \"docker\", images };\n};\n","import { cloudSetupPath } from \"./cloud-setup\";\nimport { cloudClaudeSettingsPath } from \"./cloud-setup-claude\";\nimport {\n isComposeDefinitionPath,\n isKubernetesDefinitionPath,\n} from \"./toolchain-container-inputs\";\n\nconst excludedInputPath = (file: string) =>\n file === \"\" ||\n file.split(\"/\").some((part) => part === \"node_modules\" || part === \"vendor\");\n\nexport const javascriptDependencyLockfiles = [\n \"bun.lock\",\n \"package-lock.json\",\n \"yarn.lock\",\n \"pnpm-lock.yaml\",\n] as const;\n\nexport const dependabotManifestEcosystems = {\n Gemfile: \"bundler\",\n \"Gemfile.lock\": \"bundler\",\n \"composer.json\": \"composer\",\n \"composer.lock\": \"composer\",\n} as const;\n\n/** Share ecosystem inventory with snapshot selection; no dependency graph reads are needed. */\nexport const dependabotManifestEcosystem = (file: string) => {\n if (excludedInputPath(file)) return undefined;\n const basename = file.split(\"/\").at(-1);\n for (const [name, ecosystem] of Object.entries(dependabotManifestEcosystems))\n if (basename === name) return ecosystem;\n return undefined;\n};\n\n/** Match project, environment, local, and fragment filenames recognized by mise. */\nexport const isMiseConfigPath = (file: string) =>\n !excludedInputPath(file) &&\n (/(?:^|\\/)\\.?mise(?:\\.[^./][^/]*)?\\.toml$/.test(file) ||\n /(?:^|\\/)(?:\\.?mise|\\.config\\/mise)\\/config(?:\\.[^./][^/]*)?\\.toml$/.test(\n file,\n ) ||\n /(?:^|\\/)(?:\\.?mise|\\.config\\/mise)\\/conf\\.d\\/[^./][^/]*\\.toml$/.test(\n file,\n ));\n\n/** GitHub action metadata may live at the repository root or in any directory. */\nexport const githubAutomationFileKind = (file: string) => {\n if (file === \"\") return undefined;\n if (/^\\.github\\/workflows\\/[^/]+\\.ya?ml$/.test(file)) return \"workflow\";\n if (/(?:^|\\/)action\\.ya?ml$/.test(file)) return \"action\";\n return undefined;\n};\n\n/** Dependabot updates workflows and repository-root action metadata. */\nexport const isDependabotGithubActionsPath = (file: string) => {\n const kind = githubAutomationFileKind(file);\n return kind === \"workflow\" || (kind === \"action\" && !file.includes(\"/\"));\n};\n\n/** Use one filename discriminator for reader selection and Python ecosystem decisions. */\nexport const pythonDependencyManifestKind = (file: string) => {\n if (excludedInputPath(file)) return undefined;\n const name = file.split(\"/\").at(-1);\n if (name === \"pyproject.toml\") return \"project\";\n if (name === \"Pipfile\") return \"pipfile\";\n if (name === \"Pipfile.lock\") return \"pipfile-lock\";\n if (name === \"setup.py\" || name === \"setup.cfg\") return \"setup\";\n if (name !== undefined && /^requirements[^/]*\\.(?:txt|in)$/.test(name))\n return \"requirements\";\n return undefined;\n};\n\nexport const isPythonDependencyManifest = (file: string) =>\n pythonDependencyManifestKind(file) !== undefined;\n\n/** Docker definition names use dot-delimited variants, excluding source and documentation. */\nexport const isDockerDefinitionPath = (file: string) => {\n if (excludedInputPath(file)) return false;\n const name = file.split(\"/\").at(-1) ?? \"\";\n if (\n /\\.(?:[cm]?[jt]sx?|mdx?|rst|txt|html?|py|rs|go|java|sh|c|cc|cpp|cxx|h|hpp|cs|rb|php|swift|kt|css|scss)$/i.test(\n name,\n )\n )\n return false;\n return /^(?:[^./]+\\.)*(?:dockerfile|containerfile)(?:\\.[^./]+)*$/i.test(name);\n};\n\nexport const isFormatterConfigPath = (file: string) => {\n const name = file.split(\"/\").at(-1) ?? \"\";\n return (\n /^\\.oxfmtrc(?:\\.jsonc?)?$/.test(name) ||\n /^oxfmt\\.config\\.[cm]?[jt]s$/.test(name) ||\n /^\\.prettierrc(?:\\.[^/]+)?$/.test(name) ||\n /^prettier\\.config\\.[cm]?[jt]s$/.test(name) ||\n name === \".prettierignore\" ||\n /^biome\\.jsonc?$/.test(name) ||\n /^\\.?dprint\\.jsonc?$/.test(name)\n );\n};\n\nexport const isLefthookConfigPath = (file: string) =>\n /^\\.?lefthook(?:-local)?\\.ya?ml$/.test(file);\n\n/** Executable shell files may have no suffix; the interpreter is then their discriminator. */\nexport const isShellScript = (file: string, text = \"\") =>\n !excludedInputPath(file) &&\n (/\\.(?:sh|bash|zsh)$/.test(file) ||\n /^#![ \\t]*(?:\\/(?:[^ \\t\\r\\n]+\\/)*(?:bash|dash|ksh|zsh|sh)|\\/usr\\/bin\\/env[ \\t]+(?:-S[ \\t]+)?(?:bash|dash|ksh|zsh|sh))(?=[ \\t\\r\\n]|$)/.test(\n text,\n ));\n\n/** Lockfiles establish ecosystem presence without reading their dependency graphs. */\nexport const toolchainInputKind = (file: string, text = \"\") => {\n if (\n file === \"bunfig.toml\" ||\n file === cloudSetupPath ||\n file === cloudClaudeSettingsPath ||\n file === \"Cargo.lock\" ||\n file === \".changeset/config.json\" ||\n isLefthookConfigPath(file)\n )\n return \"config\";\n if (githubAutomationFileKind(file) !== undefined) return \"config\";\n if (excludedInputPath(file)) return undefined;\n if (\n dependabotManifestEcosystem(file) !== undefined ||\n pythonDependencyManifestKind(file) === \"pipfile-lock\" ||\n javascriptDependencyLockfiles.some(\n (name) => file.split(\"/\").at(-1) === name,\n ) ||\n /(?:^|\\/)uv\\.lock$/.test(file) ||\n isFormatterConfigPath(file)\n )\n return \"presence\";\n if (\n githubAutomationFileKind(file) !== undefined ||\n isShellScript(file, text) ||\n /(?:^|\\/)ci-service-images\\.json$/.test(file) ||\n isMiseConfigPath(file) ||\n isPythonDependencyManifest(file) ||\n isDockerDefinitionPath(file) ||\n isComposeDefinitionPath(file) ||\n isKubernetesDefinitionPath(file) ||\n /(?:^|\\/)(?: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(\n file,\n )\n )\n return \"config\";\n return undefined;\n};\n"],"mappings":"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EACL,KAAK;EACL,QAAQ;EACR,SAAS;EACT,UAAU;GACR,4BACE;GACF,YAAY;GACZ,gBACE;EACJ;CACF;AACF;;AAGA,MAAa,sBAAsB;CACjC,eAAe;EACb,SAAS;EACT,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU,EACR,eAAe,cACjB;EACF;EACA,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU,EACR,eAAe,cACjB;EACF;CACF;CACA,UAAU;EACR,SAAS;EACT,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU,EAAE,UAAU,WAAW;EACnC;EACA,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU,EAAE,UAAU,WAAW;EACnC;CACF;CACA,iBAAiB;EACf,SAAS;EACT,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU,EACR,iBAAiB,gBACnB;EACF;EACA,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU,EACR,iBAAiB,gBACnB;EACF;CACF;CACA,oBAAoB;EAClB,SAAS;EACT,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU;IACR,4BACE;IACF,YAAY;IACZ,gBACE;GACJ;EACF;EACA,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU;IACR,4BACE;IACF,YACE;IACF,gBACE;GACJ;EACF;CACF;CACA,IAAI;EACF,SAAS;EACT,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU;IACR,IAAI;IACJ,KAAK;GACP;EACF;EACA,OAAO;GACL,KAAK;GACL,QACE;GACF,SAAS;GACT,UAAU;IACR,IAAI;IACJ,KAAK;GACP;EACF;CACF;AACF;;AASA,MAAa,8BAA8B,CACzC,iBACA,oBAAoB,mBACtB;;AAGA,MAAa,6BAA6B;CACxC,eAAe,CAAC,oBAAoB,cAAc;CAClD,iBAAiB,CAAC,oBAAoB,gBAAgB;CACtD,oBAAoB;CACpB,IAAI,CAAC,oBAAoB,EAAE;CAC3B,UAAU,CAAC,oBAA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"}