karnel-termux 4.7.6 → 4.7.7
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 +230 -225
- package/install.sh +30 -9
- package/karnel/bin/karnel +2 -2
- package/karnel/cli/commands/backup.sh +10 -2
- package/karnel/cli/commands/brain.sh +28 -23
- package/karnel/cli/commands/cleanup.sh +10 -4
- package/karnel/cli/commands/deploy.sh +53 -0
- package/karnel/cli/commands/doctor/code.sh +225 -0
- package/karnel/cli/commands/doctor/code_detect.sh +184 -0
- package/karnel/cli/commands/doctor/code_exec.sh +278 -0
- package/karnel/cli/commands/doctor/code_langs.sh +229 -0
- package/karnel/cli/commands/doctor/fixes.sh +63 -46
- package/karnel/cli/commands/doctor.sh +222 -80
- package/karnel/cli/commands/env.sh +2 -0
- package/karnel/cli/commands/ia.sh +12 -2
- package/karnel/cli/commands/init.sh +17 -9
- package/karnel/cli/commands/install.sh +90 -54
- package/karnel/cli/commands/list.sh +36 -0
- package/karnel/cli/commands/pg.sh +21 -6
- package/karnel/cli/commands/reinstall.sh +99 -0
- package/karnel/cli/commands/restore.sh +43 -3
- package/karnel/cli/commands/search.sh +2 -2
- package/karnel/cli/commands/update.sh +6 -1
- package/karnel/cli/commands/upgrade.sh +8 -1
- package/karnel/cli/commands/voice.sh +2 -1
- package/karnel/cli/karnel.sh +11 -5
- package/karnel/modules/games.sh +11 -0
- package/karnel/tools/ai/all.sh +1 -0
- package/karnel/tools/ai/copilot-termux/README.md +40 -0
- package/karnel/tools/ai/copilot-termux/install.sh +80 -0
- package/karnel/tools/ai/copilot-termux/package.json +20 -0
- package/karnel/tools/db/all.sh +2 -0
- package/karnel/tools/deploy/railway/install.sh +2 -2
- package/karnel/tools/dev/all.sh +8 -0
- package/karnel/tools/dev/applaunch/__pycache__/applaunch.cpython-314.pyc +0 -0
- package/karnel/tools/dev/applaunch/applaunch.py +434 -0
- package/karnel/tools/dev/applaunch/install.sh +51 -0
- package/karnel/tools/dev/fconv/__pycache__/fconv.cpython-314.pyc +0 -0
- package/karnel/tools/dev/fconv/fconv.py +749 -0
- package/karnel/tools/dev/fconv/install.sh +51 -0
- package/karnel/tools/dev/filecheck/__pycache__/filecheck.cpython-314.pyc +0 -0
- package/karnel/tools/dev/filecheck/filecheck.py +429 -0
- package/karnel/tools/dev/filecheck/install.sh +51 -0
- package/karnel/tools/dev/notes/__pycache__/notes.cpython-314.pyc +0 -0
- package/karnel/tools/dev/notes/install.sh +51 -0
- package/karnel/tools/dev/notes/notes.py +849 -0
- package/karnel/tools/dev/passman/__pycache__/passman.cpython-314.pyc +0 -0
- package/karnel/tools/dev/passman/install.sh +51 -0
- package/karnel/tools/dev/passman/passman.py +536 -0
- package/karnel/tools/dev/splash/__pycache__/splash.cpython-314.pyc +0 -0
- package/karnel/tools/dev/splash/install.sh +51 -0
- package/karnel/tools/dev/splash/splash.py +188 -0
- package/karnel/tools/dev/treex/install.sh +51 -0
- package/karnel/tools/dev/treex/treex.py +2036 -0
- package/karnel/tools/dev/websites/__pycache__/websites.cpython-314.pyc +0 -0
- package/karnel/tools/dev/websites/install.sh +51 -0
- package/karnel/tools/dev/websites/websites.py +844 -0
- package/karnel/tools/games/all.sh +62 -0
- package/karnel/tools/games/arcade/__pycache__/arcade.cpython-314.pyc +0 -0
- package/karnel/tools/games/arcade/arcade.py +193 -0
- package/karnel/tools/games/arcade/install.sh +51 -0
- package/karnel/tools/games/buzz/__pycache__/buzz.cpython-314.pyc +0 -0
- package/karnel/tools/games/buzz/buzz.py +1264 -0
- package/karnel/tools/games/buzz/install.sh +51 -0
- package/karnel/tools/games/ctfgod/__pycache__/ctfgod.cpython-314.pyc +0 -0
- package/karnel/tools/games/ctfgod/ctfgod.py +1576 -0
- package/karnel/tools/games/ctfgod/install.sh +51 -0
- package/karnel/tools/games/detective/__pycache__/detective.cpython-314.pyc +0 -0
- package/karnel/tools/games/detective/detective.py +2091 -0
- package/karnel/tools/games/detective/install.sh +51 -0
- package/karnel/tools/games/pet-friends/__pycache__/pet-friends.cpython-314.pyc +0 -0
- package/karnel/tools/games/pet-friends/install.sh +51 -0
- package/karnel/tools/games/pet-friends/pet-friends.py +15802 -0
- package/karnel/tools/games/tamagotchi/__pycache__/tamagotchi.cpython-314.pyc +0 -0
- package/karnel/tools/games/tamagotchi/install.sh +51 -0
- package/karnel/tools/games/tamagotchi/tamagotchi.py +1224 -0
- package/karnel/tools/games/terminal-arcade/__pycache__/terminal-arcade.cpython-314.pyc +0 -0
- package/karnel/tools/games/terminal-arcade/terminal-arcade.py +193 -0
- package/karnel/tools/npm/all.sh +1 -0
- package/karnel/utils/log.sh +34 -12
- package/package.json +1 -1
|
@@ -4,18 +4,80 @@ import "@/utils/log"
|
|
|
4
4
|
import "@/utils/colors"
|
|
5
5
|
|
|
6
6
|
doctor_main() {
|
|
7
|
+
local subcommand="${1:-termux}"
|
|
8
|
+
case "$subcommand" in
|
|
9
|
+
help|--help|-h)
|
|
10
|
+
doctor_help
|
|
11
|
+
;;
|
|
12
|
+
termux)
|
|
13
|
+
shift
|
|
14
|
+
doctor_termux "$@"
|
|
15
|
+
;;
|
|
16
|
+
code)
|
|
17
|
+
shift
|
|
18
|
+
doctor_code "$@"
|
|
19
|
+
;;
|
|
20
|
+
--quick|-q)
|
|
21
|
+
log_warn "Deprecated: use ${D_CYAN}karnel doctor termux --quick${NC}"
|
|
22
|
+
doctor_termux "$@"
|
|
23
|
+
;;
|
|
24
|
+
--fix|-f)
|
|
25
|
+
log_warn "Deprecated: use ${D_CYAN}karnel doctor termux --fix${NC}"
|
|
26
|
+
shift
|
|
27
|
+
doctor_termux "--fix" "$@"
|
|
28
|
+
;;
|
|
29
|
+
*)
|
|
30
|
+
log_error "Unknown doctor subcommand: $subcommand"
|
|
31
|
+
echo
|
|
32
|
+
doctor_help
|
|
33
|
+
return 1
|
|
34
|
+
;;
|
|
35
|
+
esac
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
doctor_help() {
|
|
39
|
+
echo
|
|
40
|
+
box "◈ KARNEL DOCTOR ◈"
|
|
41
|
+
echo
|
|
42
|
+
log_info "Usage: karnel doctor <subcommand> [options]"
|
|
43
|
+
echo
|
|
44
|
+
log_info "When no subcommand is given, runs termux diagnostics."
|
|
45
|
+
echo
|
|
46
|
+
separator_section "Subcommands"
|
|
47
|
+
echo
|
|
48
|
+
printf " ${D_CYAN}%-16s${NC} %s\n" "termux" "Diagnose Termux environment (full system check)"
|
|
49
|
+
printf " ${D_CYAN}%-16s${NC} %s\n" "code" "Analyze project code structure and tools"
|
|
50
|
+
echo
|
|
51
|
+
separator_section "Termux Options"
|
|
52
|
+
echo
|
|
53
|
+
printf " ${D_CYAN}%-16s${NC} %s\n" "--quick, -q" "Skip slow checks"
|
|
54
|
+
printf " ${D_CYAN}%-16s${NC} %s\n" "--fix, -f" "Auto-apply all fixes without prompt"
|
|
55
|
+
echo
|
|
56
|
+
log_info "Examples:"
|
|
57
|
+
list_item "${D_CYAN}karnel doctor${NC} — Termux diagnostics (default)"
|
|
58
|
+
list_item "${D_CYAN}karnel doctor termux --quick${NC} — Quick diagnostics"
|
|
59
|
+
list_item "${D_CYAN}karnel doctor code${NC} — Analyze current project"
|
|
60
|
+
list_item "${D_CYAN}karnel doctor termux --fix${NC} — Diagnose + auto-fix"
|
|
61
|
+
echo
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
doctor_termux() {
|
|
7
65
|
local QUICK_MODE=false
|
|
8
66
|
local FIX_MODE=false
|
|
9
67
|
for arg in "$@"; do
|
|
10
|
-
|
|
11
|
-
|
|
68
|
+
case "$arg" in
|
|
69
|
+
--quick|-q) QUICK_MODE=true ;;
|
|
70
|
+
--fix|-f) FIX_MODE=true ;;
|
|
71
|
+
--help|-h) doctor_help; return ;;
|
|
72
|
+
--*) log_error "Unknown option: $arg"; doctor_help; return 1 ;;
|
|
73
|
+
esac
|
|
12
74
|
done
|
|
13
75
|
|
|
14
76
|
echo
|
|
15
|
-
box "◈ KARNEL DOCTOR ◈"
|
|
77
|
+
box "◈ KARNEL DOCTOR — TERMUX ◈"
|
|
16
78
|
echo
|
|
17
79
|
if $QUICK_MODE; then
|
|
18
|
-
log_info "Quick mode —
|
|
80
|
+
log_info "Quick mode — running essential system and package checks only"
|
|
19
81
|
fi
|
|
20
82
|
log_info "Diagnosing your Termux and Karnel environment..."
|
|
21
83
|
echo
|
|
@@ -35,14 +97,13 @@ doctor_main() {
|
|
|
35
97
|
android_ver=$(getprop ro.build.version.release 2>/dev/null)
|
|
36
98
|
android_ver="${android_ver:-Unknown}"
|
|
37
99
|
|
|
38
|
-
local termux_ver=""
|
|
39
|
-
if command -v termux-info &>/dev/null; then
|
|
40
|
-
termux_ver=$(timeout 5 termux-info 2>/dev/null | grep -i "termux_version" | head -n1 | cut -d'=' -f2)
|
|
100
|
+
local termux_ver="${TERMUX_VERSION:-}"
|
|
101
|
+
if [[ -z "$termux_ver" ]] && command -v termux-info &>/dev/null; then
|
|
102
|
+
termux_ver=$(timeout 5 termux-info 2>/dev/null | grep -i "termux_version" | head -n1 | cut -d'=' -f2 || true)
|
|
41
103
|
fi
|
|
42
104
|
if [[ -z "$termux_ver" ]]; then
|
|
43
|
-
termux_ver=$(dpkg -s termux-tools 2>/dev/null | grep -i version | awk '{print $2}')
|
|
105
|
+
termux_ver=$(dpkg -s termux-tools 2>/dev/null | grep -i version | awk '{print $2}' 2>/dev/null || echo "Unknown")
|
|
44
106
|
fi
|
|
45
|
-
termux_ver="${termux_ver:-Unknown}"
|
|
46
107
|
|
|
47
108
|
log_success "Android Version: $android_ver"
|
|
48
109
|
log_success "Termux Version: $termux_ver"
|
|
@@ -127,7 +188,7 @@ doctor_main() {
|
|
|
127
188
|
case "$dep" in
|
|
128
189
|
git) version=$(git --version | awk '{print $3}') ;;
|
|
129
190
|
node) version=$(node --version) ;;
|
|
130
|
-
python) version=$(python3 --version 2>/dev/null || python --version 2>/dev/null | awk '{print $2}') ;;
|
|
191
|
+
python) version=$( (python3 --version 2>/dev/null || python --version 2>/dev/null) | awk '{print $2}' ) ;;
|
|
131
192
|
rustc) version=$(rustc --version | awk '{print $2}') ;;
|
|
132
193
|
go) version=$(go version | awk '{print $3}') ;;
|
|
133
194
|
clang) version=$(clang --version | head -1 | awk '{print $3}') ;;
|
|
@@ -153,7 +214,10 @@ doctor_main() {
|
|
|
153
214
|
separator_section "Package Manager & System Health"
|
|
154
215
|
echo
|
|
155
216
|
|
|
156
|
-
|
|
217
|
+
local dpkg_audit_out
|
|
218
|
+
dpkg_audit_out=$(dpkg --audit 2>&1)
|
|
219
|
+
local dpkg_rc=$?
|
|
220
|
+
if [[ $dpkg_rc -eq 0 ]] && [[ -z "$dpkg_audit_out" ]]; then
|
|
157
221
|
log_success "dpkg package manager is healthy"
|
|
158
222
|
else
|
|
159
223
|
log_error "dpkg has interrupted installations!"
|
|
@@ -186,9 +250,55 @@ doctor_main() {
|
|
|
186
250
|
fi
|
|
187
251
|
fi
|
|
188
252
|
|
|
253
|
+
# Keyring integrity check (Termux-fixer inspired)
|
|
254
|
+
local keyring_dir="$PREFIX/etc/apt/trusted.gpg.d"
|
|
255
|
+
if [[ -d "$keyring_dir" ]]; then
|
|
256
|
+
local key_count
|
|
257
|
+
key_count=$(find "$keyring_dir" -maxdepth 1 -type f \( -name '*.gpg' -o -name '*.asc' \) -print 2>/dev/null | wc -l)
|
|
258
|
+
if (( key_count == 0 )); then
|
|
259
|
+
log_warn "No APT keyring files found in $keyring_dir"
|
|
260
|
+
((warnings++))
|
|
261
|
+
fix_commands+=("pkg update -y && pkg install -y termux-keyring")
|
|
262
|
+
fix_descriptions+=("Reinstall termux-keyring")
|
|
263
|
+
fix_callbacks+=("_fix_keyring")
|
|
264
|
+
else
|
|
265
|
+
log_success "APT keyring: $key_count key file(s) present"
|
|
266
|
+
fi
|
|
267
|
+
fi
|
|
268
|
+
|
|
269
|
+
# System clock sanity check (HTTPS cert validation)
|
|
270
|
+
if command -v date &>/dev/null; then
|
|
271
|
+
local current_year
|
|
272
|
+
current_year=$(date +%Y 2>/dev/null)
|
|
273
|
+
if (( current_year < 2024 )); then
|
|
274
|
+
log_error "System clock is incorrect (year: $current_year) — HTTPS/TLS certs will fail!"
|
|
275
|
+
((errors++))
|
|
276
|
+
else
|
|
277
|
+
log_success "System clock: $current_year"
|
|
278
|
+
fi
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
# APT cache health check
|
|
282
|
+
local apt_cache_dir="$PREFIX/var/apt/lists"
|
|
283
|
+
if [[ -d "$apt_cache_dir" ]]; then
|
|
284
|
+
local cache_size
|
|
285
|
+
cache_size=$(du -sh "$apt_cache_dir" 2>/dev/null | awk '{print $1}')
|
|
286
|
+
local cache_files
|
|
287
|
+
cache_files=$(find "$apt_cache_dir" -type f 2>/dev/null | wc -l)
|
|
288
|
+
if (( cache_files > 500 )); then
|
|
289
|
+
log_warn "APT lists cache is large: $cache_size ($cache_files files)"
|
|
290
|
+
((warnings++))
|
|
291
|
+
fix_commands+=("rm -rf $apt_cache_dir/* && pkg update -y")
|
|
292
|
+
fix_descriptions+=("Reset APT lists cache (fixes Hash Sum mismatch)")
|
|
293
|
+
fix_callbacks+=("_fix_apt_cache")
|
|
294
|
+
else
|
|
295
|
+
log_success "APT cache: $cache_size ($cache_files files)"
|
|
296
|
+
fi
|
|
297
|
+
fi
|
|
298
|
+
|
|
189
299
|
if $QUICK_MODE; then
|
|
190
300
|
echo
|
|
191
|
-
log_info "Quick mode: skipping
|
|
301
|
+
log_info "Quick mode: skipping extended runtime, AI, shell, process, I/O, and network checks"
|
|
192
302
|
echo
|
|
193
303
|
else
|
|
194
304
|
|
|
@@ -384,10 +494,12 @@ doctor_main() {
|
|
|
384
494
|
fi
|
|
385
495
|
|
|
386
496
|
# C extension build capability
|
|
387
|
-
local
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
497
|
+
local python_include_output
|
|
498
|
+
local -a python_include_flags=()
|
|
499
|
+
python_include_output=$(python3-config --includes 2>/dev/null || true)
|
|
500
|
+
read -r -a python_include_flags <<< "$python_include_output"
|
|
501
|
+
if [[ ${#python_include_flags[@]} -gt 0 ]] && \
|
|
502
|
+
clang "${python_include_flags[@]}" -shared -fPIC -o /dev/null -x c - <<<'#include <Python.h>' &>/dev/null; then
|
|
391
503
|
log_success "C extensions can be compiled (Python.h + clang OK)"
|
|
392
504
|
else
|
|
393
505
|
log_warn "C extension build may fail — clang or Python headers issue"
|
|
@@ -396,7 +508,6 @@ doctor_main() {
|
|
|
396
508
|
fix_descriptions+=("Install C build dependencies for Python extensions")
|
|
397
509
|
fix_callbacks+=("_fix_pkg_install")
|
|
398
510
|
fi
|
|
399
|
-
rm -f "$cc_test"
|
|
400
511
|
|
|
401
512
|
# uv availability (used by hermes-agent installer)
|
|
402
513
|
if command -v uv &>/dev/null; then
|
|
@@ -406,9 +517,11 @@ doctor_main() {
|
|
|
406
517
|
fi
|
|
407
518
|
|
|
408
519
|
# pip check — detect broken dependencies
|
|
409
|
-
local pip_check_output
|
|
410
|
-
pip_check_output=$(timeout 15 pip check 2>&1
|
|
411
|
-
|
|
520
|
+
local pip_check_output pip_check_rc
|
|
521
|
+
pip_check_output=$(timeout 15 pip check 2>&1) && pip_check_rc=0 || pip_check_rc=$?
|
|
522
|
+
local broken_lines
|
|
523
|
+
broken_lines=$(echo "$pip_check_output" | grep -i "broken\|missing\|conflict\|incompatible" || true)
|
|
524
|
+
if (( pip_check_rc == 0 )) || [[ -z "$broken_lines" ]]; then
|
|
412
525
|
log_success "pip dependencies: consistent"
|
|
413
526
|
else
|
|
414
527
|
log_warn "pip dependency issues detected"
|
|
@@ -417,7 +530,7 @@ doctor_main() {
|
|
|
417
530
|
done
|
|
418
531
|
((warnings++))
|
|
419
532
|
local broken_pkgs
|
|
420
|
-
broken_pkgs=$(
|
|
533
|
+
broken_pkgs=$(echo "$broken_lines" | grep -oP '^\S+' | head -3 | tr '\n' ' ')
|
|
421
534
|
if [[ -n "$broken_pkgs" ]]; then
|
|
422
535
|
fix_commands+=("pip install --upgrade --force-reinstall $broken_pkgs")
|
|
423
536
|
fix_descriptions+=("Fix pip dependency conflicts: $broken_pkgs")
|
|
@@ -467,14 +580,13 @@ doctor_main() {
|
|
|
467
580
|
fix_callbacks+=("_fix_banner")
|
|
468
581
|
fi
|
|
469
582
|
fi
|
|
470
|
-
fi # end QUICK_MODE skip
|
|
471
583
|
|
|
472
584
|
# ===== 10. AI TOOLS STATUS =====
|
|
473
585
|
echo
|
|
474
586
|
separator_section "AI Tools Installed"
|
|
475
587
|
echo
|
|
476
588
|
|
|
477
|
-
local -a ai_cmds=("opencode" "claude" "gemini" "codex" "qwen" "vibe" "mimo" "hermes" "kimi" "ollama" "freebuff" "pi" "agy" "mmx" "gentle-ai" "gga" "engram" "codegraph" "kilocode" "kiro" "crush" "odysseus" "openclaude" "openclaw" "command-code" "kimchi" "cline" "omni-route" "ctx7" "openspec")
|
|
589
|
+
local -a ai_cmds=("opencode" "claude" "gemini" "codex" "qwen" "vibe" "mimo" "hermes" "kimi" "ollama" "freebuff" "pi" "agy" "mmx" "gentle-ai" "gga" "engram" "codegraph" "kilocode" "kiro" "crush" "odysseus" "openclaude" "openclaw" "command-code" "kimchi" "cline" "omni-route" "ctx7" "openspec" "copilot")
|
|
478
590
|
local ai_count=0
|
|
479
591
|
|
|
480
592
|
for cmd in "${ai_cmds[@]}"; do
|
|
@@ -699,9 +811,7 @@ doctor_main() {
|
|
|
699
811
|
|
|
700
812
|
if command -v proot-distro &>/dev/null; then
|
|
701
813
|
log_success "proot-distro: available"
|
|
702
|
-
|
|
703
|
-
if proot-distro list 2>/dev/null | grep -qi ubuntu; then
|
|
704
|
-
ubuntu_installed=true
|
|
814
|
+
if proot-distro list 2>&1 | grep -qi ubuntu; then
|
|
705
815
|
log_success "Ubuntu proot container: installed"
|
|
706
816
|
else
|
|
707
817
|
log_info "Ubuntu proot container: not installed (needed by kimchi)"
|
|
@@ -727,8 +837,10 @@ doctor_main() {
|
|
|
727
837
|
separator_section "Termux:API"
|
|
728
838
|
echo
|
|
729
839
|
|
|
730
|
-
if command -v termux-
|
|
731
|
-
log_success "Termux:API is installed"
|
|
840
|
+
if command -v termux-battery-status &>/dev/null; then
|
|
841
|
+
log_success "Termux:API is installed (termux-battery-status available)"
|
|
842
|
+
elif dpkg -s termux-api 2>/dev/null | grep -q 'Status.*installed'; then
|
|
843
|
+
log_success "Termux:API package installed"
|
|
732
844
|
else
|
|
733
845
|
log_warn "Termux:API not installed (needed for voice commands)"
|
|
734
846
|
((warnings++))
|
|
@@ -775,14 +887,24 @@ doctor_main() {
|
|
|
775
887
|
echo
|
|
776
888
|
|
|
777
889
|
# DNS resolution
|
|
778
|
-
|
|
890
|
+
local dns_ok=false
|
|
891
|
+
if command -v nslookup &>/dev/null; then
|
|
892
|
+
nslookup github.com &>/dev/null && dns_ok=true
|
|
893
|
+
elif command -v host &>/dev/null; then
|
|
894
|
+
host github.com &>/dev/null && dns_ok=true
|
|
895
|
+
elif command -v curl &>/dev/null; then
|
|
896
|
+
curl -fsSL --max-time 5 https://github.com &>/dev/null && dns_ok=true
|
|
897
|
+
fi
|
|
898
|
+
if $dns_ok; then
|
|
779
899
|
log_success "DNS resolution: OK"
|
|
780
900
|
else
|
|
781
|
-
|
|
901
|
+
local dns_warn="DNS resolution check failed"
|
|
902
|
+
if ! command -v nslookup &>/dev/null && ! command -v host &>/dev/null; then
|
|
903
|
+
dns_warn="$dns_warn (install dnsutils or whois for detailed check)"
|
|
904
|
+
fi
|
|
905
|
+
log_warn "$dns_warn"
|
|
782
906
|
((warnings++))
|
|
783
|
-
|
|
784
|
-
fix_descriptions+=("Set Google DNS (8.8.8.8) for Termux")
|
|
785
|
-
fix_callbacks+=("_fix_dns")
|
|
907
|
+
|
|
786
908
|
fi
|
|
787
909
|
|
|
788
910
|
if curl -fsSL --max-time 5 https://github.com &>/dev/null; then
|
|
@@ -843,7 +965,7 @@ doctor_main() {
|
|
|
843
965
|
separator_section "Karnel Data Integrity"
|
|
844
966
|
echo
|
|
845
967
|
|
|
846
|
-
local karnel_dirs=("$KARNEL_CONFIG" "$KARNEL_CACHE" "$KARNEL_DATA"
|
|
968
|
+
local karnel_dirs=("$KARNEL_CONFIG" "$KARNEL_CACHE" "$KARNEL_DATA")
|
|
847
969
|
for dir in "${karnel_dirs[@]}"; do
|
|
848
970
|
if [[ -d "$dir" ]]; then
|
|
849
971
|
local size
|
|
@@ -887,7 +1009,7 @@ doctor_main() {
|
|
|
887
1009
|
|
|
888
1010
|
# Check url-quote-magic for parse errors (Termux zsh bug)
|
|
889
1011
|
local uqm_file="$PREFIX/share/zsh/functions/Zle/url-quote-magic"
|
|
890
|
-
if [[ -f "$uqm_file" ]] && grep -
|
|
1012
|
+
if [[ -f "$uqm_file" ]] && grep -qF "((\${~localschema})" "$uqm_file" 2>/dev/null; then
|
|
891
1013
|
log_warn "url-quote-magic: double-paren parse error found (zsh 5.9 bug)"
|
|
892
1014
|
log_warn "url-quote-magic has known double-paren syntax error"
|
|
893
1015
|
fix_commands+=("true")
|
|
@@ -902,7 +1024,7 @@ doctor_main() {
|
|
|
902
1024
|
|
|
903
1025
|
if command -v termux-info &>/dev/null; then
|
|
904
1026
|
local gpu_info
|
|
905
|
-
gpu_info=$(termux-info 2>/dev/null | grep -i "gpu\|render\|opengl" | head -3)
|
|
1027
|
+
gpu_info=$(timeout 10 termux-info 2>/dev/null | grep -i "gpu\|render\|opengl" | head -3)
|
|
906
1028
|
if [[ -n "$gpu_info" ]]; then
|
|
907
1029
|
log_success "GPU: $(echo "$gpu_info" | tr -s ' ')"
|
|
908
1030
|
fi
|
|
@@ -936,7 +1058,7 @@ doctor_main() {
|
|
|
936
1058
|
|
|
937
1059
|
if command -v termux-battery-status &>/dev/null; then
|
|
938
1060
|
local battery_info
|
|
939
|
-
battery_info=$(termux-battery-status 2>/dev/null)
|
|
1061
|
+
battery_info=$(timeout 5 termux-battery-status 2>/dev/null || true)
|
|
940
1062
|
if [[ -n "$battery_info" ]]; then
|
|
941
1063
|
local battery_pct
|
|
942
1064
|
battery_pct=$(echo "$battery_info" | python3 -c "import json,sys; print(json.load(sys.stdin).get('percentage',0))" 2>/dev/null || echo "?")
|
|
@@ -952,6 +1074,8 @@ doctor_main() {
|
|
|
952
1074
|
local charging
|
|
953
1075
|
charging=$(echo "$battery_info" | python3 -c "import json,sys; print(json.load(sys.stdin).get('status','Unknown'))" 2>/dev/null || echo "?")
|
|
954
1076
|
log_info "Charging status: $charging"
|
|
1077
|
+
else
|
|
1078
|
+
log_info "Battery status unavailable or timed out"
|
|
955
1079
|
fi
|
|
956
1080
|
else
|
|
957
1081
|
log_info "termux-battery-status not available (install termux-api)"
|
|
@@ -1023,7 +1147,7 @@ doctor_main() {
|
|
|
1023
1147
|
# Check for orphaned node/python processes
|
|
1024
1148
|
local orphan_count=0
|
|
1025
1149
|
orphan_count=$(pgrep -c -f 'node.*karnel\|python.*karnel' 2>/dev/null || echo 0)
|
|
1026
|
-
if (( orphan_count > 2 )); then
|
|
1150
|
+
if [[ "$orphan_count" =~ ^[0-9]+$ ]] && (( orphan_count > 2 )); then
|
|
1027
1151
|
log_warn "$orphan_count Karnel-related processes running (may be stale)"
|
|
1028
1152
|
((warnings++))
|
|
1029
1153
|
fi
|
|
@@ -1033,8 +1157,8 @@ doctor_main() {
|
|
|
1033
1157
|
separator_section "Storage I/O Health"
|
|
1034
1158
|
echo
|
|
1035
1159
|
|
|
1036
|
-
local io_test_file
|
|
1037
|
-
|
|
1160
|
+
local io_test_file
|
|
1161
|
+
io_test_file="$(mktemp "$KARNEL_CACHE/karnel_io_test.XXXXXX" 2>/dev/null)" || io_test_file="$KARNEL_CACHE/karnel_io_test.$$"
|
|
1038
1162
|
local io_start io_end io_time
|
|
1039
1163
|
io_start=$(date +%s%N 2>/dev/null || echo 0)
|
|
1040
1164
|
dd if=/dev/zero of="$io_test_file" bs=4096 count=100 2>/dev/null
|
|
@@ -1107,8 +1231,13 @@ doctor_main() {
|
|
|
1107
1231
|
echo
|
|
1108
1232
|
|
|
1109
1233
|
if [[ -d /storage ]]; then
|
|
1110
|
-
local storage_count
|
|
1111
|
-
|
|
1234
|
+
local storage_count=0 storage_path storage_name
|
|
1235
|
+
for storage_path in /storage/*; do
|
|
1236
|
+
[[ -e "$storage_path" ]] || continue
|
|
1237
|
+
storage_name=$(basename "$storage_path")
|
|
1238
|
+
[[ "$storage_name" == "emulated" || "$storage_name" == "self" ]] && continue
|
|
1239
|
+
storage_count=$((storage_count + 1))
|
|
1240
|
+
done
|
|
1112
1241
|
if (( storage_count > 0 )); then
|
|
1113
1242
|
log_success "External storage: $storage_count volume(s) mounted"
|
|
1114
1243
|
else
|
|
@@ -1119,54 +1248,23 @@ doctor_main() {
|
|
|
1119
1248
|
# Check USB devices
|
|
1120
1249
|
if [[ -d /dev/bus/usb ]]; then
|
|
1121
1250
|
local usb_count
|
|
1122
|
-
usb_count=$(
|
|
1251
|
+
usb_count=$(find /dev/bus/usb -mindepth 1 -maxdepth 1 -type d -print 2>/dev/null | wc -l)
|
|
1123
1252
|
if (( usb_count > 0 )); then
|
|
1124
1253
|
log_info "USB: $usb_count bus(es) detected"
|
|
1125
1254
|
fi
|
|
1126
1255
|
fi
|
|
1127
1256
|
|
|
1257
|
+
fi # end QUICK_MODE skip
|
|
1258
|
+
|
|
1128
1259
|
# ===== GENERATE REPORT =====
|
|
1129
1260
|
local report_dir="$KARNEL_DATA/doctor_reports"
|
|
1130
|
-
mkdir -p "$report_dir"
|
|
1261
|
+
mkdir -p "$report_dir" 2>/dev/null || log_warn "Could not create report directory"
|
|
1131
1262
|
local report_file="$report_dir/doctor_report_latest.md"
|
|
1132
1263
|
|
|
1133
|
-
cat >"$report_file" <<EOF
|
|
1134
|
-
# Karnel Doctor Diagnostic Report
|
|
1135
|
-
Generated: $(date)
|
|
1136
|
-
|
|
1137
|
-
## System Info
|
|
1138
|
-
- **Android**: $android_ver
|
|
1139
|
-
- **Termux**: $termux_ver
|
|
1140
|
-
- **Architecture**: $arch
|
|
1141
|
-
- **Karnel Version**: $karnel_ver
|
|
1142
|
-
|
|
1143
|
-
## Resources
|
|
1144
|
-
- **Disk Free**: $free_space
|
|
1145
|
-
- **RAM Total**: $ram_total
|
|
1146
|
-
- **RAM Free**: $ram_free
|
|
1147
|
-
|
|
1148
|
-
## Storage & Permissions
|
|
1149
|
-
- **Shared Storage**: $storage_status
|
|
1150
|
-
- **Karnel Write Access**: $([ -w "$KARNEL_PATH" ] && echo "Yes" || echo "No")
|
|
1151
|
-
|
|
1152
|
-
## PostgreSQL
|
|
1153
|
-
- **Installed**: $pg_installed
|
|
1154
|
-
- **Data Found**: ${pg_data_found:-unknown}
|
|
1155
|
-
|
|
1156
|
-
## AI Tools
|
|
1157
|
-
- **Count**: $ai_count
|
|
1158
|
-
|
|
1159
|
-
## Summary
|
|
1160
|
-
- **Errors**: $errors
|
|
1161
|
-
- **Warnings**: $warnings
|
|
1162
|
-
- **Fixed**: $fixed
|
|
1163
|
-
EOF
|
|
1164
|
-
|
|
1165
1264
|
# ===== RESULTS =====
|
|
1166
1265
|
echo
|
|
1167
1266
|
separator
|
|
1168
1267
|
log_success "Diagnostics completed!"
|
|
1169
|
-
list_item "Report saved: ${D_CYAN}$report_file${D_NC}"
|
|
1170
1268
|
|
|
1171
1269
|
if [[ $errors -gt 0 ]]; then
|
|
1172
1270
|
log_error "Found $errors error(s) and $warnings warning(s)."
|
|
@@ -1201,8 +1299,6 @@ EOF
|
|
|
1201
1299
|
|
|
1202
1300
|
if [[ -n "$callback" ]] && type "$callback" &>/dev/null 2>&1; then
|
|
1203
1301
|
"$callback" && success=true
|
|
1204
|
-
elif [[ -n "${fix_commands[$i]}" ]]; then
|
|
1205
|
-
eval "${fix_commands[$i]}" 2>/dev/null && success=true
|
|
1206
1302
|
fi
|
|
1207
1303
|
|
|
1208
1304
|
if [[ "$success" == "true" ]]; then
|
|
@@ -1220,8 +1316,54 @@ EOF
|
|
|
1220
1316
|
fi
|
|
1221
1317
|
fi
|
|
1222
1318
|
fi
|
|
1319
|
+
|
|
1320
|
+
if cat >"$report_file" <<EOF
|
|
1321
|
+
# Karnel Doctor Diagnostic Report
|
|
1322
|
+
Generated: $(date)
|
|
1323
|
+
|
|
1324
|
+
## System Info
|
|
1325
|
+
- **Android**: $android_ver
|
|
1326
|
+
- **Termux**: $termux_ver
|
|
1327
|
+
- **Architecture**: $arch
|
|
1328
|
+
- **Karnel Version**: ${karnel_ver:-skipped}
|
|
1329
|
+
|
|
1330
|
+
## Resources
|
|
1331
|
+
- **Disk Free**: $free_space
|
|
1332
|
+
- **RAM Total**: $ram_total
|
|
1333
|
+
- **RAM Free**: $ram_free
|
|
1334
|
+
|
|
1335
|
+
## Storage & Permissions
|
|
1336
|
+
- **Shared Storage**: $storage_status
|
|
1337
|
+
- **Karnel Write Access**: $([ -w "$KARNEL_PATH" ] && echo "Yes" || echo "No")
|
|
1338
|
+
|
|
1339
|
+
## PostgreSQL
|
|
1340
|
+
- **Installed**: ${pg_installed:-skipped}
|
|
1341
|
+
- **Data Found**: ${pg_data_found:-skipped}
|
|
1342
|
+
|
|
1343
|
+
## AI Tools
|
|
1344
|
+
- **Count**: ${ai_count:-skipped}
|
|
1345
|
+
|
|
1346
|
+
## Summary
|
|
1347
|
+
- **Errors**: $errors
|
|
1348
|
+
- **Warnings**: $warnings
|
|
1349
|
+
- **Fixed**: $fixed
|
|
1350
|
+
EOF
|
|
1351
|
+
then
|
|
1352
|
+
list_item "Report saved: ${D_CYAN}$report_file${D_NC}"
|
|
1353
|
+
else
|
|
1354
|
+
log_warn "Failed to save report"
|
|
1355
|
+
fi
|
|
1223
1356
|
echo
|
|
1224
1357
|
}
|
|
1225
1358
|
|
|
1226
|
-
|
|
1359
|
+
_fix_keyring() {
|
|
1360
|
+
pkg update -y &>/dev/null && pkg install -y termux-keyring &>/dev/null
|
|
1361
|
+
}
|
|
1227
1362
|
|
|
1363
|
+
_fix_apt_cache() {
|
|
1364
|
+
rm -rf "$PREFIX/var/apt/lists"/* 2>/dev/null
|
|
1365
|
+
pkg update -y &>/dev/null
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
import "@/cli/commands/doctor/fixes"
|
|
1369
|
+
import "@/cli/commands/doctor/code"
|
|
@@ -100,6 +100,7 @@ env_unset() {
|
|
|
100
100
|
local -a keys=()
|
|
101
101
|
local line k
|
|
102
102
|
while IFS= read -r line; do
|
|
103
|
+
[[ "$line" != *"="* ]] && continue
|
|
103
104
|
line="${line#export }"
|
|
104
105
|
k="${line%%=*}"
|
|
105
106
|
keys+=("$k")
|
|
@@ -179,6 +180,7 @@ env_ls() {
|
|
|
179
180
|
local line
|
|
180
181
|
|
|
181
182
|
while IFS= read -r line; do
|
|
183
|
+
[[ "$line" != *"="* ]] && continue
|
|
182
184
|
line="${line#export }"
|
|
183
185
|
local k="${line%%=*}"
|
|
184
186
|
local v="${line#*=}"
|
|
@@ -353,6 +353,16 @@ ia_sessions() {
|
|
|
353
353
|
done
|
|
354
354
|
fi
|
|
355
355
|
|
|
356
|
+
# Copilot-Termux sessions
|
|
357
|
+
if [[ -d "$HOME/.copilot" ]]; then
|
|
358
|
+
while IFS= read -r -d '' f; do
|
|
359
|
+
local basename; basename=$(basename "$f")
|
|
360
|
+
local ts; ts=$(stat -c %Y "$f" 2>/dev/null || echo "unknown")
|
|
361
|
+
local readable_ts; readable_ts=$(date -d "@$ts" +%Y%m%d_%H%M%S 2>/dev/null || echo "unknown")
|
|
362
|
+
sessions+=("[copilot]|$readable_ts|$basename")
|
|
363
|
+
done < <(find "$HOME/.copilot" \( -name 'events.jsonl' -o -name 'command-history-state.json' \) -type f -print0 2>/dev/null)
|
|
364
|
+
fi
|
|
365
|
+
|
|
356
366
|
if [[ ${#sessions[@]} -eq 0 ]]; then
|
|
357
367
|
log_warn "No AI sessions found"
|
|
358
368
|
log_info "Start an AI tool to create your first session"
|
|
@@ -371,7 +381,7 @@ ia_sessions() {
|
|
|
371
381
|
ts_raw=$(echo "$session" | cut -d'|' -f2)
|
|
372
382
|
name=$(echo "$session" | cut -d'|' -f3-)
|
|
373
383
|
local escaped_name
|
|
374
|
-
escaped_name=$(printf '%s' "$name" | sed 's/"/\\"/g')
|
|
384
|
+
escaped_name=$(printf '%s' "$name" | sed 's/"/\\"/g' | sed "s/'/\\\\'/g")
|
|
375
385
|
if [[ $first -eq 1 ]]; then
|
|
376
386
|
first=0
|
|
377
387
|
else
|
|
@@ -421,7 +431,7 @@ ia_routes() {
|
|
|
421
431
|
local -a routes=()
|
|
422
432
|
|
|
423
433
|
# Collect all available AI CLIs (em sincronia com AI_TOOLS_REGISTRY em tools/ai/all.sh)
|
|
424
|
-
for cmd in qwen gemini claude vibe openclaude openclaw ollama codex opencode mimo engram codegraph pi agy mmx gentle-ai gga hermes kimi command-code freebuff kilocode kiro cline crush odysseus kimchi omni-route ctx7 openspec; do
|
|
434
|
+
for cmd in qwen gemini claude vibe openclaude openclaw ollama codex opencode mimo engram codegraph pi agy mmx gentle-ai gga hermes kimi command-code freebuff kilocode kiro cline crush odysseus kimchi omni-route ctx7 openspec copilot; do
|
|
425
435
|
if command -v "$cmd" &>/dev/null; then
|
|
426
436
|
local path
|
|
427
437
|
path=$(command -v "$cmd")
|
|
@@ -131,7 +131,8 @@ EOF
|
|
|
131
131
|
if ! command -v jq &>/dev/null; then
|
|
132
132
|
log_warn "jq not found — skipping package.json update"
|
|
133
133
|
else
|
|
134
|
-
local temp
|
|
134
|
+
local temp
|
|
135
|
+
temp=$(mktemp)
|
|
135
136
|
jq '.scripts.dev = "next dev --webpack" | .scripts.build = "next build --webpack" | .scripts.start = "next start"' package.json > "$temp" && mv "$temp" package.json
|
|
136
137
|
log_success "Added --webpack flag to dev and build scripts"
|
|
137
138
|
fi
|
|
@@ -531,7 +532,8 @@ EOF
|
|
|
531
532
|
if ! command -v jq &>/dev/null; then
|
|
532
533
|
log_warn "jq not found — skipping package.json update"
|
|
533
534
|
else
|
|
534
|
-
local temp
|
|
535
|
+
local temp
|
|
536
|
+
temp=$(mktemp)
|
|
535
537
|
jq '.scripts += {
|
|
536
538
|
"dev": "ts-node-dev --require tsconfig-paths/register --env-file=.env --respawn src/index.ts",
|
|
537
539
|
"build": "tsc && tsc-alias -p tsconfig.json",
|
|
@@ -1005,8 +1007,8 @@ EOF
|
|
|
1005
1007
|
|
|
1006
1008
|
# Create scripts/run.sh
|
|
1007
1009
|
cat >scripts/run.sh <<'EOF'
|
|
1008
|
-
#!/usr/bin/bash
|
|
1009
|
-
|
|
1010
|
+
#!/usr/bin/env bash
|
|
1011
|
+
cargo run
|
|
1010
1012
|
EOF
|
|
1011
1013
|
chmod +x scripts/run.sh
|
|
1012
1014
|
|
|
@@ -1076,8 +1078,13 @@ configure_rust() {
|
|
|
1076
1078
|
|
|
1077
1079
|
# Append dependencies to Cargo.toml
|
|
1078
1080
|
if [[ -f "Cargo.toml" ]]; then
|
|
1079
|
-
#
|
|
1080
|
-
|
|
1081
|
+
# Append after [dependencies] or add it
|
|
1082
|
+
if grep -q '^\[dependencies\]' Cargo.toml; then
|
|
1083
|
+
cat >>Cargo.toml <<EOF
|
|
1084
|
+
EOF
|
|
1085
|
+
else
|
|
1086
|
+
echo -e "\n[dependencies]" >> Cargo.toml
|
|
1087
|
+
fi
|
|
1081
1088
|
cat >>Cargo.toml <<EOF
|
|
1082
1089
|
tokio = { version = "1.0", features = ["full"] }
|
|
1083
1090
|
serde = { version = "1.0", features = ["derive"] }
|
|
@@ -1184,8 +1191,8 @@ EOF
|
|
|
1184
1191
|
|
|
1185
1192
|
# Create scripts/run.sh
|
|
1186
1193
|
cat >scripts/run.sh <<'EOF'
|
|
1187
|
-
#!/usr/bin/bash
|
|
1188
|
-
|
|
1194
|
+
#!/usr/bin/env bash
|
|
1195
|
+
go run cmd/api/main.go
|
|
1189
1196
|
EOF
|
|
1190
1197
|
chmod +x scripts/run.sh
|
|
1191
1198
|
|
|
@@ -1236,7 +1243,8 @@ init_main() {
|
|
|
1236
1243
|
go | gin) configure_go ;;
|
|
1237
1244
|
rust | axum) configure_rust ;;
|
|
1238
1245
|
"")
|
|
1239
|
-
local detected
|
|
1246
|
+
local detected
|
|
1247
|
+
detected=$(detect_project_type)
|
|
1240
1248
|
if [[ "$detected" != "unknown" ]]; then
|
|
1241
1249
|
log_info "Detected project type: $detected"
|
|
1242
1250
|
echo
|