@stll/oxlint-config 2.1.2 → 2.1.3
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.
|
@@ -5,6 +5,91 @@ import { createHash } from "node:crypto";
|
|
|
5
5
|
import { subset, valid, validRange } from "semver";
|
|
6
6
|
import { isDeepStrictEqual } from "node:util";
|
|
7
7
|
import { parseDocument } from "yaml";
|
|
8
|
+
//#region src/cloud-setup-shell.ts
|
|
9
|
+
const cloudShellProfilePath = "/etc/profile.d/stll-cloud.sh";
|
|
10
|
+
const cloudShellProfileSource = `. ${cloudShellProfilePath}`;
|
|
11
|
+
const quote$1 = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
12
|
+
/**
|
|
13
|
+
* install, cp and mv place the file inside a target that resolves to a
|
|
14
|
+
* directory and still succeed, so every generated file publish refuses one
|
|
15
|
+
* first. `target` is the exact shell word the publish command uses.
|
|
16
|
+
*/
|
|
17
|
+
const refuseDirectoryTarget = (target) => `[[ ! -d ${target} ]] || fail 'Install target is a directory; remove it and rerun install:' ${target}`;
|
|
18
|
+
const renderCloudShellProfile = ({ nodeVersion, bunVersion, rust }) => {
|
|
19
|
+
const node = `/opt/stll-cloud/node/${nodeVersion}/bin`;
|
|
20
|
+
const bun = `/opt/stll-cloud/bun/${bunVersion}`;
|
|
21
|
+
return `# Generated by stll-cloud-setup; managed cloud shell environment.
|
|
22
|
+
# Remove managed entries before prepending, including repeated shell startup.
|
|
23
|
+
_stll_cloud_remaining="\${PATH-}"
|
|
24
|
+
_stll_cloud_result=''
|
|
25
|
+
_stll_cloud_separator=''
|
|
26
|
+
while :; do
|
|
27
|
+
case "$_stll_cloud_remaining" in
|
|
28
|
+
*:*) _stll_cloud_part="\${_stll_cloud_remaining%%:*}"; _stll_cloud_remaining="\${_stll_cloud_remaining#*:}"; _stll_cloud_more=yes ;;
|
|
29
|
+
*) _stll_cloud_part="$_stll_cloud_remaining"; _stll_cloud_more=no ;;
|
|
30
|
+
esac
|
|
31
|
+
case "$_stll_cloud_part" in
|
|
32
|
+
${quote$1(node)}|${quote$1(bun)}|/usr/local/bin) ;;
|
|
33
|
+
*) _stll_cloud_result="$_stll_cloud_result$_stll_cloud_separator$_stll_cloud_part"; _stll_cloud_separator=: ;;
|
|
34
|
+
esac
|
|
35
|
+
[ "$_stll_cloud_more" = yes ] || break
|
|
36
|
+
done
|
|
37
|
+
export PATH=${quote$1(`${node}:${bun}:/usr/local/bin`)}"\${_stll_cloud_separator:+:}$_stll_cloud_result"
|
|
38
|
+
unset _stll_cloud_remaining _stll_cloud_result _stll_cloud_separator _stll_cloud_part _stll_cloud_more
|
|
39
|
+
${rust === void 0 ? "" : `export RUSTUP_HOME=/opt/stll-cloud/rustup\nexport CARGO_HOME=/opt/stll-cloud/cargo\nexport RUSTUP_TOOLCHAIN=${quote$1(rust.channel)}\nexport RUSTUP_AUTO_INSTALL=0\n`}`;
|
|
40
|
+
};
|
|
41
|
+
const userStartup = String.raw`
|
|
42
|
+
set -euo pipefail
|
|
43
|
+
for name in .bashrc .profile .bash_profile .bash_login; do
|
|
44
|
+
file="$HOME/$name"
|
|
45
|
+
if [[ ! -e "$file" && ! -L "$file" && "$name" != .bashrc && "$name" != .profile ]]; then continue; fi
|
|
46
|
+
[[ ! -L "$file" ]] || { echo "cloud-setup: shell startup file must not be a symlink: $name" >&2; exit 1; }
|
|
47
|
+
if [[ -e "$file" ]]; then
|
|
48
|
+
[[ -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; }
|
|
49
|
+
fi
|
|
50
|
+
temporary="$(mktemp "$HOME/.stll-cloud-shell.XXXXXX")"
|
|
51
|
+
trap 'rm -f -- "$temporary"' EXIT
|
|
52
|
+
if [[ "$name" == .bashrc ]]; then
|
|
53
|
+
printf '%s\n' '# stll-cloud: early environment' '@SOURCE@' > "$temporary"
|
|
54
|
+
fi
|
|
55
|
+
if [[ -f "$file" ]]; then
|
|
56
|
+
# Remove only exact managed blocks; preserve unrelated startup lines and permissions.
|
|
57
|
+
awk '
|
|
58
|
+
$0 == "# stll-cloud: early environment" || $0 == "# stll-cloud: session environment" {
|
|
59
|
+
if ((getline following) <= 0 || following != "@SOURCE@") exit 1
|
|
60
|
+
next
|
|
61
|
+
}
|
|
62
|
+
{ print }
|
|
63
|
+
' "$file" >> "$temporary" || { echo "cloud-setup: managed shell startup block differs: $name" >&2; exit 1; }
|
|
64
|
+
fi
|
|
65
|
+
printf '%s\n' '# stll-cloud: session environment' '@SOURCE@' >> "$temporary"
|
|
66
|
+
if [[ -f "$file" ]] && cmp -s "$temporary" "$file"; then rm -- "$temporary"; continue; fi
|
|
67
|
+
if [[ -f "$file" ]]; then chmod --reference="$file" "$temporary"; else chmod 644 "$temporary"; fi
|
|
68
|
+
mv -f -- "$temporary" "$file"
|
|
69
|
+
done
|
|
70
|
+
`;
|
|
71
|
+
const renderCloudShellInstall = (options) => {
|
|
72
|
+
const profile = renderCloudShellProfile(options);
|
|
73
|
+
return `install_shell_environment() (
|
|
74
|
+
# Subshell scope retains temporary for EXIT cleanup after a failed command.
|
|
75
|
+
[[ ! -L ${quote$1(cloudShellProfilePath)} ]] || fail 'Managed shell profile must not be a symlink'
|
|
76
|
+
if [[ -e ${quote$1(cloudShellProfilePath)} ]]; then
|
|
77
|
+
[[ -f ${quote$1(cloudShellProfilePath)} && "$(stat -c '%h:%u' ${quote$1(cloudShellProfilePath)})" == 1:0 ]] || fail 'Managed shell profile must be a root-owned single-link file'
|
|
78
|
+
fi
|
|
79
|
+
temporary="$(mktemp)"
|
|
80
|
+
trap 'rm -f -- "$temporary"' EXIT
|
|
81
|
+
cat > "$temporary" <<'STLL_CLOUD_PROFILE'
|
|
82
|
+
${profile}STLL_CLOUD_PROFILE
|
|
83
|
+
if ! cmp -s "$temporary" ${quote$1(cloudShellProfilePath)}; then install -m 644 "$temporary" ${quote$1(cloudShellProfilePath)}; fi
|
|
84
|
+
runuser -u "$OUTPUT_USER" -- env HOME="$OUTPUT_HOME" bash -c ${quote$1(userStartup.replaceAll("@SOURCE@", cloudShellProfileSource))}
|
|
85
|
+
)
|
|
86
|
+
verify_shell_environment() {
|
|
87
|
+
[[ -f ${quote$1(cloudShellProfilePath)} && ! -L ${quote$1(cloudShellProfilePath)} && "$(stat -c '%h:%u' ${quote$1(cloudShellProfilePath)})" == 1:0 ]] || fail 'Managed shell environment is unavailable; run install'
|
|
88
|
+
[[ "$(sha256sum -- ${quote$1(cloudShellProfilePath)} | cut -d ' ' -f1)" == ${quote$1(createHash("sha256").update(profile).digest("hex"))} ]] || fail 'Managed shell environment differs; run install'
|
|
89
|
+
}
|
|
90
|
+
`;
|
|
91
|
+
};
|
|
92
|
+
//#endregion
|
|
8
93
|
//#region src/cloud-setup-install.ts
|
|
9
94
|
const packageInstall = String.raw`
|
|
10
95
|
# Prevent package maintainer scripts from starting unmanaged system services.
|
|
@@ -181,6 +266,7 @@ const postgresInstall = String.raw`
|
|
|
181
266
|
key_fingerprint="$(pgdg_key_fingerprint "$key")"
|
|
182
267
|
[[ "$key_fingerprint" == @PGDG_FINGERPRINT@ ]] || fail 'PostgreSQL signing key mismatch'
|
|
183
268
|
install -d -m 755 /usr/share/keyrings
|
|
269
|
+
${refuseDirectoryTarget("/usr/share/keyrings/stll-pgdg.asc")}
|
|
184
270
|
install -m 644 "$key" /usr/share/keyrings/stll-pgdg.asc
|
|
185
271
|
rm -- "$key"
|
|
186
272
|
printf '%s\n' '@PGDG_SOURCE@' > /etc/apt/sources.list.d/stll-pgdg.list
|
|
@@ -800,85 +886,6 @@ const renderCloudServiceStart = ({ services, postgres, valkey }) => {
|
|
|
800
886
|
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`;
|
|
801
887
|
};
|
|
802
888
|
//#endregion
|
|
803
|
-
//#region src/cloud-setup-shell.ts
|
|
804
|
-
const cloudShellProfilePath = "/etc/profile.d/stll-cloud.sh";
|
|
805
|
-
const cloudShellProfileSource = `. ${cloudShellProfilePath}`;
|
|
806
|
-
const quote$1 = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
807
|
-
const renderCloudShellProfile = ({ nodeVersion, bunVersion, rust }) => {
|
|
808
|
-
const node = `/opt/stll-cloud/node/${nodeVersion}/bin`;
|
|
809
|
-
const bun = `/opt/stll-cloud/bun/${bunVersion}`;
|
|
810
|
-
return `# Generated by stll-cloud-setup; managed cloud shell environment.
|
|
811
|
-
# Remove managed entries before prepending, including repeated shell startup.
|
|
812
|
-
_stll_cloud_remaining="\${PATH-}"
|
|
813
|
-
_stll_cloud_result=''
|
|
814
|
-
_stll_cloud_separator=''
|
|
815
|
-
while :; do
|
|
816
|
-
case "$_stll_cloud_remaining" in
|
|
817
|
-
*:*) _stll_cloud_part="\${_stll_cloud_remaining%%:*}"; _stll_cloud_remaining="\${_stll_cloud_remaining#*:}"; _stll_cloud_more=yes ;;
|
|
818
|
-
*) _stll_cloud_part="$_stll_cloud_remaining"; _stll_cloud_more=no ;;
|
|
819
|
-
esac
|
|
820
|
-
case "$_stll_cloud_part" in
|
|
821
|
-
${quote$1(node)}|${quote$1(bun)}|/usr/local/bin) ;;
|
|
822
|
-
*) _stll_cloud_result="$_stll_cloud_result$_stll_cloud_separator$_stll_cloud_part"; _stll_cloud_separator=: ;;
|
|
823
|
-
esac
|
|
824
|
-
[ "$_stll_cloud_more" = yes ] || break
|
|
825
|
-
done
|
|
826
|
-
export PATH=${quote$1(`${node}:${bun}:/usr/local/bin`)}"\${_stll_cloud_separator:+:}$_stll_cloud_result"
|
|
827
|
-
unset _stll_cloud_remaining _stll_cloud_result _stll_cloud_separator _stll_cloud_part _stll_cloud_more
|
|
828
|
-
${rust === void 0 ? "" : `export RUSTUP_HOME=/opt/stll-cloud/rustup\nexport CARGO_HOME=/opt/stll-cloud/cargo\nexport RUSTUP_TOOLCHAIN=${quote$1(rust.channel)}\nexport RUSTUP_AUTO_INSTALL=0\n`}`;
|
|
829
|
-
};
|
|
830
|
-
const userStartup = String.raw`
|
|
831
|
-
set -euo pipefail
|
|
832
|
-
for name in .bashrc .profile .bash_profile .bash_login; do
|
|
833
|
-
file="$HOME/$name"
|
|
834
|
-
if [[ ! -e "$file" && ! -L "$file" && "$name" != .bashrc && "$name" != .profile ]]; then continue; fi
|
|
835
|
-
[[ ! -L "$file" ]] || { echo "cloud-setup: shell startup file must not be a symlink: $name" >&2; exit 1; }
|
|
836
|
-
if [[ -e "$file" ]]; then
|
|
837
|
-
[[ -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; }
|
|
838
|
-
fi
|
|
839
|
-
temporary="$(mktemp "$HOME/.stll-cloud-shell.XXXXXX")"
|
|
840
|
-
trap 'rm -f -- "$temporary"' EXIT
|
|
841
|
-
if [[ "$name" == .bashrc ]]; then
|
|
842
|
-
printf '%s\n' '# stll-cloud: early environment' '@SOURCE@' > "$temporary"
|
|
843
|
-
fi
|
|
844
|
-
if [[ -f "$file" ]]; then
|
|
845
|
-
# Remove only exact managed blocks; preserve unrelated startup lines and permissions.
|
|
846
|
-
awk '
|
|
847
|
-
$0 == "# stll-cloud: early environment" || $0 == "# stll-cloud: session environment" {
|
|
848
|
-
if ((getline following) <= 0 || following != "@SOURCE@") exit 1
|
|
849
|
-
next
|
|
850
|
-
}
|
|
851
|
-
{ print }
|
|
852
|
-
' "$file" >> "$temporary" || { echo "cloud-setup: managed shell startup block differs: $name" >&2; exit 1; }
|
|
853
|
-
fi
|
|
854
|
-
printf '%s\n' '# stll-cloud: session environment' '@SOURCE@' >> "$temporary"
|
|
855
|
-
if [[ -f "$file" ]] && cmp -s "$temporary" "$file"; then rm -- "$temporary"; continue; fi
|
|
856
|
-
if [[ -f "$file" ]]; then chmod --reference="$file" "$temporary"; else chmod 644 "$temporary"; fi
|
|
857
|
-
mv -f -- "$temporary" "$file"
|
|
858
|
-
done
|
|
859
|
-
`;
|
|
860
|
-
const renderCloudShellInstall = (options) => {
|
|
861
|
-
const profile = renderCloudShellProfile(options);
|
|
862
|
-
return `install_shell_environment() (
|
|
863
|
-
# Subshell scope retains temporary for EXIT cleanup after a failed command.
|
|
864
|
-
[[ ! -L ${quote$1(cloudShellProfilePath)} ]] || fail 'Managed shell profile must not be a symlink'
|
|
865
|
-
if [[ -e ${quote$1(cloudShellProfilePath)} ]]; then
|
|
866
|
-
[[ -f ${quote$1(cloudShellProfilePath)} && "$(stat -c '%h:%u' ${quote$1(cloudShellProfilePath)})" == 1:0 ]] || fail 'Managed shell profile must be a root-owned single-link file'
|
|
867
|
-
fi
|
|
868
|
-
temporary="$(mktemp)"
|
|
869
|
-
trap 'rm -f -- "$temporary"' EXIT
|
|
870
|
-
cat > "$temporary" <<'STLL_CLOUD_PROFILE'
|
|
871
|
-
${profile}STLL_CLOUD_PROFILE
|
|
872
|
-
if ! cmp -s "$temporary" ${quote$1(cloudShellProfilePath)}; then install -m 644 "$temporary" ${quote$1(cloudShellProfilePath)}; fi
|
|
873
|
-
runuser -u "$OUTPUT_USER" -- env HOME="$OUTPUT_HOME" bash -c ${quote$1(userStartup.replaceAll("@SOURCE@", cloudShellProfileSource))}
|
|
874
|
-
)
|
|
875
|
-
verify_shell_environment() {
|
|
876
|
-
[[ -f ${quote$1(cloudShellProfilePath)} && ! -L ${quote$1(cloudShellProfilePath)} && "$(stat -c '%h:%u' ${quote$1(cloudShellProfilePath)})" == 1:0 ]] || fail 'Managed shell environment is unavailable; run install'
|
|
877
|
-
[[ "$(sha256sum -- ${quote$1(cloudShellProfilePath)} | cut -d ' ' -f1)" == ${quote$1(createHash("sha256").update(profile).digest("hex"))} ]] || fail 'Managed shell environment differs; run install'
|
|
878
|
-
}
|
|
879
|
-
`;
|
|
880
|
-
};
|
|
881
|
-
//#endregion
|
|
882
889
|
//#region src/cloud-setup-toolchains.ts
|
|
883
890
|
const record$2 = (input) => typeof input === "object" && input !== null && !Array.isArray(input);
|
|
884
891
|
/** Resolve the same tracked snapshot for generation and the mandatory drift check. */
|
|
@@ -1033,6 +1040,7 @@ install_rust() (
|
|
|
1033
1040
|
# Launchers persist the system homes in fresh shells without profile sourcing.
|
|
1034
1041
|
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"
|
|
1035
1042
|
if ! cmp -s "$scratch/$tool" "/usr/local/bin/$tool"; then
|
|
1043
|
+
${refuseDirectoryTarget("\"/usr/local/bin/$tool\"")}
|
|
1036
1044
|
install -m 755 "$scratch/$tool" "/usr/local/bin/$tool"
|
|
1037
1045
|
fi
|
|
1038
1046
|
done
|
|
@@ -1078,7 +1086,7 @@ install_${tool.replaceAll("-", "_")}() (
|
|
|
1078
1086
|
tar -xzf "$scratch/archive.tar.gz" -C "$scratch"
|
|
1079
1087
|
install -d -m 755 ${quote(directory)}
|
|
1080
1088
|
case "$ARCH" in
|
|
1081
|
-
${["amd64", "arm64"].map((arch) => ` ${arch})\n${Object.entries(release[arch].binaries).map(([binary, path]) => ` install -m 755 "$scratch/${path}" ${quote(`${directory}/${binary}`)}`).join("\n")}\n ;;`).join("\n")}
|
|
1089
|
+
${["amd64", "arm64"].map((arch) => ` ${arch})\n${Object.entries(release[arch].binaries).map(([binary, path]) => ` ${refuseDirectoryTarget(quote(`${directory}/${binary}`))}\n install -m 755 "$scratch/${path}" ${quote(`${directory}/${binary}`)}`).join("\n")}\n ;;`).join("\n")}
|
|
1082
1090
|
esac
|
|
1083
1091
|
verify_${tool.replaceAll("-", "_")} || fail ${quote(`Installed ${tool} version differs from its pin`)}
|
|
1084
1092
|
fi
|
|
@@ -1300,6 +1308,7 @@ install_runtimes() (
|
|
|
1300
1308
|
(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 -)
|
|
1301
1309
|
unzip -q "$scratch/$bun_archive" -d "$scratch/bun"
|
|
1302
1310
|
install -d -m 755 "$BUN_DIR"
|
|
1311
|
+
${refuseDirectoryTarget("\"$BUN_DIR/bun\"")}
|
|
1303
1312
|
install -m 755 "$scratch/bun/$bun_folder/bun" "$BUN_DIR/bun"
|
|
1304
1313
|
fi
|
|
1305
1314
|
runtime_ready
|
|
@@ -1654,6 +1663,52 @@ $cloud_shell_exports"
|
|
|
1654
1663
|
fi`
|
|
1655
1664
|
}]
|
|
1656
1665
|
});
|
|
1666
|
+
const releasedSnapshotHook = (script) => ({
|
|
1667
|
+
matcher: "",
|
|
1668
|
+
hooks: [{
|
|
1669
|
+
type: "command",
|
|
1670
|
+
command: `if [ "\${CLAUDE_CODE_REMOTE:-}" = "true" ]; then
|
|
1671
|
+
cloud_setup_incomplete() {
|
|
1672
|
+
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.'
|
|
1673
|
+
printf '%s\\n' "cloud-setup: $1" >&2
|
|
1674
|
+
exit 0
|
|
1675
|
+
}
|
|
1676
|
+
if [ -n "\${CLAUDE_ENV_FILE:-}" ]; then
|
|
1677
|
+
cloud_session_exports="$(${script} session)" || cloud_setup_incomplete 'startup failed; run install'
|
|
1678
|
+
else
|
|
1679
|
+
${script} start >&2 || cloud_setup_incomplete 'startup failed; run install'
|
|
1680
|
+
exit 0
|
|
1681
|
+
fi
|
|
1682
|
+
if [ -n "\${CLAUDE_ENV_FILE:-}" ]; then
|
|
1683
|
+
if [ ! -s ${cloudShellProfilePath} ]; then
|
|
1684
|
+
cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1685
|
+
fi
|
|
1686
|
+
cloud_shell_exports="$(cat ${cloudShellProfilePath})" || cloud_setup_incomplete 'cloud shell profile could not be read; run install'
|
|
1687
|
+
[ -n "$cloud_shell_exports" ] || cloud_setup_incomplete 'cloud shell profile is unavailable; run install'
|
|
1688
|
+
if [ -e "$CLAUDE_ENV_FILE" ] || [ -L "$CLAUDE_ENV_FILE" ]; then
|
|
1689
|
+
[ -f "$CLAUDE_ENV_FILE" ] && [ ! -L "$CLAUDE_ENV_FILE" ] || cloud_setup_incomplete 'session environment must be a regular file; check its path and rerun start'
|
|
1690
|
+
fi
|
|
1691
|
+
cloud_env_snapshot="\${CLAUDE_ENV_FILE}.stll-cloud"
|
|
1692
|
+
case "$cloud_env_snapshot" in
|
|
1693
|
+
*"'"*) cloud_setup_incomplete 'session environment path must not contain a single quote; check its path and rerun start' ;;
|
|
1694
|
+
esac
|
|
1695
|
+
if [ -n "$cloud_session_exports" ]; then
|
|
1696
|
+
cloud_session_exports="$cloud_session_exports
|
|
1697
|
+
$cloud_shell_exports"
|
|
1698
|
+
else
|
|
1699
|
+
cloud_session_exports="$cloud_shell_exports"
|
|
1700
|
+
fi
|
|
1701
|
+
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'
|
|
1702
|
+
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'; }
|
|
1703
|
+
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'; }
|
|
1704
|
+
cloud_env_source=". '$cloud_env_snapshot'"
|
|
1705
|
+
if [ ! -f "$CLAUDE_ENV_FILE" ] || ! grep -Fqx -- "$cloud_env_source" "$CLAUDE_ENV_FILE"; then
|
|
1706
|
+
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'
|
|
1707
|
+
fi
|
|
1708
|
+
fi
|
|
1709
|
+
fi`
|
|
1710
|
+
}]
|
|
1711
|
+
});
|
|
1657
1712
|
const sessionStartHook = (script) => ({
|
|
1658
1713
|
matcher: "",
|
|
1659
1714
|
hooks: [{
|
|
@@ -1683,6 +1738,9 @@ const sessionStartHook = (script) => ({
|
|
|
1683
1738
|
case "$cloud_env_snapshot" in
|
|
1684
1739
|
*"'"*) cloud_setup_incomplete 'session environment path must not contain a single quote; check its path and rerun start' ;;
|
|
1685
1740
|
esac
|
|
1741
|
+
if [ -e "$cloud_env_snapshot" ] || [ -L "$cloud_env_snapshot" ]; then
|
|
1742
|
+
[ -f "$cloud_env_snapshot" ] && [ ! -L "$cloud_env_snapshot" ] || cloud_setup_incomplete "session environment snapshot must be a regular file; remove $cloud_env_snapshot and rerun start"
|
|
1743
|
+
fi
|
|
1686
1744
|
if [ -n "$cloud_session_exports" ]; then
|
|
1687
1745
|
cloud_session_exports="$cloud_session_exports
|
|
1688
1746
|
$cloud_shell_exports"
|
|
@@ -1692,6 +1750,7 @@ $cloud_shell_exports"
|
|
|
1692
1750
|
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'
|
|
1693
1751
|
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'; }
|
|
1694
1752
|
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'; }
|
|
1753
|
+
[ -f "$cloud_env_snapshot" ] && [ ! -L "$cloud_env_snapshot" ] || cloud_setup_incomplete "session environment snapshot must be a regular file; remove $cloud_env_snapshot and rerun start"
|
|
1695
1754
|
cloud_env_source=". '$cloud_env_snapshot'"
|
|
1696
1755
|
if [ ! -f "$CLAUDE_ENV_FILE" ] || ! grep -Fqx -- "$cloud_env_source" "$CLAUDE_ENV_FILE"; then
|
|
1697
1756
|
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'
|
|
@@ -1727,7 +1786,8 @@ const previousCloudSessionStartHooks = [
|
|
|
1727
1786
|
releasedSessionStartHook(`bash ${cloudSetupPath}`),
|
|
1728
1787
|
releasedSessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`),
|
|
1729
1788
|
currentMainSessionStartHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`),
|
|
1730
|
-
releasedTemporaryFileHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`)
|
|
1789
|
+
releasedTemporaryFileHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`),
|
|
1790
|
+
releasedSnapshotHook(`bash "$CLAUDE_PROJECT_DIR/${cloudSetupPath}"`)
|
|
1731
1791
|
];
|
|
1732
1792
|
const cloudAttribution = {
|
|
1733
1793
|
commit: "",
|