karnel-termux 4.17.7 → 4.17.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  <p align="center">
10
10
  <a href="https://github.com/israelmarques1024-dotcom/karnel-termux">
11
- <img src="https://img.shields.io/badge/version-4.17.7-0078D4?style=for-the-badge" alt="Version">
11
+ <img src="https://img.shields.io/badge/version-4.17.8-0078D4?style=for-the-badge" alt="Version">
12
12
  </a>
13
13
  <a href="https://www.npmjs.com/package/karnel-termux">
14
14
  <img src="https://img.shields.io/npm/v/karnel-termux?style=for-the-badge&logo=npm&color=cb3837" alt="npm">
@@ -61,7 +61,7 @@ Core agent contributions by **devcorex**.
61
61
  ### Via checksummed GitHub release (recommended)
62
62
 
63
63
  ```bash
64
- version=4.17.7
64
+ version=4.17.8
65
65
  tmpdir=$(mktemp -d) && trap 'rm -rf "$tmpdir"' EXIT
66
66
  base="https://github.com/israelmarques1024-dotcom/karnel-termux/releases/download/v$version"
67
67
  curl -fsSL "$base/karnel-termux-install.sh" -o "$tmpdir/karnel-termux-install.sh"
package/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Documentation Changelog
2
2
 
3
+ ## 4.17.7
4
+
5
+ - Documentation site overhauled: valid `_config.yml`, cayman-compatible custom
6
+ stylesheet that imports the full theme, a workflow that builds Jekyll before
7
+ deploying to GitHub Pages, and tool counts reconciled with the actual
8
+ `karnel/tools/*` and `karnel/tools/ai/*` directories (45 AI tools, 3 editors,
9
+ 8 languages, 5 databases, 22 dev tools, 11 npm packages, 10 shell plugins,
10
+ 4 UI components, 4 deploy CLIs, 6 games, 2 network tools, 12 utility tools,
11
+ 30 security tools, 1 automation tool).
12
+
3
13
  ## 4.16.1 - 2026-08-22
4
14
 
5
15
  - `karnel agent ask/run`: when the model endpoint is unreachable and Cactus is
package/docs/_config.yml CHANGED
@@ -2,11 +2,14 @@ title: Karnel Termux
2
2
  description: >-
3
3
  Modular Dev Environment for Termux — install languages, databases, AI agents,
4
4
  editors, and more with one command.
5
+ author: Israel Marques
6
+ lang: en-US
5
7
  theme: jekyll-theme-cayman
6
8
  markdown: kramdown
7
9
  logo: /assets/images/karnel-logo.png
8
10
  custom_css: /assets/css/style.css
9
11
  baseurl: /karnel-termux
12
+ show_downloads: false
10
13
  exclude:
11
14
  - vendor
12
15
  - Gemfile
@@ -1,3 +1,8 @@
1
+ ---
2
+ ---
3
+
4
+ @import "jekyll-theme-cayman";
5
+
1
6
  /* Karnel Termux — custom styling layered on top of jekyll-theme-cayman */
2
7
 
