karnel-termux 4.17.0 → 4.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/install.sh +20 -2
- package/karnel/RELEASE_COMMIT +1 -1
- package/karnel/bin/karnel +2 -1
- package/karnel/cli/commands/backup.sh +1 -1
- package/karnel/cli/commands/doctor/fixes.sh +2 -2
- package/karnel/cli/commands/init.sh +21 -21
- package/karnel/cli/commands/supabase.sh +1 -1
- package/karnel/tools/ai/antigravity-cli/install.sh +18 -6
- package/karnel/tools/ai/ctx7/install.sh +7 -0
- package/karnel/tools/ai/droid/install.sh +19 -6
- package/karnel/tools/ai/freebuff/install.sh +7 -0
- package/karnel/tools/ai/goose/install.sh +1 -0
- package/karnel/tools/ai/keelcode/install.sh +7 -0
- package/karnel/tools/ai/kimchi-code/install.sh +9 -3
- package/karnel/tools/ai/oh-my-pi/install.sh +31 -6
- package/karnel/tools/ai/omni-route/install.sh +7 -0
- package/karnel/tools/ai/openspec/install.sh +7 -0
- package/karnel/tools/ai/puter/install.sh +7 -0
- package/karnel/tools/ai/supercode-cli/install.sh +7 -0
- package/karnel/tools/db/redis/install.sh +4 -1
- package/karnel/tools/deploy/netlify/install.sh +7 -0
- package/karnel/tools/deploy/railway/install.sh +9 -0
- package/karnel/tools/deploy/vercel/install.sh +7 -0
- package/karnel/tools/dev/openssh/install.sh +4 -1
- package/karnel/tools/dev/tmux/install.sh +4 -1
- package/karnel/tools/lang/bun/install.sh +26 -7
- package/karnel/tools/npm/turbopack/install.sh +2 -2
- package/karnel/tools/osint/robin/install.sh +6 -2
- package/karnel/tools/security/amass/install.sh +7 -0
- package/karnel/tools/security/subfinder/install.sh +7 -0
- package/karnel/tools/shell/zsh-defer/install.sh +1 -1
- package/karnel/utils/install.sh +7 -1
- package/karnel/utils/tools.sh +4 -0
- package/karnel/utils/uninstall.sh +2 -1
- package/package.json +1 -1
package/install.sh
CHANGED
|
@@ -79,7 +79,9 @@ _INSTALL_KARNEL_SYMLINK_CHANGED=false
|
|
|
79
79
|
_INSTALL_PREVIOUS_KARNEL_SYMLINK=""
|
|
80
80
|
|
|
81
81
|
_cleanup_failed() {
|
|
82
|
-
|
|
82
|
+
set +e
|
|
83
|
+
trap - ERR
|
|
84
|
+
echo -e "\n ${P_FAIL}✖${P_NC} Installation failed at step ${CURRENT_STEP}. Cleaning up..."
|
|
83
85
|
if $_INSTALL_KARNEL_SYMLINK_CHANGED; then
|
|
84
86
|
if [[ -n "$_INSTALL_PREVIOUS_KARNEL_SYMLINK" ]]; then
|
|
85
87
|
local rollback_link_dir
|
|
@@ -287,7 +289,23 @@ clone_repo() {
|
|
|
287
289
|
log_fail "Failed to clone repository"
|
|
288
290
|
return 1
|
|
289
291
|
fi
|
|
290
|
-
if [[ -n "$
|
|
292
|
+
if [[ -n "$RELEASE_COMMIT" ]]; then
|
|
293
|
+
if ! git -C "$candidate_repo" fetch --depth=1 origin "$RELEASE_COMMIT" &>/dev/null; then
|
|
294
|
+
log_fail "Failed to fetch release commit $RELEASE_COMMIT"
|
|
295
|
+
return 1
|
|
296
|
+
fi
|
|
297
|
+
if ! git -C "$candidate_repo" checkout --quiet --detach "$RELEASE_COMMIT" &>/dev/null; then
|
|
298
|
+
log_fail "Failed to checkout release commit $RELEASE_COMMIT"
|
|
299
|
+
return 1
|
|
300
|
+
fi
|
|
301
|
+
local candidate_commit
|
|
302
|
+
candidate_commit=$(git -C "$candidate_repo" rev-parse HEAD 2>/dev/null) || return 1
|
|
303
|
+
if [[ "$candidate_commit" != "$RELEASE_COMMIT" ]]; then
|
|
304
|
+
log_fail "Release commit mismatch"
|
|
305
|
+
log_info "Expected $RELEASE_COMMIT, got $candidate_commit"
|
|
306
|
+
return 1
|
|
307
|
+
fi
|
|
308
|
+
elif [[ -n "$RELEASE_REF" ]]; then
|
|
291
309
|
local candidate_commit
|
|
292
310
|
candidate_commit=$(git -C "$candidate_repo" rev-parse HEAD 2>/dev/null) || return 1
|
|
293
311
|
if [[ "$candidate_commit" != "$RELEASE_COMMIT" ]]; then
|
package/karnel/RELEASE_COMMIT
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
680f9d3f783c6f2bf95e4499c3e230d2d25b7070
|
package/karnel/bin/karnel
CHANGED
|
@@ -30,7 +30,8 @@ import "@/utils/env"
|
|
|
30
30
|
|
|
31
31
|
# ===== SEMVER COMPARISON =====
|
|
32
32
|
_semver_gt() {
|
|
33
|
-
|
|
33
|
+
local a="${1#v}" b="${2#v}"
|
|
34
|
+
[[ "$(printf '%s\n%s' "$a" "$b" | sort -V | tail -1)" == "$a" ]] && [[ "$a" != "$b" ]]
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
_valid_semver() {
|
|
@@ -292,7 +292,7 @@ _fix_locale() {
|
|
|
292
292
|
if [[ ! -f "$config" ]] && [[ -f "$HOME/.bashrc" ]]; then
|
|
293
293
|
config="$HOME/.bashrc"
|
|
294
294
|
fi
|
|
295
|
-
echo 'export LANG=en_US.UTF-8' >> "$config" 2>/dev/null
|
|
295
|
+
grep -qxF 'export LANG=en_US.UTF-8' "$config" 2>/dev/null || echo 'export LANG=en_US.UTF-8' >> "$config" 2>/dev/null
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
|
|
@@ -425,6 +425,6 @@ _fix_keyring() {
|
|
|
425
425
|
}
|
|
426
426
|
|
|
427
427
|
_fix_apt_cache() {
|
|
428
|
-
rm -rf "$PREFIX/var/apt/lists"/* 2>/dev/null
|
|
428
|
+
rm -rf "${PREFIX:?}/var/apt/lists"/* 2>/dev/null
|
|
429
429
|
pkg update -y &>/dev/null
|
|
430
430
|
}
|
|
@@ -1078,33 +1078,33 @@ configure_rust() {
|
|
|
1078
1078
|
|
|
1079
1079
|
# Append dependencies to Cargo.toml
|
|
1080
1080
|
if [[ -f "Cargo.toml" ]]; then
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
cat >>Cargo.toml <<EOF
|
|
1084
|
-
EOF
|
|
1085
|
-
else
|
|
1086
|
-
echo -e "\n[dependencies]" >> Cargo.toml
|
|
1081
|
+
if ! grep -q '^\[dependencies\]' Cargo.toml; then
|
|
1082
|
+
printf '\n[dependencies]\n' >> Cargo.toml
|
|
1087
1083
|
fi
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1084
|
+
local dep name spec
|
|
1085
|
+
local -a deps=(
|
|
1086
|
+
'tokio = { version = "1.0", features = ["full"] }'
|
|
1087
|
+
'serde = { version = "1.0", features = ["derive"] }'
|
|
1088
|
+
'serde_json = "1.0"'
|
|
1089
|
+
'dotenvy = "0.15"'
|
|
1090
|
+
)
|
|
1094
1091
|
if [[ "$framework_choice" == "Axum" ]]; then
|
|
1095
|
-
|
|
1096
|
-
axum = "0.7"
|
|
1097
|
-
EOF
|
|
1092
|
+
deps+=('axum = "0.7"')
|
|
1098
1093
|
else
|
|
1099
|
-
|
|
1100
|
-
actix-web = "4.0"
|
|
1101
|
-
EOF
|
|
1094
|
+
deps+=('actix-web = "4.0"')
|
|
1102
1095
|
fi
|
|
1103
1096
|
if [[ "$db_choice" == "SQLx (PostgreSQL)" ]]; then
|
|
1104
|
-
|
|
1105
|
-
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres", "macros"] }
|
|
1106
|
-
EOF
|
|
1097
|
+
deps+=('sqlx = { version = "0.7", features = ["runtime-tokio", "postgres", "macros"] }')
|
|
1107
1098
|
fi
|
|
1099
|
+
for dep in "${deps[@]}"; do
|
|
1100
|
+
name="${dep%% =*}"
|
|
1101
|
+
name="${name%%[[:space:]]*}"
|
|
1102
|
+
if grep -q "^${name} =" Cargo.toml; then
|
|
1103
|
+
log_info "Dependency already present: ${name}"
|
|
1104
|
+
else
|
|
1105
|
+
sed -i "/^\[dependencies\]/a ${dep}" Cargo.toml
|
|
1106
|
+
fi
|
|
1107
|
+
done
|
|
1108
1108
|
log_success "Configured Cargo.toml"
|
|
1109
1109
|
fi
|
|
1110
1110
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import "@/utils/log"
|
|
4
4
|
import "@/utils/colors"
|
|
5
5
|
import "@/utils/version"
|
|
6
|
+
import "@/utils/install"
|
|
6
7
|
|
|
7
8
|
LOG_FILE="$KARNEL_CACHE/install_ai.log"
|
|
8
9
|
AGY_DATA_DIR="$HOME/.local/share/karnel-data/antigravity-cli"
|
|
@@ -63,17 +64,22 @@ _antigravity_download_binary() {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
_antigravity_download_binary_impl() {
|
|
66
|
-
local
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
local manifest
|
|
68
|
+
manifest=$(curl -fsSL "$MANIFEST_URL") || {
|
|
69
|
+
log_error "Failed to fetch Antigravity CLI manifest"
|
|
70
|
+
return 1
|
|
71
|
+
}
|
|
72
|
+
local latest_version download_url manifest_sha256
|
|
73
|
+
latest_version=$(printf '%s' "$manifest" | jq -r .version)
|
|
74
|
+
download_url=$(printf '%s' "$manifest" | jq -r .url)
|
|
75
|
+
manifest_sha256=$(printf '%s' "$manifest" | jq -r '.sha256 // empty')
|
|
76
|
+
if [ -z "$latest_version" ] || [ -z "$download_url" ]; then
|
|
77
|
+
log_error "Failed to parse Antigravity CLI manifest"
|
|
70
78
|
return 1
|
|
71
79
|
fi
|
|
72
80
|
|
|
73
81
|
mkdir -p "$AGY_DATA_DIR"
|
|
74
82
|
|
|
75
|
-
local download_url
|
|
76
|
-
download_url=$(_antigravity_get_download_url)
|
|
77
83
|
local tarball="$AGY_DATA_DIR/agy.tar.gz"
|
|
78
84
|
|
|
79
85
|
if ! curl -fsSL -o "$tarball" "$download_url" &>>"$LOG_FILE"; then
|
|
@@ -81,6 +87,12 @@ _antigravity_download_binary_impl() {
|
|
|
81
87
|
return 1
|
|
82
88
|
fi
|
|
83
89
|
|
|
90
|
+
if [[ "$manifest_sha256" =~ ^[0-9a-f]{64}$ ]]; then
|
|
91
|
+
verify_sha256 "$tarball" "$manifest_sha256" || return 1
|
|
92
|
+
else
|
|
93
|
+
log_warn "Antigravity CLI manifest does not publish a SHA-256; skipping integrity verification"
|
|
94
|
+
fi
|
|
95
|
+
|
|
84
96
|
if ! tar -xzf "$tarball" -C "$AGY_DATA_DIR" &>>"$LOG_FILE"; then
|
|
85
97
|
log_error "Failed to extract Antigravity CLI binary"
|
|
86
98
|
return 1
|
|
@@ -13,6 +13,13 @@ install_ctx7() {
|
|
|
13
13
|
return 2
|
|
14
14
|
fi
|
|
15
15
|
|
|
16
|
+
if ! command -v npm &>/dev/null; then
|
|
17
|
+
if ! pkg install nodejs-lts -y &>>"$LOG_FILE"; then
|
|
18
|
+
log_error "Failed to install Node.js (required by ctx7)"
|
|
19
|
+
return 1
|
|
20
|
+
fi
|
|
21
|
+
fi
|
|
22
|
+
|
|
16
23
|
log_info "Installing ctx7 (Context7 documentation provider)..."
|
|
17
24
|
npm install -g ctx7 2>/dev/null
|
|
18
25
|
local rc=$?
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import "@/utils/log"
|
|
4
4
|
import "@/utils/colors"
|
|
5
5
|
import "@/utils/version"
|
|
6
|
+
import "@/utils/install"
|
|
6
7
|
import "@/utils/uninstall"
|
|
7
8
|
|
|
8
9
|
: "${KARNEL_DATA:=${XDG_DATA_HOME:-$HOME/.local/share}/karnel-data}"
|
|
@@ -239,14 +240,20 @@ _droid_ubuntu_install_bin() {
|
|
|
239
240
|
|
|
240
241
|
local binary_url="https://downloads.factory.ai/factory-cli/releases/$latest_version/linux/arm64/droid"
|
|
241
242
|
|
|
242
|
-
|
|
243
|
+
local expected
|
|
244
|
+
expected=$(curl -fsSL "$binary_url.sha256" 2>/dev/null | awk '{print $1}') || expected=""
|
|
245
|
+
if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
|
|
246
|
+
log_warn "No published SHA-256 for Droid; skipping integrity verification"
|
|
247
|
+
fi
|
|
248
|
+
_droid_proot_ubuntu /bin/bash -c '
|
|
243
249
|
mkdir -p /tmp/droid-install &&
|
|
244
|
-
curl -fsSL
|
|
250
|
+
curl -fsSL "$1" -o /tmp/droid-install/droid &&
|
|
251
|
+
{ [ -z "$2" ] || [ "$(sha256sum /tmp/droid-install/droid | awk "{print \$1}")" = "$2" ]; } &&
|
|
245
252
|
mkdir -p /usr/local/bin &&
|
|
246
253
|
mv /tmp/droid-install/droid /usr/local/bin/droid &&
|
|
247
254
|
chmod +x /usr/local/bin/droid &&
|
|
248
255
|
rm -rf /tmp/droid-install
|
|
249
|
-
" &>>"$LOG_FILE"
|
|
256
|
+
' bash "$binary_url" "$expected" &>>"$LOG_FILE"
|
|
250
257
|
|
|
251
258
|
local droid_bin="$(_droid_detect_ubuntu_root)/usr/local/bin/droid"
|
|
252
259
|
if [ ! -f "$droid_bin" ]; then
|
|
@@ -413,14 +420,20 @@ _update_droid_proot_impl() {
|
|
|
413
420
|
|
|
414
421
|
local binary_url="https://downloads.factory.ai/factory-cli/releases/$latest_version/linux/arm64/droid"
|
|
415
422
|
|
|
416
|
-
|
|
423
|
+
local expected
|
|
424
|
+
expected=$(curl -fsSL "$binary_url.sha256" 2>/dev/null | awk '{print $1}') || expected=""
|
|
425
|
+
if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
|
|
426
|
+
log_warn "No published SHA-256 for Droid; skipping integrity verification"
|
|
427
|
+
fi
|
|
428
|
+
_droid_proot_ubuntu /bin/bash -c '
|
|
417
429
|
rm -f /usr/local/bin/droid &&
|
|
418
430
|
mkdir -p /tmp/droid-update &&
|
|
419
|
-
curl -fsSL
|
|
431
|
+
curl -fsSL "$1" -o /tmp/droid-update/droid &&
|
|
432
|
+
{ [ -z "$2" ] || [ "$(sha256sum /tmp/droid-update/droid | awk "{print \$1}")" = "$2" ]; } &&
|
|
420
433
|
mv /tmp/droid-update/droid /usr/local/bin/droid &&
|
|
421
434
|
chmod +x /usr/local/bin/droid &&
|
|
422
435
|
rm -rf /tmp/droid-update
|
|
423
|
-
" &>>"$LOG_FILE"
|
|
436
|
+
' bash "$binary_url" "$expected" &>>"$LOG_FILE"
|
|
424
437
|
|
|
425
438
|
local ubuntu_root
|
|
426
439
|
ubuntu_root="$(_droid_detect_ubuntu_root)"
|
|
@@ -9,6 +9,13 @@ install_freebuff() {
|
|
|
9
9
|
return 2
|
|
10
10
|
fi
|
|
11
11
|
|
|
12
|
+
if ! command -v npm &>/dev/null; then
|
|
13
|
+
if ! pkg install nodejs-lts -y &>>"$LOG_FILE"; then
|
|
14
|
+
log_error "Failed to install Node.js (required by Freebuff)"
|
|
15
|
+
return 1
|
|
16
|
+
fi
|
|
17
|
+
fi
|
|
18
|
+
|
|
12
19
|
log_info "Installing Freebuff..."
|
|
13
20
|
npm install -g freebuff || {
|
|
14
21
|
log_error "Failed to install Freebuff"
|
|
@@ -196,6 +196,7 @@ _goose_download_binary_proot_impl() {
|
|
|
196
196
|
log_error "Failed to download Goose CLI"
|
|
197
197
|
return 1
|
|
198
198
|
fi
|
|
199
|
+
verify_github_release_asset aaif-goose/goose "v${latest_version}" "$tarball" "$GOOSE_DATA_DIR/$tarball" || return 1
|
|
199
200
|
if ! tar -xzf "$GOOSE_DATA_DIR/$tarball" -C "$GOOSE_DATA_DIR" &>>"$LOG_FILE"; then
|
|
200
201
|
rm -f "$GOOSE_DATA_DIR/$tarball"
|
|
201
202
|
log_error "Failed to extract Goose CLI"
|
|
@@ -117,6 +117,13 @@ install_keelcode() {
|
|
|
117
117
|
fi
|
|
118
118
|
_keelcode_verify_ownership || return 1
|
|
119
119
|
|
|
120
|
+
if ! command -v npm &>/dev/null; then
|
|
121
|
+
if ! pkg install nodejs-lts -y &>>"$LOG_FILE"; then
|
|
122
|
+
log_error "Failed to install Node.js (required by KeelCode)"
|
|
123
|
+
return 1
|
|
124
|
+
fi
|
|
125
|
+
fi
|
|
126
|
+
|
|
120
127
|
log_info "Installing KeelCode..."
|
|
121
128
|
local output rc
|
|
122
129
|
output="$(npm install -g "$KEELCODE_PACKAGE" --force 2>&1)"
|
|
@@ -262,9 +262,15 @@ _kimchi_ubuntu_install_bin() {
|
|
|
262
262
|
|
|
263
263
|
local download_url="https://github.com/getkimchi/kimchi/releases/download/$latest_version/kimchi_linux_arm64.tar.gz"
|
|
264
264
|
|
|
265
|
-
|
|
265
|
+
local expected
|
|
266
|
+
expected=$(github_release_asset_sha256 getkimchi/kimchi "$latest_version" "kimchi_linux_arm64.tar.gz") || expected=""
|
|
267
|
+
if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
|
|
268
|
+
log_warn "No published SHA-256 for Kimchi; skipping integrity verification"
|
|
269
|
+
fi
|
|
270
|
+
_kimchi_proot_ubuntu /bin/bash -c '
|
|
266
271
|
mkdir -p /tmp/kimchi-install &&
|
|
267
|
-
curl -fsSL
|
|
272
|
+
curl -fsSL "$1" -o /tmp/kimchi-install/kimchi.tar.gz &&
|
|
273
|
+
{ [ -z "$2" ] || [ "$(sha256sum /tmp/kimchi-install/kimchi.tar.gz | awk "{print \$1}")" = "$2" ]; } &&
|
|
268
274
|
tar -zxf /tmp/kimchi-install/kimchi.tar.gz -C /tmp/kimchi-install &&
|
|
269
275
|
mkdir -p /usr/local/bin /usr/local/share &&
|
|
270
276
|
mv /tmp/kimchi-install/bin/kimchi /usr/local/bin/kimchi &&
|
|
@@ -272,7 +278,7 @@ _kimchi_ubuntu_install_bin() {
|
|
|
272
278
|
rm -rf /usr/local/share/kimchi &&
|
|
273
279
|
mv /tmp/kimchi-install/share/kimchi /usr/local/share/kimchi &&
|
|
274
280
|
rm -rf /tmp/kimchi-install
|
|
275
|
-
" &>>"$LOG_FILE"
|
|
281
|
+
' bash "$download_url" "$expected" &>>"$LOG_FILE"
|
|
276
282
|
|
|
277
283
|
local kimchi_bin
|
|
278
284
|
kimchi_bin="$(_kimchi_detect_ubuntu_root)/usr/local/bin/kimchi"
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import "@/utils/log"
|
|
4
4
|
import "@/utils/colors"
|
|
5
5
|
import "@/utils/version"
|
|
6
|
+
import "@/utils/install"
|
|
6
7
|
|
|
7
8
|
LOG_FILE="$KARNEL_CACHE/install_ai.log"
|
|
8
9
|
OMP_DATA_DIR="$HOME/.local/share/karnel-data/oh-my-pi"
|
|
@@ -85,8 +86,16 @@ _download_omp_binary_impl() {
|
|
|
85
86
|
log_error "Failed to download Oh-My-Pi binary"
|
|
86
87
|
return 1
|
|
87
88
|
fi
|
|
89
|
+
local expected
|
|
90
|
+
expected=$(github_release_asset_sha256 can1357/oh-my-pi "$latest_version" "omp-linux-arm64") || expected=""
|
|
91
|
+
if [[ "$expected" =~ ^[0-9a-f]{64}$ ]]; then
|
|
92
|
+
verify_sha256 "$target_dir/omp" "$expected" || return 1
|
|
93
|
+
else
|
|
94
|
+
log_warn "No published SHA-256 for Oh-My-Pi; skipping integrity verification"
|
|
95
|
+
fi
|
|
88
96
|
chmod +x "$target_dir/omp"
|
|
89
97
|
echo "$latest_version" > "$target_dir/version"
|
|
98
|
+
: > "$target_dir/.karnel-managed"
|
|
90
99
|
return 0
|
|
91
100
|
}
|
|
92
101
|
|
|
@@ -160,15 +169,21 @@ _install_omp_proot_impl() {
|
|
|
160
169
|
return 1
|
|
161
170
|
fi
|
|
162
171
|
local download_url="https://github.com/can1357/oh-my-pi/releases/download/$latest_version/omp-linux-arm64"
|
|
163
|
-
|
|
172
|
+
local expected
|
|
173
|
+
expected=$(github_release_asset_sha256 can1357/oh-my-pi "$latest_version" "omp-linux-arm64") || expected=""
|
|
174
|
+
if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
|
|
175
|
+
log_warn "No published SHA-256 for Oh-My-Pi; skipping integrity verification"
|
|
176
|
+
fi
|
|
177
|
+
if ! _omp_proot_ubuntu /bin/bash -c '
|
|
164
178
|
mkdir -p /tmp/omp-install &&
|
|
165
|
-
curl -fsSL
|
|
179
|
+
curl -fsSL "$1" -o /tmp/omp-install/omp &&
|
|
180
|
+
{ [ -z "$2" ] || [ "$(sha256sum /tmp/omp-install/omp | awk "{print \$1}")" = "$2" ]; } &&
|
|
166
181
|
chmod +x /tmp/omp-install/omp &&
|
|
167
182
|
test -x /tmp/omp-install/omp &&
|
|
168
183
|
mkdir -p /usr/local/bin &&
|
|
169
184
|
mv /tmp/omp-install/omp /usr/local/bin/omp &&
|
|
170
185
|
rm -rf /tmp/omp-install
|
|
171
|
-
" &>>"$LOG_FILE"; then
|
|
186
|
+
' bash "$download_url" "$expected" &>>"$LOG_FILE"; then
|
|
172
187
|
log_error "Failed to install Oh-My-Pi binary"
|
|
173
188
|
return 1
|
|
174
189
|
fi
|
|
@@ -209,6 +224,10 @@ install_oh_my_pi() {
|
|
|
209
224
|
}
|
|
210
225
|
|
|
211
226
|
_uninstall_omp_native_impl() {
|
|
227
|
+
if [[ ! -f "$OMP_DATA_DIR/.karnel-managed" ]]; then
|
|
228
|
+
log_error "Refusing to remove an Oh-My-Pi installation that is not managed by Karnel"
|
|
229
|
+
return 1
|
|
230
|
+
fi
|
|
212
231
|
rm -f "$PREFIX/bin/omp"
|
|
213
232
|
rm -rf "$OMP_DATA_DIR"
|
|
214
233
|
}
|
|
@@ -256,14 +275,20 @@ _update_omp_proot_impl() {
|
|
|
256
275
|
return 1
|
|
257
276
|
fi
|
|
258
277
|
local download_url="https://github.com/can1357/oh-my-pi/releases/download/$latest_version/omp-linux-arm64"
|
|
259
|
-
|
|
278
|
+
local expected
|
|
279
|
+
expected=$(github_release_asset_sha256 can1357/oh-my-pi "$latest_version" "omp-linux-arm64") || expected=""
|
|
280
|
+
if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
|
|
281
|
+
log_warn "No published SHA-256 for Oh-My-Pi; skipping integrity verification"
|
|
282
|
+
fi
|
|
283
|
+
if ! _omp_proot_ubuntu /bin/bash -c '
|
|
260
284
|
mkdir -p /tmp/omp-update &&
|
|
261
|
-
curl -fsSL
|
|
285
|
+
curl -fsSL "$1" -o /tmp/omp-update/omp &&
|
|
286
|
+
{ [ -z "$2" ] || [ "$(sha256sum /tmp/omp-update/omp | awk "{print \$1}")" = "$2" ]; } &&
|
|
262
287
|
chmod +x /tmp/omp-update/omp &&
|
|
263
288
|
test -x /tmp/omp-update/omp &&
|
|
264
289
|
mv /tmp/omp-update/omp /usr/local/bin/omp &&
|
|
265
290
|
rm -rf /tmp/omp-update
|
|
266
|
-
" &>>"$LOG_FILE"; then
|
|
291
|
+
' bash "$download_url" "$expected" &>>"$LOG_FILE"; then
|
|
267
292
|
log_error "Failed to update Oh-My-Pi binary"
|
|
268
293
|
return 1
|
|
269
294
|
fi
|
|
@@ -127,6 +127,13 @@ install_omni_route() {
|
|
|
127
127
|
fi
|
|
128
128
|
fi
|
|
129
129
|
|
|
130
|
+
if ! command -v npm &>/dev/null; then
|
|
131
|
+
if ! pkg install nodejs-lts -y &>>"$LOG_FILE"; then
|
|
132
|
+
log_error "Failed to install Node.js (required by omniRoute)"
|
|
133
|
+
return 1
|
|
134
|
+
fi
|
|
135
|
+
fi
|
|
136
|
+
|
|
130
137
|
log_info "Installing omniRoute (this may take a while)..."
|
|
131
138
|
if command -v npm >/dev/null 2>&1 && npm i karnelroute --prefix "$OMNI_ROUTE_PKG" 2>>"$LOG_FILE"; then
|
|
132
139
|
sed -i '1s|^#!/usr/bin/env node|#!'"$PREFIX"'/bin/node|' "$OMNI_ROUTE_LOCAL_BIN" 2>/dev/null
|
|
@@ -13,6 +13,13 @@ install_openspec() {
|
|
|
13
13
|
return 2
|
|
14
14
|
fi
|
|
15
15
|
|
|
16
|
+
if ! command -v npm &>/dev/null; then
|
|
17
|
+
if ! pkg install nodejs-lts -y &>>"$LOG_FILE"; then
|
|
18
|
+
log_error "Failed to install Node.js (required by openspec)"
|
|
19
|
+
return 1
|
|
20
|
+
fi
|
|
21
|
+
fi
|
|
22
|
+
|
|
16
23
|
log_info "Installing openspec (Spec-Driven Development framework)..."
|
|
17
24
|
npm install -g @fission-ai/openspec@latest 2>/dev/null
|
|
18
25
|
local rc=$?
|
|
@@ -12,6 +12,13 @@ install_puter() {
|
|
|
12
12
|
return 2
|
|
13
13
|
fi
|
|
14
14
|
|
|
15
|
+
if ! command -v npm &>/dev/null; then
|
|
16
|
+
if ! pkg install nodejs-lts -y &>>"$LOG_FILE"; then
|
|
17
|
+
log_error "Failed to install Node.js (required by Puter CLI)"
|
|
18
|
+
return 1
|
|
19
|
+
fi
|
|
20
|
+
fi
|
|
21
|
+
|
|
15
22
|
log_info "Installing Puter CLI..."
|
|
16
23
|
if ! npm install -g "$PUTER_PACKAGE" &>>"$PUTER_LOG_FILE"; then
|
|
17
24
|
log_error "Failed to install Puter CLI; see $PUTER_LOG_FILE"
|
|
@@ -8,6 +8,13 @@ install_supercode_cli() {
|
|
|
8
8
|
log_info "Supercode CLI is already installed"
|
|
9
9
|
return 2
|
|
10
10
|
fi
|
|
11
|
+
if ! command -v npm &>/dev/null; then
|
|
12
|
+
if ! pkg install nodejs-lts -y &>>"$LOG_FILE"; then
|
|
13
|
+
log_error "Failed to install Node.js (required by Supercode CLI)"
|
|
14
|
+
return 1
|
|
15
|
+
fi
|
|
16
|
+
fi
|
|
17
|
+
|
|
11
18
|
log_info "Installing Supercode CLI..."
|
|
12
19
|
local output rc
|
|
13
20
|
output="$(npm install -g supercode-cli 2>&1)"
|
|
@@ -50,7 +50,10 @@ _update_redis_impl() {
|
|
|
50
50
|
|
|
51
51
|
_do_redis_update() {
|
|
52
52
|
mkdir -p "$(dirname "$LOG_FILE")"
|
|
53
|
-
pkg upgrade redis -y &>>"$LOG_FILE"
|
|
53
|
+
if ! pkg upgrade redis -y &>>"$LOG_FILE"; then
|
|
54
|
+
log_error "Falha ao atualizar Redis"
|
|
55
|
+
return 1
|
|
56
|
+
fi
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
update_redis() {
|
|
@@ -15,6 +15,13 @@ install_netlify() {
|
|
|
15
15
|
if command -v netlify &>/dev/null && netlify --version &>/dev/null; then
|
|
16
16
|
log_info "Netlify CLI is already installed"
|
|
17
17
|
return 2
|
|
18
|
+
fi
|
|
19
|
+
if ! command -v node &>/dev/null || ! command -v npm &>/dev/null; then
|
|
20
|
+
log_info "Installing Node.js..."
|
|
21
|
+
if ! pkg install -y nodejs-lts &>>"$LOG_FILE"; then
|
|
22
|
+
log_error "Failed to install Node.js"
|
|
23
|
+
return 1
|
|
24
|
+
fi
|
|
18
25
|
fi
|
|
19
26
|
if ! _netlify_node_supported; then
|
|
20
27
|
log_error "Netlify CLI requires Node.js 22.13.0 or newer. Update Node.js and retry."
|
|
@@ -185,6 +185,15 @@ uninstall_railway() {
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
update_railway() {
|
|
188
|
+
if _railway_proot_wrapper_owned; then
|
|
189
|
+
log_info "Railway was installed via Ubuntu PRoot; updating inside the container..."
|
|
190
|
+
if proot-distro login ubuntu -- npm update -g @railway/cli &>>"$LOG_FILE"; then
|
|
191
|
+
log_success "Railway CLI updated through Ubuntu Proot"
|
|
192
|
+
return 0
|
|
193
|
+
fi
|
|
194
|
+
log_warn "Railway CLI update failed inside Ubuntu Proot"
|
|
195
|
+
return 1
|
|
196
|
+
fi
|
|
188
197
|
_check_update_needed "Railway CLI" "$(_get_installed_npm_version @railway/cli)" "$(_get_remote_npm_version @railway/cli)" _do_update_railway
|
|
189
198
|
}
|
|
190
199
|
|
|
@@ -10,6 +10,13 @@ install_vercel() {
|
|
|
10
10
|
log_info "Vercel CLI is already installed"
|
|
11
11
|
return 2
|
|
12
12
|
fi
|
|
13
|
+
if ! command -v node &>/dev/null || ! command -v npm &>/dev/null; then
|
|
14
|
+
log_info "Installing Node.js..."
|
|
15
|
+
if ! pkg install -y nodejs-lts &>>"$LOG_FILE"; then
|
|
16
|
+
log_error "Failed to install Node.js"
|
|
17
|
+
return 1
|
|
18
|
+
fi
|
|
19
|
+
fi
|
|
13
20
|
log_info "Installing Vercel CLI..."
|
|
14
21
|
npm install -g vercel &>/dev/null || {
|
|
15
22
|
log_error "Failed to install Vercel CLI"
|
|
@@ -62,7 +62,10 @@ _update_openssh_pkg() {
|
|
|
62
62
|
|
|
63
63
|
_do_openssh_update() {
|
|
64
64
|
mkdir -p "$(dirname "$LOG_FILE")"
|
|
65
|
-
yes | pkg upgrade openssh -y &>>"$LOG_FILE"
|
|
65
|
+
if ! yes | pkg upgrade openssh -y &>>"$LOG_FILE"; then
|
|
66
|
+
log_error "Falha ao atualizar OpenSSH"
|
|
67
|
+
return 1
|
|
68
|
+
fi
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
update_openssh() {
|
|
@@ -62,7 +62,10 @@ _update_tmux_pkg() {
|
|
|
62
62
|
|
|
63
63
|
_do_tmux_update() {
|
|
64
64
|
mkdir -p "$(dirname "$LOG_FILE")"
|
|
65
|
-
yes | pkg upgrade tmux -y &>>"$LOG_FILE"
|
|
65
|
+
if ! yes | pkg upgrade tmux -y &>>"$LOG_FILE"; then
|
|
66
|
+
log_error "Falha ao atualizar Tmux"
|
|
67
|
+
return 1
|
|
68
|
+
fi
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
update_tmux() {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import "@/utils/log"
|
|
4
4
|
import "@/utils/colors"
|
|
5
5
|
import "@/utils/version"
|
|
6
|
+
import "@/utils/install"
|
|
6
7
|
|
|
7
8
|
LOG_FILE="$KARNEL_CACHE/install_lang.log"
|
|
8
9
|
BUN_DATA_DIR="$KARNEL_DATA/bun"
|
|
@@ -268,16 +269,22 @@ _install_bun_proot_impl() {
|
|
|
268
269
|
_bun_proot_ubuntu /bin/bash -c \
|
|
269
270
|
'apt-get update && apt-get upgrade -y && apt-get install -y curl ca-certificates unzip' \
|
|
270
271
|
&>>"$LOG_FILE"
|
|
271
|
-
|
|
272
|
+
local expected
|
|
273
|
+
expected=$(github_release_asset_sha256 "$BUN_REPO" "bun-v$version" "bun-linux-aarch64.zip") || expected=""
|
|
274
|
+
if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
|
|
275
|
+
log_warn "No published SHA-256 for Bun; skipping integrity verification"
|
|
276
|
+
fi
|
|
277
|
+
_bun_proot_ubuntu /bin/bash -c '
|
|
272
278
|
export HOME=/root TMPDIR=/tmp
|
|
273
279
|
cd /tmp &&
|
|
274
|
-
curl -fsSL
|
|
280
|
+
curl -fsSL "$1" -o bun.zip &&
|
|
281
|
+
{ [ -z "$2" ] || [ "$(sha256sum bun.zip | awk "{print \$1}")" = "$2" ]; } &&
|
|
275
282
|
unzip -o bun.zip >/dev/null 2>&1 &&
|
|
276
283
|
mkdir -p /usr/local/bin &&
|
|
277
284
|
mv bun-linux-aarch64/bun /usr/local/bin/bun &&
|
|
278
285
|
chmod +x /usr/local/bin/bun &&
|
|
279
286
|
rm -rf bun.zip bun-linux-aarch64
|
|
280
|
-
" &>>"$LOG_FILE"
|
|
287
|
+
' bash "$download_url" "$expected" &>>"$LOG_FILE"
|
|
281
288
|
local ubuntu_root
|
|
282
289
|
ubuntu_root="$(_bun_detect_ubuntu_root)"
|
|
283
290
|
if [ -z "$ubuntu_root" ]; then
|
|
@@ -296,6 +303,7 @@ _install_bun_proot_impl() {
|
|
|
296
303
|
fi
|
|
297
304
|
sed "s|__UBUNTU_ROOTFS__|$ubuntu_root|g" "$wrapper_src" >"$PREFIX/bin/bun"
|
|
298
305
|
chmod +x "$PREFIX/bin/bun"
|
|
306
|
+
mkdir -p "$BUN_DATA_DIR" && : >"$BUN_DATA_DIR/.karnel-proot"
|
|
299
307
|
return 0
|
|
300
308
|
}
|
|
301
309
|
|
|
@@ -339,7 +347,12 @@ _uninstall_bun_impl() {
|
|
|
339
347
|
_uninstall_bun_native
|
|
340
348
|
return $?
|
|
341
349
|
fi
|
|
342
|
-
|
|
350
|
+
if [ -f "$BUN_DATA_DIR/.karnel-proot" ]; then
|
|
351
|
+
_uninstall_bun_proot
|
|
352
|
+
return $?
|
|
353
|
+
fi
|
|
354
|
+
log_error "Refusing to remove unowned bun command: $PREFIX/bin/bun"
|
|
355
|
+
return 1
|
|
343
356
|
}
|
|
344
357
|
|
|
345
358
|
uninstall_bun() {
|
|
@@ -368,16 +381,22 @@ _update_bun_proot() {
|
|
|
368
381
|
fi
|
|
369
382
|
local download_url="https://github.com/$BUN_REPO/releases/download/bun-v$version/bun-linux-aarch64.zip"
|
|
370
383
|
_bun_proot_ubuntu /bin/bash -c 'rm -f /usr/local/bin/bun' &>>"$LOG_FILE"
|
|
371
|
-
|
|
384
|
+
local expected
|
|
385
|
+
expected=$(github_release_asset_sha256 "$BUN_REPO" "bun-v$version" "bun-linux-aarch64.zip") || expected=""
|
|
386
|
+
if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
|
|
387
|
+
log_warn "No published SHA-256 for Bun; skipping integrity verification"
|
|
388
|
+
fi
|
|
389
|
+
_bun_proot_ubuntu /bin/bash -c '
|
|
372
390
|
export HOME=/root TMPDIR=/tmp
|
|
373
391
|
cd /tmp &&
|
|
374
|
-
curl -fsSL
|
|
392
|
+
curl -fsSL "$1" -o bun.zip &&
|
|
393
|
+
{ [ -z "$2" ] || [ "$(sha256sum bun.zip | awk "{print \$1}")" = "$2" ]; } &&
|
|
375
394
|
unzip -o bun.zip >/dev/null 2>&1 &&
|
|
376
395
|
mkdir -p /usr/local/bin &&
|
|
377
396
|
mv bun-linux-aarch64/bun /usr/local/bin/bun &&
|
|
378
397
|
chmod +x /usr/local/bin/bun &&
|
|
379
398
|
rm -rf bun.zip bun-linux-aarch64
|
|
380
|
-
" &>>"$LOG_FILE"
|
|
399
|
+
' bash "$download_url" "$expected" &>>"$LOG_FILE"
|
|
381
400
|
local ubuntu_root
|
|
382
401
|
ubuntu_root="$(_bun_detect_ubuntu_root)"
|
|
383
402
|
local bun_bin="$ubuntu_root/usr/local/bin/bun"
|
|
@@ -178,8 +178,8 @@ install_turbopack() {
|
|
|
178
178
|
|
|
179
179
|
uninstall_turbopack() {
|
|
180
180
|
if ! _has_glibc_node; then
|
|
181
|
-
|
|
182
|
-
return
|
|
181
|
+
log_info "Turbopack is not installed"
|
|
182
|
+
return 2
|
|
183
183
|
fi
|
|
184
184
|
|
|
185
185
|
loading "Removing CLI wrappers" _uninstall_wrappers
|
|
@@ -493,10 +493,14 @@ uninstall_robin() {
|
|
|
493
493
|
return 2
|
|
494
494
|
fi
|
|
495
495
|
|
|
496
|
+
if [[ ! -f "$ROBIN_ROOT/.managed-by-karnel" ]]; then
|
|
497
|
+
log_error "Robin at $ROBIN_ROOT is not managed by Karnel; refusing to remove it to avoid deleting unrelated data"
|
|
498
|
+
return 1
|
|
499
|
+
fi
|
|
500
|
+
|
|
496
501
|
_robin_acquire_lock || return 1
|
|
497
502
|
local rc=0
|
|
498
|
-
|
|
499
|
-
if (( rc == 0 )) && _robin_runtime_active; then
|
|
503
|
+
if _robin_runtime_active; then
|
|
500
504
|
log_error "Stop Robin before uninstalling it: karnel robin stop"
|
|
501
505
|
rc=1
|
|
502
506
|
fi
|
|
@@ -24,10 +24,17 @@ install_amass() (
|
|
|
24
24
|
log_info "Instalando amass..."
|
|
25
25
|
if [ ! -f "$_AMASS_MARKER" ] &&
|
|
26
26
|
{ pkg install -y amass 2>/dev/null || apt install -y amass 2>/dev/null; }; then
|
|
27
|
+
local bin; bin="$(command -v amass)"
|
|
28
|
+
[ -n "$bin" ] && sha256sum "$bin" > "$_AMASS_MARKER" 2>/dev/null
|
|
27
29
|
log_success "amass instalado"
|
|
28
30
|
return 0
|
|
29
31
|
fi
|
|
30
32
|
|
|
33
|
+
command -v unzip >/dev/null 2>&1 || pkg install -y unzip >/dev/null 2>&1 || {
|
|
34
|
+
log_error "unzip indisponível; não foi possível extrair amass"
|
|
35
|
+
return 1
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
local arch asset checksum url tmpdir archive amass_bin staged_bin
|
|
32
39
|
arch=$(_amass_arch) || { log_error "Arquitetura não suportada"; return 1; }
|
|
33
40
|
[[ "$arch" == armv7 ]] && arch="arm"
|
|
@@ -24,10 +24,17 @@ install_subfinder() (
|
|
|
24
24
|
log_info "Instalando subfinder..."
|
|
25
25
|
if [ ! -f "$_SUBFINDER_MARKER" ] &&
|
|
26
26
|
{ pkg install -y subfinder 2>/dev/null || apt install -y subfinder 2>/dev/null; }; then
|
|
27
|
+
local bin; bin="$(command -v subfinder)"
|
|
28
|
+
[ -n "$bin" ] && sha256sum "$bin" > "$_SUBFINDER_MARKER" 2>/dev/null
|
|
27
29
|
log_success "subfinder instalado"
|
|
28
30
|
return 0
|
|
29
31
|
fi
|
|
30
32
|
|
|
33
|
+
command -v unzip >/dev/null 2>&1 || pkg install -y unzip >/dev/null 2>&1 || {
|
|
34
|
+
log_error "unzip indisponível; não foi possível extrair subfinder"
|
|
35
|
+
return 1
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
local arch asset checksum url tmpdir archive staged_bin
|
|
32
39
|
arch=$(_subfinder_arch) || { log_error "Arquitetura não suportada"; return 1; }
|
|
33
40
|
[[ "$arch" == armv7 ]] && arch="arm"
|
package/karnel/utils/install.sh
CHANGED
|
@@ -269,8 +269,14 @@ managed_file_matches() {
|
|
|
269
269
|
|
|
270
270
|
github_download_and_extract() {
|
|
271
271
|
local repo="$1" version="$2" asset="$3" outdir="$4"
|
|
272
|
-
local tarball
|
|
272
|
+
local tarball expected
|
|
273
273
|
tarball=$(github_download_release "$repo" "$version" "$asset" "$outdir") || return 1
|
|
274
|
+
expected=$(github_release_asset_sha256 "$repo" "$version" "$asset") || expected=""
|
|
275
|
+
if [[ "$expected" =~ ^[0-9a-f]{64}$ ]]; then
|
|
276
|
+
verify_sha256 "$tarball" "$expected" || return 1
|
|
277
|
+
else
|
|
278
|
+
log_warn "No published SHA-256 digest for $repo/$asset; skipping integrity verification"
|
|
279
|
+
fi
|
|
274
280
|
extract_tarball "$tarball" "$outdir" || return 1
|
|
275
281
|
return 0
|
|
276
282
|
}
|
package/karnel/utils/tools.sh
CHANGED
|
@@ -106,6 +106,10 @@ _batch_tool_action() {
|
|
|
106
106
|
local failed_count=0
|
|
107
107
|
local skipped_count=0
|
|
108
108
|
|
|
109
|
+
# An explicit uninstall should actually remove owned data, even when no TTY
|
|
110
|
+
# is attached (piped/non-interactive). Ownership is still guarded upstream.
|
|
111
|
+
[[ "$action" == "uninstall" ]] && export KARNEL_REMOVE_DEFAULT=y
|
|
112
|
+
|
|
109
113
|
import "@/tools/$module/all"
|
|
110
114
|
|
|
111
115
|
for tool in "${tools[@]}"; do
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
confirm_remove_paths() {
|
|
4
4
|
local label="$1"
|
|
5
5
|
shift
|
|
6
|
+
local default="${KARNEL_REMOVE_DEFAULT:-n}"
|
|
6
7
|
local answer path
|
|
7
8
|
local -a existing=()
|
|
8
9
|
|
|
@@ -11,7 +12,7 @@ confirm_remove_paths() {
|
|
|
11
12
|
done
|
|
12
13
|
(( ${#existing[@]} > 0 )) || return 0
|
|
13
14
|
|
|
14
|
-
read_confirm_default "Remove $label configuration and data?" "
|
|
15
|
+
read_confirm_default "Remove $label configuration and data?" "$default" answer || return 2
|
|
15
16
|
[[ "$answer" == "y" ]] || return 2
|
|
16
17
|
|
|
17
18
|
rm -rf -- "${existing[@]}"
|
package/package.json
CHANGED