karnel-termux 4.17.34 → 4.17.36

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.34-0078D4?style=for-the-badge" alt="Version">
11
+ <img src="https://img.shields.io/badge/version-4.17.36-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">
@@ -31,7 +31,7 @@
31
31
 
32
32
  **Karnel Termux** is a modular development environment that transforms Termux into a complete workstation.
33
33
 
34
- Created by **Israel Marques**. Core agent contributions by **devcorex**.
34
+ Created by **Israel Marques**.
35
35
 
36
36
  With a single CLI (`karnel`), install and manage:
37
37
 
@@ -78,7 +78,7 @@ Why it's great:
78
78
  ### Via checksummed GitHub release (recommended)
79
79
 
80
80
  ```bash
81
- version=4.17.34
81
+ version=4.17.36
82
82
  tmpdir=$(mktemp -d) && trap 'rm -rf "$tmpdir"' EXIT
83
83
  base="https://github.com/israelmarques1024-dotcom/karnel-termux/releases/download/v$version"
84
84
  curl -fsSL "$base/karnel-termux-install.sh" -o "$tmpdir/karnel-termux-install.sh"
@@ -666,8 +666,9 @@ once every 24 hours; the check can use npm or GitHub and writes state under
666
666
 
667
667
  The repository CI validates Bash/Zsh syntax, ShellCheck errors, CLI smoke tests,
668
668
  version behavior, Robin contracts, plugin lifecycle contracts, and npm package
669
- contents. The documentation site is built by the `Publish Docs` workflow with
670
- `actions/jekyll-build-pages`, so a broken Jekyll page fails that build.
669
+ contents. The `Publish Docs` workflow builds the GitHub Pages documentation
670
+ mirror with `actions/jekyll-build-pages`; the official Vite documentation site
671
+ is built and deployed separately through Vercel.
671
672
 
672
673
  These checks do not install every external tool or prove behavior on every Android
673
674
  device. Before relying on a new installer, test it in native Termux aarch64 with
@@ -33,7 +33,7 @@ karnel-termux/
33
33
  │ │ ├── dev.sh # Dev tools installer
34
34
  │ │ └── ...
35
35
  │ ├── tools/ # Individual tool installers
36
- │ │ ├── ai/ # 45 AI tools
36
+ │ │ ├── ai/ # 46 AI tools
37
37
  │ │ ├── lang/ # 8 languages
38
38
  │ │ ├── db/ # 5 databases
39
39
  │ │ ├── dev/ # 22 dev tools
package/docs/CHANGELOG.md CHANGED
@@ -249,14 +249,13 @@ layout: base
249
249
  - Cactus glibc installer: pip output is now streamed live (and mirrored to the
250
250
  install log) instead of being hidden behind an indeterminate spinner, which
251
251
  made multi-minute downloads look frozen.
252
- - Credits: devcorex credited as a core agent contributor in `karnel agent`
253
- help/REPL screens and project READMEs.
252
+ - Agent help/REPL screens and project READMEs were updated with contributor
253
+ credits.
254
254
 
255
255
  ## 4.16.0 - 2026-08-20
256
256
 
257
- - Rebranded fully to Karnel: removed every remaining reference to DevCoreX and
258
- core-termux across contributors, CLI `open` targets, completions, docs and
259
- agent utilities.
257
+ - Rebranded fully to Karnel: removed legacy upstream branding across
258
+ contributors, CLI `open` targets, completions, docs and agent utilities.
260
259
  - `nvchad` editor tool now installs the official upstream `NvChad/starter`
261
260
  (pinned to a reviewed commit) instead of a third-party fork.
262
261
  - Added the `karnel agent` subsystem (agent.sh, agent_actions.sh, agent_llm.sh,
package/docs/cli/index.md CHANGED
@@ -29,7 +29,7 @@ karnel install <module> --tool1 --tool2 # Install specific tools only
29
29
  |-----------|-------------|
30
30
  | `lang` | Node.js, Python, Go, Rust, C/C++, PHP, Perl, Bun |
31
31
  | `db` | PostgreSQL, MariaDB, SQLite, MongoDB, Redis |
32
- | `ai` | 45 AI tools (OpenCode, Cactus, Hugging Face, Claude Code, KeelCode, Goose, Factory Droid, Ollama, etc.) |
32
+ | `ai` | 46 AI tools (OpenCode, Cactus, Hugging Face, Claude Code, KeelCode, Goose, Factory Droid, 10Router, Ollama, etc.) |
33
33
  | `editor` | code-server (VS Code in browser), Neovim, NvChad |
34
34
  | `dev` | gh, curl, fzf, bat, lsd, jq, tmux, openssh, snyk (22 tools) |
35
35
  | `npm` | TypeScript, NestJS CLI, Prettier, Vercel CLI, etc. |
@@ -143,7 +143,7 @@ binary/command name, and current install status.
143
143
  |-----------|-------|
144
144
  | `lang` | 8 languages |
145
145
  | `db` | 5 databases |
146
- | `ai` | 45 AI tools |
146
+ | `ai` | 46 AI tools |
147
147
  | `editor` | 3 editor components |
148
148
  | `dev` | 22 development tools |
149
149
  | `npm` | 11 npm global modules |
package/docs/index.md CHANGED
@@ -9,7 +9,7 @@ layout: base
9
9
  ## What is Karnel?
10
10
 
11
11
  Karnel Termux transforms your Android device into a complete development workstation.
12
- With a single CLI (`karnel`), you can install and manage 45 AI tools, 3 editors,
12
+ With a single CLI (`karnel`), you can install and manage 46 AI tools, 3 editors,
13
13
  8 languages, 5 databases, 22 dev tools, 11 npm packages, 10 shell plugins,
14
14
  4 UI components, 4 deploy CLIs, 6 games, 2 network tools, 13 utility tools,
15
15
  30 security tools, 1 automation tool, responsible OSINT, a second brain,
@@ -48,4 +48,4 @@ Open its docs with `karnel open herdr`.
48
48
 
49
49
  ## Credits
50
50
 
51
- Created by **Israel Marques**. Core agent contributions by **devcorex**.
51
+ Created by **Israel Marques**.
@@ -1 +1 @@
1
- f571178a0a7fdf05e9963d7effeeb2ddf65e7599
1
+ 6ce9fe8b0567a2129eac070d4c168dd5ea79450f
@@ -14,8 +14,6 @@
14
14
  # TTY) typing `@query` opens an fzf picker to attach a file's
15
15
  # contents to your message.
16
16
  #
17
- # Credits:
18
- # devcorex — core agent contributor
19
17
  # ============================================================
20
18
 
21
19
  import "@/utils/log"
@@ -31,8 +29,6 @@ agent_help() {
31
29
  echo
32
30
  box "Karnel Agent — Local AI Assistant & Task Agent"
33
31
  echo
34
- printf " ${D_GRAY}credits: devcorex — core agent${D_NC}\n"
35
- echo
36
32
  log_info "Usage: karnel agent <ask|run|config> [options]"
37
33
  echo
38
34
  separator_section "Subcommands"
@@ -560,8 +556,6 @@ agent_ask_repl() {
560
556
  agent_banner
561
557
  separator_section "Karnel Agent — Ask"
562
558
  echo
563
- printf " ${D_GRAY}credits: devcorex — core agent${D_NC}\n"
564
- echo
565
559
  agent_status_line
566
560
  echo
567
561
  list_item "Type ${D_CYAN}/help${D_NC} to see all commands"
@@ -677,8 +671,6 @@ agent_run_repl() {
677
671
  agent_banner
678
672
  separator_section "Karnel Agent — Run ($([[ $AGENT_PLAN_MODE == 1 ]] && echo 'PLAN · read-only' || echo 'BUILD mode'))"
679
673
  echo
680
- printf " ${D_GRAY}credits: devcorex — core agent${D_NC}\n"
681
- echo
682
674
  agent_status_line
683
675
  echo
684
676
  list_item "Type ${D_CYAN}/help${D_NC} to see all commands"
@@ -276,11 +276,7 @@ _update_try_curl() {
276
276
  return 0
277
277
  fi
278
278
  else
279
- if bash "$installer" --ref "$tag"; then
280
- rm -f "$installer"
281
- log_success "Karnel-Termux updated via curl ($tag)"
282
- return 0
283
- fi
279
+ log_error "Could not verify the immutable commit for $tag"
284
280
  fi
285
281
 
286
282
  rm -f "$installer"
@@ -421,7 +417,17 @@ _update_show_manual() {
421
417
 
422
418
  _update_karnel_repo() {
423
419
  local repo_dir="$KARNEL_PATH/.."
424
- local old_head
420
+ local old_head origin
421
+
422
+ origin=$(git -C "$repo_dir" remote get-url origin 2>/dev/null) || return 1
423
+ case "${origin%.git}" in
424
+ https://github.com/israelmarques1024-dotcom/karnel-termux|git@github.com:israelmarques1024-dotcom/karnel-termux) ;;
425
+ *) log_error "Refusing git update from an untrusted origin: $origin"; return 1 ;;
426
+ esac
427
+ if [[ -n "$(git -C "$repo_dir" status --porcelain --untracked-files=all 2>/dev/null)" ]]; then
428
+ log_error "Refusing git update with uncommitted framework changes"
429
+ return 1
430
+ fi
425
431
 
426
432
  old_head=$(git -C "$repo_dir" rev-parse HEAD 2>/dev/null)
427
433
 
@@ -33,7 +33,7 @@ _n8n_dependencies() {
33
33
  }
34
34
 
35
35
  _install_n8n_impl() {
36
- _n8n_dependencies
36
+ _n8n_dependencies || return 1
37
37
 
38
38
  mkdir -p "$(dirname "$LOG_FILE")"
39
39
  export GYP_DEFINES="android_ndk_path=''"
@@ -87,6 +87,7 @@ _do_update_netlify() {
87
87
  return 1
88
88
  fi
89
89
  command -v termux-fix-shebang &>/dev/null && termux-fix-shebang "$(command -v netlify)" &>/dev/null
90
+ record_managed_file "$(command -v netlify)" "$NETLIFY_MARKER" || return 1
90
91
  return 0
91
92
  }
92
93
 
@@ -88,7 +88,15 @@ _install_railway_manual() {
88
88
  }
89
89
 
90
90
  _install_railway_manual_impl() {
91
- mkdir -p "$RAILWAY_DATA_DIR"
91
+ if [[ -e "$RAILWAY_DATA_DIR" ]] && ! _railway_data_is_karnel_owned; then
92
+ log_error "Refusing to replace unowned Railway data: $RAILWAY_DATA_DIR"
93
+ return 1
94
+ fi
95
+ if [[ -e "$PREFIX/bin/railway" || -L "$PREFIX/bin/railway" ]] && ! _railway_command_is_karnel_owned; then
96
+ log_error "Refusing to replace unowned railway command: $PREFIX/bin/railway"
97
+ return 1
98
+ fi
99
+ mkdir -p "$RAILWAY_DATA_DIR" "$PREFIX/bin"
92
100
 
93
101
  local latest_version
94
102
  latest_version=$(curl -fsSL --connect-timeout 10 "https://api.github.com/repos/railwayapp/cli/releases/latest" 2>/dev/null | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
@@ -69,6 +69,7 @@ _do_update_vercel() {
69
69
  return 1
70
70
  fi
71
71
  command -v termux-fix-shebang &>/dev/null && termux-fix-shebang "$(command -v vercel)" &>/dev/null
72
+ record_managed_file "$(command -v vercel)" "$VERCEL_MARKER" || return 1
72
73
  return 0
73
74
  }
74
75
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  _AMASS_MARKER="$PREFIX/share/karnel-installers/amass"
4
4
  _AMASS_VERSION="4.2.0"
5
+ _amass_package_owned() { [[ -f "$_AMASS_MARKER" && "$(<"$_AMASS_MARKER")" == 'pkg:amass' ]]; }
5
6
 
6
7
  _amass_arch() {
7
8
  local arch
@@ -16,7 +17,7 @@ _amass_arch() {
16
17
 
17
18
  install_amass() (
18
19
  if command -v amass &>/dev/null; then
19
- if ! installer_file_owned "$PREFIX/bin/amass" "$_AMASS_MARKER"; then
20
+ if ! installer_file_owned "$PREFIX/bin/amass" "$_AMASS_MARKER" && ! _amass_package_owned; then
20
21
  log_info "amass já está instalado"
21
22
  return 2
22
23
  fi
@@ -25,7 +26,7 @@ install_amass() (
25
26
  if [ ! -f "$_AMASS_MARKER" ] &&
26
27
  { pkg install -y amass 2>/dev/null || apt install -y amass 2>/dev/null; }; then
27
28
  local bin; bin="$(command -v amass)"
28
- [ -n "$bin" ] && sha256sum "$bin" > "$_AMASS_MARKER" 2>/dev/null
29
+ [ -n "$bin" ] && { mkdir -p "$(dirname "$_AMASS_MARKER")" && printf '%s\n' 'pkg:amass' >"$_AMASS_MARKER"; }
29
30
  log_success "amass instalado"
30
31
  return 0
31
32
  fi
@@ -66,7 +67,10 @@ install_amass() (
66
67
 
67
68
  uninstall_amass() {
68
69
  log_info "Removendo amass..."
69
- if [ -f "$_AMASS_MARKER" ]; then
70
+ if _amass_package_owned; then
71
+ pkg uninstall -y amass 2>/dev/null || apt remove -y amass 2>/dev/null || return 1
72
+ rm -f "$_AMASS_MARKER"
73
+ elif [ -f "$_AMASS_MARKER" ]; then
70
74
  [ "$(sha256sum "$PREFIX/bin/amass" 2>/dev/null)" = "$(<"$_AMASS_MARKER")" ] && rm -f "$PREFIX/bin/amass"
71
75
  rm -f "$_AMASS_MARKER"
72
76
  fi
@@ -4,6 +4,8 @@ _BURP_DIR="$PREFIX/share/burpsuite"
4
4
  _BURP_JAR="burpsuite_community.jar"
5
5
  _BURP_VERSION="2026.7.3"
6
6
  _BURP_SHA256="c8262dc5426f38bedc490d66c5d21b6ff77d6dc6d85cefe6a66c882690134069"
7
+ _BURP_PACKAGE_MARKER="$PREFIX/share/karnel-installers/burpsuite"
8
+ _burpsuite_package_owned() { [[ -f "$_BURP_PACKAGE_MARKER" && "$(<"$_BURP_PACKAGE_MARKER")" == 'pkg:burpsuite' ]]; }
7
9
 
8
10
  _burpsuite_owned() {
9
11
  installer_file_owned "$PREFIX/bin/burpsuite" "$_BURP_DIR/.karnel-wrapper"
@@ -11,7 +13,7 @@ _burpsuite_owned() {
11
13
 
12
14
  install_burpsuite() (
13
15
  if command -v burpsuite &>/dev/null; then
14
- if ! _burpsuite_owned; then
16
+ if ! _burpsuite_owned && ! _burpsuite_package_owned; then
15
17
  log_info "burpsuite já está instalado"
16
18
  return 2
17
19
  fi
@@ -20,6 +22,7 @@ install_burpsuite() (
20
22
 
21
23
  if [ ! -f "$_BURP_DIR/.karnel-wrapper" ] &&
22
24
  { pkg install -y burpsuite 2>/dev/null || apt install -y burpsuite 2>/dev/null; }; then
25
+ mkdir -p "$(dirname "$_BURP_PACKAGE_MARKER")" && printf '%s\n' 'pkg:burpsuite' >"$_BURP_PACKAGE_MARKER" || return 1
23
26
  log_success "burpsuite instalado"
24
27
  return 0
25
28
  fi
@@ -74,7 +77,10 @@ SCRIPT
74
77
 
75
78
  uninstall_burpsuite() {
76
79
  log_info "Removendo Burp Suite..."
77
- if [ -f "$_BURP_DIR/.karnel-wrapper" ]; then
80
+ if _burpsuite_package_owned; then
81
+ pkg uninstall -y burpsuite 2>/dev/null || apt remove -y burpsuite 2>/dev/null || return 1
82
+ rm -f "$_BURP_PACKAGE_MARKER"
83
+ elif [ -f "$_BURP_DIR/.karnel-wrapper" ]; then
78
84
  [ "$(sha256sum "$PREFIX/bin/burpsuite" 2>/dev/null)" = "$(<"$_BURP_DIR/.karnel-wrapper")" ] && rm -f "$PREFIX/bin/burpsuite"
79
85
  rm -rf "$_BURP_DIR"
80
86
  fi
@@ -2,6 +2,7 @@
2
2
 
3
3
  _FFUF_MARKER="$PREFIX/share/karnel-installers/ffuf"
4
4
  _FFUF_VERSION="2.1.0"
5
+ _ffuf_package_owned() { [[ -f "$_FFUF_MARKER" && "$(<"$_FFUF_MARKER")" == 'pkg:ffuf' ]]; }
5
6
 
6
7
  inc_ffuf_arch() {
7
8
  local arch
@@ -48,6 +49,7 @@ install_ffuf() {
48
49
  fi
49
50
  log_info "Instalando ffuf..."
50
51
  if pkg install -y ffuf 2>/dev/null || apt install -y ffuf 2>/dev/null; then
52
+ mkdir -p "$(dirname "$_FFUF_MARKER")" && printf '%s\n' 'pkg:ffuf' >"$_FFUF_MARKER" || return 1
51
53
  log_success "ffuf instalado"
52
54
  return 0
53
55
  fi
@@ -61,7 +63,10 @@ install_ffuf() {
61
63
 
62
64
  uninstall_ffuf() {
63
65
  log_info "Removendo ffuf..."
64
- if [ -f "$_FFUF_MARKER" ]; then
66
+ if _ffuf_package_owned; then
67
+ pkg uninstall -y ffuf 2>/dev/null || apt remove -y ffuf 2>/dev/null || return 1
68
+ rm -f "$_FFUF_MARKER"
69
+ elif [ -f "$_FFUF_MARKER" ]; then
65
70
  [ "$(sha256sum "$PREFIX/bin/ffuf" 2>/dev/null)" = "$(<"$_FFUF_MARKER")" ] && rm -f "$PREFIX/bin/ffuf"
66
71
  rm -f "$_FFUF_MARKER"
67
72
  fi
@@ -3,6 +3,7 @@
3
3
  _GOBUSTER_VERSION="3.6.0"
4
4
  _GOBUSTER_DIR="$PREFIX/share/gobuster"
5
5
  _GOBUSTER_MARKER="$PREFIX/share/karnel-installers/gobuster"
6
+ _gobuster_package_owned() { [[ -f "$_GOBUSTER_MARKER" && "$(<"$_GOBUSTER_MARKER")" == 'pkg:gobuster' ]]; }
6
7
 
7
8
  _install_gobuster_bin() (
8
9
  local arch asset checksum tmpdir archive staged_bin
@@ -36,7 +37,7 @@ _install_gobuster_bin() (
36
37
 
37
38
  install_gobuster() {
38
39
  if command -v gobuster &>/dev/null; then
39
- if ! installer_file_owned "$PREFIX/bin/gobuster" "$_GOBUSTER_MARKER"; then
40
+ if ! installer_file_owned "$PREFIX/bin/gobuster" "$_GOBUSTER_MARKER" && ! _gobuster_package_owned; then
40
41
  log_info "gobuster já está instalado"
41
42
  return 2
42
43
  fi
@@ -44,6 +45,7 @@ install_gobuster() {
44
45
  log_info "Instalando gobuster..."
45
46
  if [ ! -f "$_GOBUSTER_MARKER" ] &&
46
47
  { pkg install -y gobuster 2>/dev/null || apt install -y gobuster 2>/dev/null; }; then
48
+ mkdir -p "$(dirname "$_GOBUSTER_MARKER")" && printf '%s\n' 'pkg:gobuster' >"$_GOBUSTER_MARKER" || return 1
47
49
  log_success "gobuster instalado"
48
50
  return 0
49
51
  fi
@@ -57,7 +59,10 @@ install_gobuster() {
57
59
 
58
60
  uninstall_gobuster() {
59
61
  log_info "Removendo gobuster..."
60
- if [ -f "$_GOBUSTER_MARKER" ]; then
62
+ if _gobuster_package_owned; then
63
+ pkg uninstall -y gobuster 2>/dev/null || apt remove -y gobuster 2>/dev/null || return 1
64
+ rm -f "$_GOBUSTER_MARKER"
65
+ elif [ -f "$_GOBUSTER_MARKER" ]; then
61
66
  [ "$(sha256sum "$PREFIX/bin/gobuster" 2>/dev/null)" = "$(<"$_GOBUSTER_MARKER")" ] && rm -f "$PREFIX/bin/gobuster"
62
67
  rm -f "$_GOBUSTER_MARKER"
63
68
  fi
@@ -3,6 +3,8 @@
3
3
  _MASSCAN_DIR="${KARNEL_DATA:-${XDG_DATA_HOME:-$HOME/.local/share}/karnel-data}/tools/masscan"
4
4
  _MASSCAN_REPO="https://github.com/robertdavidgraham/masscan.git"
5
5
  _MASSCAN_COMMIT="94e118ccd26c2fb263fb2fe731043f7b3240723c"
6
+ _MASSCAN_PACKAGE_MARKER="$PREFIX/share/karnel-installers/masscan"
7
+ _masscan_package_owned() { [[ -f "$_MASSCAN_PACKAGE_MARKER" && "$(<"$_MASSCAN_PACKAGE_MARKER")" == 'pkg:masscan' ]]; }
6
8
 
7
9
  install_masscan() {
8
10
  if command -v masscan &>/dev/null; then
@@ -11,6 +13,7 @@ install_masscan() {
11
13
  fi
12
14
  log_info "Instalando masscan..."
13
15
  if pkg install -y masscan 2>/dev/null || apt install -y masscan 2>/dev/null; then
16
+ mkdir -p "$(dirname "$_MASSCAN_PACKAGE_MARKER")" && printf '%s\n' 'pkg:masscan' >"$_MASSCAN_PACKAGE_MARKER" || return 1
14
17
  log_success "masscan instalado"
15
18
  return 0
16
19
  fi
@@ -34,7 +37,10 @@ install_masscan() {
34
37
 
35
38
  uninstall_masscan() {
36
39
  log_info "Removendo masscan..."
37
- if [ -f "$_MASSCAN_DIR/.karnel-wrapper" ]; then
40
+ if _masscan_package_owned; then
41
+ pkg uninstall -y masscan 2>/dev/null || apt remove -y masscan 2>/dev/null || return 1
42
+ rm -f "$_MASSCAN_PACKAGE_MARKER"
43
+ elif [ -f "$_MASSCAN_DIR/.karnel-wrapper" ]; then
38
44
  [ "$(sha256sum "$PREFIX/bin/masscan" 2>/dev/null)" = "$(<"$_MASSCAN_DIR/.karnel-wrapper")" ] && rm -f "$PREFIX/bin/masscan"
39
45
  rm -rf "$_MASSCAN_DIR"
40
46
  fi
@@ -3,6 +3,8 @@
3
3
  METASPLOIT_DIR="${KARNEL_DATA:-${XDG_DATA_HOME:-$HOME/.local/share}/karnel-data}/tools/metasploit-framework"
4
4
  METASPLOIT_REPO="https://github.com/rapid7/metasploit-framework.git"
5
5
  METASPLOIT_COMMIT="9f74eb0a48ca7f8039c2618e359c2e80f998ac89"
6
+ METASPLOIT_PACKAGE_MARKER="$PREFIX/share/karnel-installers/metasploit"
7
+ _metasploit_package_owned() { [[ -f "$METASPLOIT_PACKAGE_MARKER" && "$(<"$METASPLOIT_PACKAGE_MARKER")" == 'pkg:metasploit' ]]; }
6
8
 
7
9
  install_metasploit() {
8
10
  if command -v msfconsole &>/dev/null; then
@@ -12,6 +14,7 @@ install_metasploit() {
12
14
  log_info "Instalando Metasploit Framework..."
13
15
 
14
16
  if pkg install -y metasploit 2>/dev/null || apt install -y metasploit 2>/dev/null; then
17
+ mkdir -p "$(dirname "$METASPLOIT_PACKAGE_MARKER")" && printf '%s\n' 'pkg:metasploit' >"$METASPLOIT_PACKAGE_MARKER" || return 1
15
18
  log_success "metasploit instalado"
16
19
  return 0
17
20
  fi
@@ -44,6 +47,12 @@ BINEOF
44
47
 
45
48
  uninstall_metasploit() {
46
49
  log_info "Removendo Metasploit..."
50
+ if _metasploit_package_owned; then
51
+ pkg uninstall -y metasploit 2>/dev/null || apt remove -y metasploit 2>/dev/null || return 1
52
+ rm -f "$METASPLOIT_PACKAGE_MARKER"
53
+ log_success "metasploit removido"
54
+ return 0
55
+ fi
47
56
  for bin in msfconsole msfvenom msfrpc msfrpcd msfdb; do
48
57
  if [ -f "$METASPLOIT_DIR/.karnel-wrapper-$bin" ]; then
49
58
  [ "$(sha256sum "$PREFIX/bin/$bin" 2>/dev/null)" = "$(<"$METASPLOIT_DIR/.karnel-wrapper-$bin")" ] && rm -f "$PREFIX/bin/$bin"
@@ -2,6 +2,7 @@
2
2
 
3
3
  _SUBFINDER_MARKER="$PREFIX/share/karnel-installers/subfinder"
4
4
  _SUBFINDER_VERSION="2.6.6"
5
+ _subfinder_package_owned() { [[ -f "$_SUBFINDER_MARKER" && "$(<"$_SUBFINDER_MARKER")" == 'pkg:subfinder' ]]; }
5
6
 
6
7
  _subfinder_arch() {
7
8
  local arch
@@ -16,7 +17,7 @@ _subfinder_arch() {
16
17
 
17
18
  install_subfinder() (
18
19
  if command -v subfinder &>/dev/null; then
19
- if ! installer_file_owned "$PREFIX/bin/subfinder" "$_SUBFINDER_MARKER"; then
20
+ if ! installer_file_owned "$PREFIX/bin/subfinder" "$_SUBFINDER_MARKER" && ! _subfinder_package_owned; then
20
21
  log_info "subfinder já está instalado"
21
22
  return 2
22
23
  fi
@@ -25,7 +26,7 @@ install_subfinder() (
25
26
  if [ ! -f "$_SUBFINDER_MARKER" ] &&
26
27
  { pkg install -y subfinder 2>/dev/null || apt install -y subfinder 2>/dev/null; }; then
27
28
  local bin; bin="$(command -v subfinder)"
28
- [ -n "$bin" ] && sha256sum "$bin" > "$_SUBFINDER_MARKER" 2>/dev/null
29
+ [ -n "$bin" ] && { mkdir -p "$(dirname "$_SUBFINDER_MARKER")" && printf '%s\n' 'pkg:subfinder' >"$_SUBFINDER_MARKER"; }
29
30
  log_success "subfinder instalado"
30
31
  return 0
31
32
  fi
@@ -65,7 +66,10 @@ install_subfinder() (
65
66
 
66
67
  uninstall_subfinder() {
67
68
  log_info "Removendo subfinder..."
68
- if [ -f "$_SUBFINDER_MARKER" ]; then
69
+ if _subfinder_package_owned; then
70
+ pkg uninstall -y subfinder 2>/dev/null || apt remove -y subfinder 2>/dev/null || return 1
71
+ rm -f "$_SUBFINDER_MARKER"
72
+ elif [ -f "$_SUBFINDER_MARKER" ]; then
69
73
  [ "$(sha256sum "$PREFIX/bin/subfinder" 2>/dev/null)" = "$(<"$_SUBFINDER_MARKER")" ] && rm -f "$PREFIX/bin/subfinder"
70
74
  rm -f "$_SUBFINDER_MARKER"
71
75
  fi
@@ -3,6 +3,8 @@
3
3
  _ZAP_DIR="$PREFIX/share/zap"
4
4
  _ZAP_VERSION="2.16.1"
5
5
  _ZAP_SHA256="5b2eb8319b085121a6e8ad50d69d67dbef8c867166f71a937bfc888d247a2ac1"
6
+ _ZAP_PACKAGE_MARKER="$PREFIX/share/karnel-installers/zaproxy"
7
+ _zap_package_owned() { [[ -f "$_ZAP_PACKAGE_MARKER" && "$(<"$_ZAP_PACKAGE_MARKER")" == 'pkg:zaproxy' ]]; }
6
8
 
7
9
  _zap_owned() {
8
10
  installer_file_owned "$PREFIX/bin/zap" "$_ZAP_DIR/.karnel-wrapper"
@@ -10,7 +12,7 @@ _zap_owned() {
10
12
 
11
13
  install_zap() (
12
14
  if command -v zap &>/dev/null; then
13
- if ! _zap_owned; then
15
+ if ! _zap_owned && ! _zap_package_owned; then
14
16
  log_info "zap já está instalado"
15
17
  return 2
16
18
  fi
@@ -19,6 +21,7 @@ install_zap() (
19
21
 
20
22
  if [ ! -f "$_ZAP_DIR/.karnel-wrapper" ] &&
21
23
  { pkg install -y zaproxy 2>/dev/null || apt install -y zaproxy 2>/dev/null; }; then
24
+ mkdir -p "$(dirname "$_ZAP_PACKAGE_MARKER")" && printf '%s\n' 'pkg:zaproxy' >"$_ZAP_PACKAGE_MARKER" || return 1
22
25
  log_success "zap instalado"
23
26
  return 0
24
27
  fi
@@ -102,7 +105,10 @@ SCRIPT
102
105
 
103
106
  uninstall_zap() {
104
107
  log_info "Removendo ZAP..."
105
- if [ -f "$_ZAP_DIR/.karnel-wrapper" ]; then
108
+ if _zap_package_owned; then
109
+ pkg uninstall -y zaproxy 2>/dev/null || apt remove -y zaproxy 2>/dev/null || return 1
110
+ rm -f "$_ZAP_PACKAGE_MARKER"
111
+ elif [ -f "$_ZAP_DIR/.karnel-wrapper" ]; then
106
112
  [ "$(sha256sum "$PREFIX/bin/zap" 2>/dev/null)" = "$(<"$_ZAP_DIR/.karnel-wrapper")" ] && rm -f "$PREFIX/bin/zap"
107
113
  rm -rf "$_ZAP_DIR"
108
114
  fi
@@ -12,6 +12,40 @@ fi
12
12
 
13
13
  : "${HOME:?HOME is unset — cannot determine config paths}"
14
14
 
15
+ # Karnel-managed commands are installed in $PREFIX/bin. Keep that directory
16
+ # ahead of user-local binaries so an obsolete external install cannot shadow
17
+ # an update that Karnel just completed, while preserving explicit PATH
18
+ # overrides that appear before both directories.
19
+ _karnel_prefer_prefix_bin() {
20
+ [[ -n "${PREFIX:-}" ]] || return 0
21
+
22
+ local prefix_bin="$PREFIX/bin" local_bin="$HOME/.local/bin"
23
+ local -a entries=() reordered=()
24
+ local prefix_index=-1 local_index=-1 index=0 entry joined="" inserted=0
25
+ IFS=: read -r -a entries <<< "${PATH:-}"
26
+ for entry in "${entries[@]}"; do
27
+ [[ "$entry" == "$prefix_bin" && $prefix_index -lt 0 ]] && prefix_index=$index
28
+ [[ "$entry" == "$local_bin" && $local_index -lt 0 ]] && local_index=$index
29
+ ((index += 1))
30
+ done
31
+ (( prefix_index > local_index && local_index >= 0 )) || return 0
32
+
33
+ for entry in "${entries[@]}"; do
34
+ [[ "$entry" == "$prefix_bin" ]] && continue
35
+ if [[ "$entry" == "$local_bin" && $inserted -eq 0 ]]; then
36
+ reordered+=("$prefix_bin")
37
+ inserted=1
38
+ fi
39
+ reordered+=("$entry")
40
+ done
41
+ for entry in "${reordered[@]}"; do
42
+ joined+="${joined:+:}$entry"
43
+ done
44
+ export PATH="$joined"
45
+ }
46
+ _karnel_prefer_prefix_bin
47
+ unset -f _karnel_prefer_prefix_bin
48
+
15
49
  # configuración
16
50
  KARNEL_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/karnel"
17
51
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karnel-termux",
3
- "version": "4.17.34",
3
+ "version": "4.17.36",
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"
@@ -39,8 +39,7 @@
39
39
  ],
40
40
  "author": "israel marques",
41
41
  "contributors": [
42
- "israel marques",
43
- "devcorex"
42
+ "israel marques"
44
43
  ],
45
44
  "license": "MIT",
46
45
  "bugs": {