3
8
  :root {
@@ -21,6 +26,16 @@ body {
21
26
  color: #24292f;
22
27
  }
23
28
 
29
+ /* Logo (added in page content; cayman's default.html does not render site.logo) */
30
+ .karnel-logo {
31
+ display: block;
32
+ margin: 0 auto 1.25rem;
33
+ max-width: 220px;
34
+ height: auto;
35
+ border-radius: 14px;
36
+ box-shadow: 0 6px 22px rgba(0, 0, 0, 0.18);
37
+ }
38
+
24
39
  @media (prefers-color-scheme: dark) {
25
40
  body {
26
41
  background: var(--karnel-bg);
@@ -53,15 +68,6 @@ body {
53
68
  font-size: 1.1rem;
54
69
  }
55
70
 
56
- /* Logo */
57
- .karnel-logo {
58
- display: block;
59
- margin: 0 auto 1.25rem;
60
- max-width: 220px;
61
- height: auto;
62
- filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.35));
63
- }
64
-
65
71
  /* Landing navigation */
66
72
  .karnel-nav {
67
73
  display: flex;
@@ -149,6 +155,15 @@ body {
149
155
  font-size: 0.88em;
150
156
  }
151
157
 
158
+ /* Inline code should not be wrapped in its own block styling */
159
+ .main-content p code,
160
+ .main-content li code,
161
+ .main-content td code {
162
+ background: rgba(120, 120, 120, 0.12);
163
+ padding: 0.12em 0.4em;
164
+ border-radius: 4px;
165
+ }
166
+
152
167
  /* Blockquotes */
153
168
  .main-content blockquote {
154
169
  border-left: 4px solid var(--karnel-accent-2, #0078d4);
@@ -158,6 +173,16 @@ body {
158
173
  border-radius: 0 6px 6px 0;
159
174
  }
160
175
 
176
+ /* Admonition callouts */
177
+ .karnel-note {
178
+ border: 1px solid var(--karnel-accent-2, #0078d4);
179
+ border-left-width: 4px;
180
+ border-radius: 8px;
181
+ padding: 0.75rem 1rem;
182
+ margin: 1.25rem 0;
183
+ background: rgba(0, 120, 212, 0.06);
184
+ }
185
+
161
186
  /* Section spacing */
162
187
  .main-content h2 {
163
188
  margin-top: 2.5rem;
@@ -203,3 +228,10 @@ body {
203
228
  color: #e6edf3;
204
229
  }
205
230
  }
231
+
232
+ /* Footer credit spacing */
233
+ .site-footer {
234
+ margin-top: 2.5rem;
235
+ border-top: 1px solid #e1e4e8;
236
+ padding-top: 1rem;
237
+ }
package/docs/index.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Karnel Termux Documentation
2
2
 
3
+ <img class="karnel-logo" src="{{ '/assets/images/karnel-logo.png' | relative_url }}" alt="Karnel Termux">
4
+
3
5
  > Modular Dev Environment for Termux — install languages, databases, AI agents, editors, and more with one command
4
6
 
5
7
  Navigate the docs:
@@ -16,12 +18,13 @@ Navigate the docs:
16
18
  ## What is Karnel?
17
19
 
18
20
  Karnel Termux transforms your Android device into a complete development workstation.
19
- With a single CLI (`karnel`), you can install and manage 45 AI tools, 8 languages,
20
- 5 databases, 22 dev tools, 11 npm packages, 10 shell plugins, 4 UI components,
21
- 4 deploy CLIs, 6 games, 2 network tools, 12 utility tools, 30 security tools,
22
- responsible OSINT, a second brain, voice commands, and reviewed plugins — all
23
- from modules: `ai`, `auto`, `db`, `deploy`, `dev`, `editor`, `games`, `lang`,
24
- `network`, `npm`, `osint`, `security`, `shell`, `ui`, `utils`, `voice`, `plugin`.
21
+ With a single CLI (`karnel`), you can install and manage 45 AI tools, 3 editors,
22
+ 8 languages, 5 databases, 22 dev tools, 11 npm packages, 10 shell plugins,
23
+ 4 UI components, 4 deploy CLIs, 6 games, 2 network tools, 12 utility tools,
24
+ 30 security tools, 1 automation tool, responsible OSINT, a second brain,
25
+ voice commands, and reviewed plugins — all from modules: `ai`, `auto`, `db`,
26
+ `deploy`, `dev`, `editor`, `games`, `lang`, `network`, `npm`, `osint`,
27
+ `security`, `shell`, `ui`, `utils`, `voice`, `plugin`.
25
28
 
26
29
  ## Sections
27
30
 
@@ -1 +1 @@
1
- d1343c03d2f32967e36b7f78c8ef8cbb6656410e
1
+ ad787cd9d5efa67b498b0b1dc5e00203553b32e7
@@ -88,13 +88,16 @@ _antigravity_download_binary_impl() {
88
88
  fi
89
89
 
90
90
  if [[ "$manifest_sha256" =~ ^[0-9a-f]{64}$ ]]; then
91
- verify_sha256 "$tarball" "$manifest_sha256" || return 1
91
+ verify_sha256 "$tarball" "$manifest_sha256" || { rm -f "$tarball"; return 1; }
92
92
  else
93
- log_warn "Antigravity CLI manifest does not publish a SHA-256; skipping integrity verification"
93
+ log_error "Antigravity CLI manifest does not publish a SHA-256; refusing install"
94
+ rm -f "$tarball"
95
+ return 1
94
96
  fi
95
97
 
96
- if ! tar -xzf "$tarball" -C "$AGY_DATA_DIR" &>>"$LOG_FILE"; then
98
+ if ! safe_extract_tar "$tarball" "$AGY_DATA_DIR"; then
97
99
  log_error "Failed to extract Antigravity CLI binary"
100
+ rm -f "$tarball"
98
101
  return 1
99
102
  fi
100
103
 
@@ -4,7 +4,7 @@ import "@/utils/log"
4
4
  import "@/utils/install"
5
5
  import "@/utils/version"
6
6
 
7
- LOG_FILE="$KARNEL_CACHE/install_deploy.log"
7
+ LOG_FILE="${KARNEL_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/karnel}/install_deploy.log"
8
8
  RAILWAY_DATA_DIR="${KARNEL_DATA:-${XDG_DATA_HOME:-$HOME/.local/share}/karnel-data}/deploy/railway"
9
9
  _RAILWAY_MARKER="$PREFIX/share/karnel-installers/railway"
10
10
  _RAILWAY_DATA_MARKER="$RAILWAY_DATA_DIR/.karnel-managed"
@@ -113,14 +113,17 @@ _install_railway_manual_impl() {
113
113
 
114
114
  local expected
115
115
  expected=$(github_release_asset_sha256 railwayapp/cli "$latest_version" "railway-${version}-aarch64-linux.tar.gz") || expected=""
116
- if [[ "$expected" =~ ^[0-9a-f]{64}$ ]]; then
117
- verify_sha256 "$RAILWAY_DATA_DIR/railway.tar.gz" "$expected" || {
118
- rm -f "$RAILWAY_DATA_DIR/railway.tar.gz"
119
- return 1
120
- }
116
+ if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
117
+ log_error "No published SHA-256 for Railway CLI; refusing install"
118
+ rm -f "$RAILWAY_DATA_DIR/railway.tar.gz"
119
+ return 1
121
120
  fi
121
+ verify_sha256 "$RAILWAY_DATA_DIR/railway.tar.gz" "$expected" || {
122
+ rm -f "$RAILWAY_DATA_DIR/railway.tar.gz"
123
+ return 1
124
+ }
122
125
 
123
- tar -zxf "$RAILWAY_DATA_DIR/railway.tar.gz" -C "$RAILWAY_DATA_DIR" 2>>"$LOG_FILE" || {
126
+ safe_extract_tar "$RAILWAY_DATA_DIR/railway.tar.gz" "$RAILWAY_DATA_DIR" || {
124
127
  rm -f "$RAILWAY_DATA_DIR/railway.tar.gz"
125
128
  return 1
126
129
  }
@@ -43,7 +43,9 @@ install_supabase() (
43
43
  local url="${_SUPABASE_RELEASE_URL}/${filename}"
44
44
  local checksum_url="${_SUPABASE_RELEASE_URL}/supabase_${_SUPABASE_VERSION}_checksums.txt"
45
45
  local tmp_dir staged_bin marker_staging="" old_bin="" old_marker=""
46
- tmp_dir=$(mktemp -d "${TMPDIR:-/tmp}/supabase.XXXXXX") || return 1
46
+ local _kdir="${KARNEL_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/karnel}"
47
+ mkdir -p "$_kdir" 2>/dev/null || _kdir="${TMPDIR:-/tmp}"
48
+ tmp_dir=$(mktemp -d "$_kdir/supabase.XXXXXX") || return 1
47
49
  staged_bin=""
48
50
  trap 'rm -rf "$tmp_dir"; [[ -z "$staged_bin" ]] || rm -f "$staged_bin"; [[ -z "$marker_staging" ]] || rm -f "$marker_staging"' EXIT
49
51
 
@@ -143,16 +143,24 @@ _download_bun_binary_native_impl() {
143
143
  }
144
144
  if declare -F github_release_asset_sha256 >/dev/null; then
145
145
  expected=$(github_release_asset_sha256 "$BUN_REPO" "bun-v$version" "$zip_name") || expected=""
146
- if [[ "$expected" =~ ^[0-9a-f]{64}$ ]]; then
147
- verify_sha256 "$staging_dir/$zip_name" "$expected" || { rm -rf "$staging_dir"; return 1; }
148
- else
149
- log_warn "No published SHA-256 for Bun native; skipping integrity verification"
146
+ if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
147
+ rm -rf "$staging_dir"
148
+ log_error "No published SHA-256 for Bun native; refusing install"
149
+ return 1
150
+ fi
151
+ verify_sha256 "$staging_dir/$zip_name" "$expected" || { rm -rf "$staging_dir"; return 1; }
152
+ if ! safe_extract_zip "$staging_dir/$zip_name" "$staging_dir"; then
153
+ rm -rf "$staging_dir"
154
+ log_error "Failed to extract Bun binary"
155
+ return 1
156
+ fi
157
+ else
158
+ command -v log_warn >/dev/null 2>&1 && log_warn "Integrity helpers unavailable; skipping Bun integrity verification"
159
+ if ! unzip -o "$staging_dir/$zip_name" -d "$staging_dir" &>>"$LOG_FILE"; then
160
+ rm -rf "$staging_dir"
161
+ log_error "Failed to extract Bun binary"
162
+ return 1
150
163
  fi
151
- fi
152
- if ! unzip -o "$staging_dir/$zip_name" -d "$staging_dir" &>>"$LOG_FILE"; then
153
- rm -rf "$staging_dir"
154
- log_error "Failed to extract Bun binary"
155
- return 1
156
164
  fi
157
165
  rm -f "$staging_dir/$zip_name"
158
166
  extracted="$staging_dir/bun-linux-aarch64/bun"
@@ -280,13 +288,14 @@ _install_bun_proot_impl() {
280
288
  local expected
281
289
  expected=$(github_release_asset_sha256 "$BUN_REPO" "bun-v$version" "bun-linux-aarch64.zip") || expected=""
282
290
  if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
283
- log_warn "No published SHA-256 for Bun; skipping integrity verification"
291
+ log_error "No published SHA-256 for Bun; refusing install"
292
+ return 1
284
293
  fi
285
294
  _bun_proot_ubuntu /bin/bash -c '
286
295
  export HOME=/root TMPDIR=/tmp
287
296
  cd /tmp &&
288
297
  curl -fsSL "$1" -o bun.zip &&
289
- { [ -z "$2" ] || [ "$(sha256sum bun.zip | awk "{print \$1}")" = "$2" ]; } &&
298
+ [ "$(sha256sum bun.zip | awk "{print \$1}")" = "$2" ] &&
290
299
  unzip -o bun.zip >/dev/null 2>&1 &&
291
300
  mkdir -p /usr/local/bin &&
292
301
  mv bun-linux-aarch64/bun /usr/local/bin/bun &&
@@ -392,13 +401,14 @@ _update_bun_proot() {
392
401
  local expected
393
402
  expected=$(github_release_asset_sha256 "$BUN_REPO" "bun-v$version" "bun-linux-aarch64.zip") || expected=""
394
403
  if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
395
- log_warn "No published SHA-256 for Bun; skipping integrity verification"
404
+ log_error "No published SHA-256 for Bun; refusing update"
405
+ return 1
396
406
  fi
397
407
  _bun_proot_ubuntu /bin/bash -c '
398
408
  export HOME=/root TMPDIR=/tmp
399
409
  cd /tmp &&
400
410
  curl -fsSL "$1" -o bun.zip &&
401
- { [ -z "$2" ] || [ "$(sha256sum bun.zip | awk "{print \$1}")" = "$2" ]; } &&
411
+ [ "$(sha256sum bun.zip | awk "{print \$1}")" = "$2" ] &&
402
412
  unzip -o bun.zip >/dev/null 2>&1 &&
403
413
  mkdir -p /usr/local/bin &&
404
414
  mv bun-linux-aarch64/bun /usr/local/bin/bun &&
@@ -2,6 +2,7 @@
2
2
 
3
3
  import "@/utils/log"
4
4
  import "@/utils/version"
5
+ import "@/utils/install"
5
6
 
6
7
  LOG_FILE="$KARNEL_CACHE/install_zork.log"
7
8
  ZORK_DATA_DIR="${KARNEL_DATA:-${XDG_DATA_HOME:-$HOME/.local/share}/karnel-data}/zork"
@@ -62,7 +63,10 @@ _download_zork_data_impl() {
62
63
  return 1
63
64
  fi
64
65
 
65
- if ! unzip -o "$zip_file" -d "$staging_dir" 2>>"$LOG_FILE"; then
66
+ if declare -F safe_extract_zip >/dev/null; then
67
+ safe_extract_zip "$zip_file" "$staging_dir" 2>>"$LOG_FILE" || {
68
+ rm -rf "$staging_dir"; log_error "Failed to extract Zork ${num}"; return 1; }
69
+ elif ! unzip -o "$zip_file" -d "$staging_dir" 2>>"$LOG_FILE"; then
66
70
  rm -rf "$staging_dir"
67
71
  log_error "Failed to extract Zork ${num}"
68
72
  return 1
@@ -889,7 +889,9 @@ agent_exec_loading() {
889
889
  local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
890
890
  local delay=0.08
891
891
  local tmpfile
892
- tmpfile="$(mktemp)"
892
+ local _ktmpdir="${KARNEL_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/karnel}"
893
+ mkdir -p "$_ktmpdir" 2>/dev/null || _ktmpdir="${TMPDIR:-/tmp}"
894
+ tmpfile="$(mktemp "$_ktmpdir/karnel.XXXXXX" 2>/dev/null)" || tmpfile="$(mktemp 2>/dev/null)"
893
895
 
894
896
  local stty_saved=""
895
897
  if [[ -t 0 ]]; then
@@ -244,7 +244,20 @@ agent_chat_completion() {
244
244
  # characters. Real UTF-8 text passes through untouched.
245
245
  # ------------------------------------------------------------
246
246
  _agent_unescape_unicode() {
247
- perl -CS -pe 's/\\u([0-9a-fA-F]{4})/chr(hex($1))/ge' 2>/dev/null
247
+ if command -v perl >/dev/null 2>&1; then
248
+ perl -CS -pe 's/\\u([0-9a-fA-F]{4})/chr(hex($1))/ge'
249
+ elif command -v python3 >/dev/null 2>&1; then
250
+ python3 -c 'import sys,re;sys.stdout.write(re.sub(r"\\u([0-9a-fA-F]{4})",lambda m:chr(int(m.group(1),16)),sys.stdin.read()))'
251
+ else
252
+ awk '{
253
+ while (match($0, /\\u[0-9a-fA-F]{4}/)) {
254
+ h = substr($0, RSTART + 2, 4)
255
+ c = sprintf("%c", strtonum("0x" h))
256
+ $0 = substr($0, 1, RSTART - 1) c substr($0, RSTART + 6)
257
+ }
258
+ print
259
+ }'
260
+ fi
248
261
  }
249
262
 
250
263
  # ------------------------------------------------------------
@@ -211,9 +211,11 @@ github_release_asset_sha256() {
211
211
  return 0
212
212
  fi
213
213
  # Fallback: a checksums.txt / SHA256SUMS asset listing every released file.
214
+ # Match the filename field exactly (it is the LAST field) so a substring or
215
+ # regex-metacharacter in $asset cannot select the wrong line's digest.
214
216
  digest=$(curl -fsSL --connect-timeout 10 --max-time 30 \
215
217
  "https://github.com/$repo/releases/download/$version/checksums.txt" 2>/dev/null \
216
- | awk -v a="$asset" '$0 ~ a {print $1; exit}' | tr -d '\r')
218
+ | awk -v a="$asset" '{ f=$NF; if (f == a) { sub(/^\*/, "", $1); print $1; exit } }' | tr -d '\r')
217
219
  if [[ "$digest" =~ ^[0-9a-f]{64}$ ]]; then
218
220
  echo "$digest"
219
221
  return 0
@@ -248,20 +250,26 @@ extract_tarball() {
248
250
 
249
251
  replace_managed_directory() {
250
252
  local staging="$1" destination="$2" marker="$3"
251
- local backup="${destination}.previous.$$"
253
+ local backup_dir backup_target=""
252
254
  if [[ -e "$destination" && ! -f "$destination/$marker" ]]; then
253
255
  log_error "Refusing to replace unowned installation: $destination"
254
256
  return 1
255
257
  fi
256
258
  printf '%s\n' 'karnel-managed-v1' >"$staging/$marker" || return 1
257
- if [[ -e "$destination" ]] && ! mv "$destination" "$backup"; then
258
- return 1
259
+ backup_dir="$(mktemp -d "$(dirname "$destination")/.karnel-managed.XXXXXX")" || return 1
260
+ if [[ -e "$destination" ]]; then
261
+ backup_target="$backup_dir/$(basename "$destination")"
262
+ if ! mv "$destination" "$backup_target"; then
263
+ rm -rf "$backup_dir"
264
+ return 1
265
+ fi
259
266
  fi
260
267
  if ! mv "$staging" "$destination"; then
261
- [[ ! -e "$backup" ]] || mv "$backup" "$destination"
268
+ [[ -n "$backup_target" ]] && mv "$backup_target" "$destination" 2>/dev/null
269
+ rm -rf "$backup_dir"
262
270
  return 1
263
271
  fi
264
- rm -rf "$backup"
272
+ rm -rf "$backup_dir"
265
273
  }
266
274
 
267
275
  record_managed_file() {
@@ -283,7 +291,9 @@ github_download_and_extract() {
283
291
  if [[ "$expected" =~ ^[0-9a-f]{64}$ ]]; then
284
292
  verify_sha256 "$tarball" "$expected" || return 1
285
293
  else
286
- log_warn "No published SHA-256 digest for $repo/$asset; skipping integrity verification"
294
+ log_error "No verifiable SHA-256 digest published for $repo/$asset; refusing install"
295
+ rm -f "$tarball"
296
+ return 1
287
297
  fi
288
298
  extract_tarball "$tarball" "$outdir" || return 1
289
299
  return 0
@@ -429,7 +429,9 @@ loading() {
429
429
  local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
430
430
  local delay=0.08
431
431
  local tmpfile
432
- tmpfile="$(mktemp "${TMPDIR:-/tmp}/karnel.XXXXXX")"
432
+ local _ktmpdir="${KARNEL_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/karnel}"
433
+ mkdir -p "$_ktmpdir" 2>/dev/null || _ktmpdir="${TMPDIR:-/tmp}"
434
+ tmpfile="$(mktemp "$_ktmpdir/karnel.XXXXXX" 2>/dev/null)" || tmpfile="$(mktemp 2>/dev/null)"
433
435
  local cmd_pid=""
434
436
 
435
437
  trap 'kill "$cmd_pid" 2>/dev/null; rm -f "$tmpfile"; return 1' INT TERM
@@ -51,7 +51,9 @@ _spin_capture() {
51
51
  shift
52
52
  local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
53
53
  local tmp
54
- tmp=$(mktemp)
54
+ local _ktmpdir="${KARNEL_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/karnel}"
55
+ mkdir -p "$_ktmpdir" 2>/dev/null || _ktmpdir="${TMPDIR:-/tmp}"
56
+ tmp=$(mktemp "$_ktmpdir/karnel.XXXXXX" 2>/dev/null) || tmp=$(mktemp 2>/dev/null)
55
57
  local spinner_fd
56
58
  if [ -c /dev/tty ] 2>/dev/null; then
57
59
  spinner_fd=/dev/tty
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karnel-termux",
3
- "version": "4.17.7",
3
+ "version": "4.17.8",
4
4
  "description": "Modular Dev Environment for Termux — install languages, databases, AI agents, editors, and more with one command",
5
5
  "bin": {
6
6
  "karnel": "karnel/bin/karnel"