karnel-termux 4.17.13 → 4.17.19

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.
Files changed (61) hide show
  1. package/README.md +22 -21
  2. package/docs/ARCHITECTURE/index.md +12 -4
  3. package/docs/CHANGELOG.md +100 -1
  4. package/docs/_config.yml +1 -0
  5. package/docs/_layouts/base.html +1 -7
  6. package/docs/_layouts/default.html +43 -0
  7. package/docs/assets/css/style.scss +15 -49
  8. package/docs/cli/index.md +67 -8
  9. package/docs/index.md +10 -6
  10. package/docs/karnel/ai/index.md +2 -2
  11. package/docs/karnel/auto/index.md +2 -2
  12. package/docs/karnel/db/index.md +2 -2
  13. package/docs/karnel/deploy/index.md +2 -2
  14. package/docs/karnel/dev/index.md +3 -3
  15. package/docs/karnel/editor/index.md +2 -2
  16. package/docs/karnel/games/index.md +2 -2
  17. package/docs/karnel/lang/index.md +2 -2
  18. package/docs/karnel/network/index.md +2 -2
  19. package/docs/karnel/npm/index.md +2 -2
  20. package/docs/karnel/osint/index.md +2 -2
  21. package/docs/karnel/plugin/index.md +2 -2
  22. package/docs/karnel/security/index.md +3 -3
  23. package/docs/karnel/shell/index.md +2 -2
  24. package/docs/karnel/ui/index.md +2 -2
  25. package/docs/karnel/utils/index.md +2 -2
  26. package/docs/karnel/voice/index.md +2 -2
  27. package/docs/troubleshooting/index.md +4 -2
  28. package/karnel/RELEASE_COMMIT +1 -1
  29. package/karnel/cli/commands/backup.sh +2 -2
  30. package/karnel/cli/commands/brain.sh +4 -4
  31. package/karnel/cli/commands/doctor/code_exec.sh +5 -0
  32. package/karnel/cli/commands/env.sh +6 -0
  33. package/karnel/cli/commands/ia.sh +6 -2
  34. package/karnel/cli/commands/init.sh +2 -2
  35. package/karnel/cli/commands/list.sh +1 -0
  36. package/karnel/cli/commands/open.sh +4 -0
  37. package/karnel/cli/commands/pg.sh +1 -1
  38. package/karnel/cli/commands/restore.sh +3 -3
  39. package/karnel/cli/commands/voice.sh +3 -3
  40. package/karnel/modules/shell.sh +3 -1
  41. package/karnel/tools/ai/cactus/install.sh +1 -1
  42. package/karnel/tools/ai/cline/install.sh +54 -6
  43. package/karnel/tools/ai/crush/install.sh +1 -1
  44. package/karnel/tools/ai/droid/install.sh +10 -10
  45. package/karnel/tools/ai/keelcode/install.sh +54 -6
  46. package/karnel/tools/ai/kilocode-cli/install.sh +54 -6
  47. package/karnel/tools/ai/kimchi-code/install.sh +16 -14
  48. package/karnel/tools/ai/kiro/install.sh +54 -6
  49. package/karnel/tools/ai/oh-my-pi/install.sh +14 -14
  50. package/karnel/tools/deploy/supabase/install.sh +54 -6
  51. package/karnel/tools/lang/bun/install.sh +6 -6
  52. package/karnel/tools/utils/applaunch/applaunch.py +18 -14
  53. package/karnel/tools/utils/passman/passman.py +20 -1
  54. package/karnel/tools/utils/splash/splash.py +10 -2
  55. package/karnel/tools/utils/treex/treex.py +4 -0
  56. package/karnel/tools/utils/zork/install.sh +2 -7
  57. package/karnel/tools/utils/zork/zork.sh +29 -5
  58. package/karnel/utils/agent_actions.sh +40 -16
  59. package/karnel/utils/agent_llm.sh +9 -9
  60. package/karnel/utils/tools.sh +6 -0
  61. package/package.json +1 -1
@@ -11,7 +11,7 @@ Deploy CLIs (Railway, Netlify, Vercel, Supabase).
11
11
 
12
12
  | `deploy` | `--vercel`, `--railway`, `--netlify`, `--supabase` |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#deploy) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#deploy) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/deploy.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -6,12 +6,12 @@ layout: base
6
6
 
7
7
  # Dev module
8
8
 
9
- General development utilities (fzf, bat, make, proot-distro, tmux, and more).
9
+ General development utilities (fzf, bat, make, proot, tmux, and more).
10
10
  ## Install
11
11
 
12
12
  | `dev` | `--gh`, `--wget`, `--curl`, `--lsd`, `--bat`, `--proot`, `--ncurses`, `--tmate`, `--openssh`, `--tmux`, `--cloudflared`, `--translate`, `--html2text`, `--jq`, `--bc`, `--tree`, `--fzf`, `--imagemagick`, `--shfmt`, `--make`, `--udocker`, `--snyk` |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#dev) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#dev) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/dev.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ Terminal and browser-based editors (code-server, Neovim, and more).
11
11
 
12
12
  | `editor` | `--code-server`, `--neovim`, `--nvchad` |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#editor) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#editor) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/editor.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ Terminal games to relax between sessions.
11
11
 
12
12
  | `games` | `--buzz`, `--ctfgod`, `--detective`, `--pet-friends`, `--tamagotchi`, `--arcade` |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#games) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#games) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/games.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ Programming-language runtimes (Python, Node.js, Rust, Go, and more).
11
11
 
12
12
  | `lang` | `--bun`, `--nodejs`, `--python`, `--perl`, `--php`, `--rust`, `--clang`, `--golang` |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#lang) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#lang) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/lang.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ Network utilities (dark, dedsec-network).
11
11
 
12
12
  | `network` | `--dark`, `--dedsec-network` |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#network) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#network) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/network.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ Node.js packages and JavaScript tooling.
11
11
 
12
12
  | `npm` | `--typescript`, `--nestjs`, `--prettier`, `--live-server`, `--localtunnel`, `--vercel`, `--markserv`, `--psqlformat`, `--ncu`, `--ngrok`, `--turbopack` |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#npm) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#npm) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/npm.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ OSINT tooling, centered on Robin.
11
11
 
12
12
  | `osint` | Robin OSINT |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#osint) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#osint) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/osint.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ The plugin system and manager.
11
11
 
12
12
  | `plugin` | Plugin system |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#plugin) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#plugin) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/plugin.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -6,12 +6,12 @@ layout: base
6
6
 
7
7
  # Security module
8
8
 
9
- Security and pentest tooling (30+ tools).
9
+ Security and pentest tooling (30 tools).
10
10
  ## Install
11
11
 
12
12
  | `security` | Security tools |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#security) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#security) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/security.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ Shell enhancements (ZSH, Oh My Zsh, zoxide).
11
11
 
12
12
  | `shell` | `--powerlevel10k`, `--zsh-defer`, `--zsh-autosuggestions`, `--zsh-syntax-highlighting`, `--history-substring`, `--zsh-completions`, `--fzf-tab`, `--you-should-use`, `--zsh-autopair`, `--better-npm` |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#shell) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#shell) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/shell.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ Termux UI components.
11
11
 
12
12
  | `ui` | `--font`, `--extra-keys`, `--cursor`, `--banner` |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#ui) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#ui) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/ui.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -15,7 +15,7 @@ and tracked with Karnel ownership markers so `karnel uninstall utils --herdr` is
15
15
 
16
16
  | `utils` | `--fconv`, `--filecheck`, `--websites`, `--notes`, `--treex`, `--passman`, `--applaunch`, `--splash`, `--httptmux`, `--zork`, `--qrcode`, `--superfile`, `--herdr` |
17
17
 
18
- See the [CLI reference]({ '/cli/' | relative_url }#utils) for the full command list, or the
18
+ See the [CLI reference]({{ '/cli/' | relative_url }}#utils) for the full command list, or the
19
19
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/utils.sh).
20
20
 
21
- [← Back to docs]({ '/' | relative_url })
21
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -11,7 +11,7 @@ Voice commands for AI agents.
11
11
 
12
12
  | `voice` | Voice command |
13
13
 
14
- See the [CLI reference]({ '/cli/' | relative_url }#voice) for the full command list, or the
14
+ See the [CLI reference]({{ '/cli/' | relative_url }}#voice) for the full command list, or the
15
15
  [source on GitHub](https://github.com/israelmarques1024-dotcom/karnel-termux/tree/main/karnel/modules/voice.sh).
16
16
 
17
- [← Back to docs]({ '/' | relative_url })
17
+ [← Back to docs]({{ '/' | relative_url }}) · [CLI reference]({{ '/cli/' | relative_url }})
@@ -24,8 +24,10 @@ npm/pnpm installs.
24
24
  | `All update methods failed` | Every fallback failed. Check network, the Git checkout state, and npm connectivity. |
25
25
  | Update stays on the same version | Old releases (`v4.13.3`, `v4.13.4`) do not ship installer assets, so the curl path falls back to git. A release that includes the installer assets enables the verified curl path. |
26
26
 
27
- Logs: `$KARNEL_CACHE/install_dev.log` (GitHub/installer) and
28
- `$KARNEL_CACHE/install_npm.log` (npm).
27
+ The updater prints its progress to the terminal only; it does not write log
28
+ files. For module installs, `karnel install dev` logs to
29
+ `$KARNEL_CACHE/install_dev.log` and `karnel install npm` logs to
30
+ `$KARNEL_CACHE/install_npm.log`.
29
31
 
30
32
  ## npm publishing
31
33
 
@@ -1 +1 @@
1
- 3d9d862c0be40df2c3f17648f56bf83ef74507b7
1
+ 1eb16a5898d6f323ed664668b96bf8eff18348cd
@@ -61,7 +61,7 @@ backup_run() {
61
61
  echo
62
62
 
63
63
  local tmp archive_tmp checksum_tmp
64
- tmp=$(mktemp -d) || { _backup_release_output; return 1; }
64
+ tmp=$(mktemp -d "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX") || { _backup_release_output; return 1; }
65
65
  archive_tmp="$BACKUP_DIR/.$(basename "$file").$$.tmp"
66
66
  checksum_tmp="$archive_tmp.sha256"
67
67
  if ! _backup_collect_payload "$tmp"; then
@@ -130,7 +130,7 @@ backup_snapshot() {
130
130
  echo
131
131
 
132
132
  local tmp archive_tmp checksum_tmp checksum
133
- tmp=$(mktemp -d) || { _backup_release_output; return 1; }
133
+ tmp=$(mktemp -d "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX") || { _backup_release_output; return 1; }
134
134
  archive_tmp="$BACKUP_DIR/.$(basename "$file").$$.tmp"
135
135
  checksum_tmp="$archive_tmp.sha256"
136
136
  if ! _backup_collect_payload "$tmp" ||
@@ -142,7 +142,7 @@ _brain_update_related() {
142
142
  if grep -q "^related:" "$tmp" 2>/dev/null; then
143
143
  sed -i "s/^related: \[\(.*\)\]/related: [\1, $escaped]/" "$tmp"
144
144
  else
145
- sed -i "/^---$/a related: [$slug]" "$tmp"
145
+ sed -i "/^---$/a related: [$escaped]" "$tmp"
146
146
  fi
147
147
  tail -n +$((frontmatter_end)) "$file" >>"$tmp"
148
148
  mv "$tmp" "$file"
@@ -230,7 +230,7 @@ _brain_editor() {
230
230
  fi
231
231
 
232
232
  local tmpfile
233
- tmpfile=$(mktemp)
233
+ tmpfile=$(mktemp "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX")
234
234
 
235
235
  echo "# $title" >"$tmpfile"
236
236
  echo >>"$tmpfile"
@@ -1466,7 +1466,7 @@ EOF
1466
1466
 
1467
1467
  if command -v jq &>/dev/null; then
1468
1468
  local temp
1469
- temp=$(mktemp)
1469
+ temp=$(mktemp "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX")
1470
1470
  if [[ "$val" == "true" ]] || [[ "$val" == "false" ]]; then
1471
1471
  jq --argjson v "$val" ".${key} = \$v" "$config_file" > "$temp" && mv "$temp" "$config_file"
1472
1472
  elif [[ "$val" =~ ^[0-9]+$ ]]; then
@@ -1635,7 +1635,7 @@ EOF
1635
1635
  echo
1636
1636
 
1637
1637
  local ai_response_temp
1638
- ai_response_temp=$(mktemp)
1638
+ ai_response_temp=$(mktemp "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX")
1639
1639
 
1640
1640
  if loading "Generating AI response" _run_ai_query "$ai_cmd" "$full_prompt" "$default_model" "$ai_response_temp"; then
1641
1641
  echo
@@ -115,6 +115,11 @@ _exec_apply_fix() {
115
115
  local tool="$1" fix_cmd="$2" lang="$3" file="$4" dir="${5:-$PWD}"
116
116
  local full_cmd; full_cmd="$(_tool_command "$fix_cmd" "$file")"
117
117
 
118
+ # NOTE: fix/check commands come exclusively from the in-repo LANG_TOOLS
119
+ # registry (code_langs.sh); some legitimate fixes are multi-statement
120
+ # loops (e.g. Go gofmt) or contain pipes, so pattern-based "injection"
121
+ # guards here would refuse valid commands. Do not re-add one.
122
+
118
123
  if [[ "$fix_cmd" == *'{}'* && -z "$file" ]]; then
119
124
  log_warn "Cannot fix — no matching file found for $tool"
120
125
  return 1
@@ -86,6 +86,12 @@ env_set() {
86
86
 
87
87
  printf 'export %s=%q\n' "$key" "$value" >>"$rc_file"
88
88
 
89
+ # Secrets stored in a shell rc are world-readable by default; tighten the
90
+ # file's permissions so other local users cannot read them.
91
+ if [[ "$key" =~ (SECRET|TOKEN|KEY|PASSWORD|PASSWD|API_|ACCESS|PRIVATE|CREDENTIAL) ]]; then
92
+ chmod go-rwx "$rc_file" 2>/dev/null || true
93
+ fi
94
+
89
95
  echo
90
96
  log_success "Variable ${D_CYAN}${key}${D_GREEN} set in ${D_NC}$(basename "$rc_file")"
91
97
  list_item "Run: ${D_CYAN}source $(basename "$rc_file")${D_NC} to apply, or restart your terminal"
@@ -22,7 +22,6 @@ ia_help() {
22
22
  separator_section "Examples"
23
23
  echo
24
24
  printf " ${D_CYAN}karnel ia sessions${NC} # Show all AI sessions\n"
25
- printf " ${D_CYAN}karnel ia sessions --all${NC} # Include agent names\n"
26
25
  printf " ${D_CYAN}karnel ia install omni-route${NC} # Install omniRoute\n"
27
26
  printf " ${D_CYAN}karnel ia routes${NC} # Show AI CLI routes\n"
28
27
  printf " ${D_CYAN}karnel list ai${NC} # List installed AI tools\n"
@@ -31,7 +30,12 @@ ia_help() {
31
30
 
32
31
  # List all AI sessions from known tools
33
32
  ia_sessions() {
33
+ # $1 was historically `--all`; agent names are always shown now, so the
34
+ # flag is accepted for back-compat and ignored.
34
35
  local show_all="${1:-0}"
36
+ if [[ "$show_all" == "--all" ]]; then
37
+ show_all=0
38
+ fi
35
39
 
36
40
  mkdir -p "$IA_SESSIONS_DIR"
37
41
 
@@ -407,7 +411,7 @@ PY
407
411
  # Persist all discovered sessions to IA_SESSIONS_DIR for history
408
412
  local persist_file="$IA_SESSIONS_DIR/.all_sessions.json"
409
413
  local tmp_persist
410
- tmp_persist=$(mktemp)
414
+ tmp_persist=$(mktemp "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX")
411
415
  echo "[" > "$tmp_persist"
412
416
  local first=1
413
417
  for session in "${sessions[@]}"; do
@@ -132,7 +132,7 @@ EOF
132
132
  log_warn "jq not found — skipping package.json update"
133
133
  else
134
134
  local temp
135
- temp=$(mktemp)
135
+ temp=$(mktemp "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX")
136
136
  jq '.scripts.dev = "next dev --webpack" | .scripts.build = "next build --webpack" | .scripts.start = "next start"' package.json > "$temp" && mv "$temp" package.json
137
137
  log_success "Added --webpack flag to dev and build scripts"
138
138
  fi
@@ -533,7 +533,7 @@ EOF
533
533
  log_warn "jq not found — skipping package.json update"
534
534
  else
535
535
  local temp
536
- temp=$(mktemp)
536
+ temp=$(mktemp "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX")
537
537
  jq '.scripts += {
538
538
  "dev": "ts-node-dev --require tsconfig-paths/register --env-file=.env --respawn src/index.ts",
539
539
  "build": "tsc && tsc-alias -p tsconfig.json",
@@ -461,6 +461,7 @@ _list_utils() {
461
461
  table_row "Zork (text adventure)" "--zork" "zork" "$(_check_cmd "zork")"
462
462
  table_row "QR Code Generator" "--qrcode" "qrcode" "$(_check_cmd "qrcode")"
463
463
  table_row "SuperFile" "--superfile" "spf" "$(_check_cmd "spf")"
464
+ table_row "Herdr (AI assistant)" "--herdr" "herdr" "$(_check_cmd "herdr")"
464
465
  table_end
465
466
 
466
467
  echo
@@ -21,6 +21,9 @@ open_main() {
21
21
  herdr)
22
22
  url="$OPEN_DOCS/karnel/utils"
23
23
  ;;
24
+ robin)
25
+ url="$OPEN_DOCS/karnel/osint"
26
+ ;;
24
27
  supabase)
25
28
  url="$OPEN_DOCS/karnel/deploy"
26
29
  ;;
@@ -95,6 +98,7 @@ open_help() {
95
98
  printf " ${D_GREEN}%-14s${NC} ${D_DIM}%s${NC}\n" "utils" "Utility tools"
96
99
  printf " ${D_GREEN}%-14s${NC} ${D_DIM}%s${NC}\n" "voice" "Voice command"
97
100
  printf " ${D_GREEN}%-14s${NC} ${D_DIM}%s${NC}\n" "osint" "OSINT tools"
101
+ printf " ${D_GREEN}%-14s${NC} ${D_DIM}%s${NC}\n" "robin" "Robin OSINT service"
98
102
  printf " ${D_GREEN}%-14s${NC} ${D_DIM}%s${NC}\n" "plugin" "Plugin system"
99
103
  printf " ${D_GREEN}%-14s${NC} ${D_DIM}%s${NC}\n" "security" "Security tools"
100
104
  printf " ${D_GREEN}%-14s${NC} ${D_DIM}%s${NC}\n" "herdr" "Herdr terminal AI assistant"
@@ -466,7 +466,7 @@ _run_restore_cmd() {
466
466
  local file_path="$2"
467
467
  local _rs_ret=0
468
468
  set -o pipefail
469
- gunzip -c "$file_path" | pg_restore -d "$db_name" -c 2>/dev/null || _rs_ret=$?
469
+ gunzip -c "$file_path" | pg_restore -d "$db_name" -c 2>>"${KARNEL_CACHE:-$HOME/.cache/karnel}/karnel-pg.log" || _rs_ret=$?
470
470
  set +o pipefail
471
471
  return $_rs_ret
472
472
  }
@@ -114,10 +114,10 @@ restore_main() {
114
114
  log_success "Checksum verified"
115
115
 
116
116
  local tmp transaction
117
- tmp=$(mktemp -d) || return 1
118
- if ! tar -xzf "$file" -C "$tmp" --no-same-owner --no-same-permissions 2>/dev/null; then
117
+ tmp=$(mktemp -d "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX") || return 1
118
+ if ! tar -xzf "$file" -C "$tmp" --no-same-owner --no-same-permissions 2>"$tmp/extract.err"; then
119
+ log_error "Failed to extract backup: $(cat "$tmp/extract.err" 2>/dev/null)"
119
120
  rm -rf "$tmp"
120
- log_error "Failed to extract backup"
121
121
  return 1
122
122
  fi
123
123
  local pkgs="$tmp/metadata/packages.list"
@@ -47,7 +47,7 @@ voice_help() {
47
47
  echo
48
48
  list_item "Termux:API package: ${D_CYAN}pkg install termux-api${NC}"
49
49
  list_item "${EDITOR:-nano} editor: ${D_CYAN}karnel install editor${NC}"
50
- list_item "Termux:API app: ${D_CYAN}https://karneltermux.vercel.app/termux/api${NC}"
50
+ list_item "Termux:API app: ${D_CYAN}https://github.com/termux/termux-api${NC}"
51
51
  echo
52
52
  }
53
53
 
@@ -101,7 +101,7 @@ voice_main() {
101
101
  else
102
102
  log_error "Termux:API is not installed"
103
103
  list_item "Install the package: ${D_CYAN}pkg install termux-api${NC}"
104
- list_item "Install the app: https://karneltermux.vercel.app/termux/api"
104
+ list_item "Install the app: https://github.com/termux/termux-api"
105
105
  separator
106
106
  return 1
107
107
  fi
@@ -151,7 +151,7 @@ voice_main() {
151
151
  local prompt="$raw"
152
152
  if [[ "$skip_edit" == "false" ]] && [[ -t 0 ]] && [[ -t 1 ]]; then
153
153
  local tmpfile
154
- tmpfile="$(mktemp)"
154
+ tmpfile="$(mktemp "${TMPDIR:-${KARNEL_CACHE:-$HOME/.cache/karnel}}/karnel-XXXXXX")"
155
155
  echo "$raw" >"$tmpfile"
156
156
  $is_text || log_info "Review the prompt in ${EDITOR:-nano}, fix mistakes, then save and quit"
157
157
  ${EDITOR:-nano} "$tmpfile" </dev/tty >/dev/tty || true
@@ -43,7 +43,9 @@ install_oh_my_zsh() (
43
43
 
44
44
  if curl -fsSL "https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/$OH_MY_ZSH_REF/tools/install.sh" -o "$temp_file" &>>"$LOG_FILE"; then
45
45
  # Keep the reviewed installer behavior, but fetch and check out the reviewed commit.
46
- sed -i "s|git fetch --depth=1 origin|git fetch --depth=1 origin $OH_MY_ZSH_REF|" "$temp_file"
46
+ local omz_ref_esc
47
+ omz_ref_esc=$(printf '%s\n' "$OH_MY_ZSH_REF" | sed 's/[][\/.&*?^$|]/\\&/g')
48
+ sed -i "s|git fetch --depth=1 origin|git fetch --depth=1 origin $omz_ref_esc|" "$temp_file"
47
49
  # shellcheck disable=SC2016
48
50
  sed -i 's|git checkout -b "$BRANCH" "origin/$BRANCH"|git checkout --detach FETCH_HEAD|' "$temp_file"
49
51
  if ! grep -qF "git fetch --depth=1 origin $OH_MY_ZSH_REF" "$temp_file" ||
@@ -285,7 +285,7 @@ _cactus_cli_post_install_glibc() {
285
285
  fi
286
286
  mkdir -p "$PREFIX/libexec"
287
287
  cp "$launcher_src" "$launcher_dst"
288
- chmod 644 "$launcher_dst"
288
+ chmod 755 "$launcher_dst"
289
289
 
290
290
  if ! command -v patchelf &>/dev/null; then
291
291
  if ! yes | pkg install patchelf &>>"$CACTUS_CLI_LOG_FILE"; then
@@ -4,13 +4,61 @@ import "@/utils/log"
4
4
  import "@/utils/version"
5
5
  import "@/utils/colors"
6
6
  import "@/utils/install"
7
+ # Safe, self-contained tar extractor (independent of framework import).
8
+ # Rejects path traversal, absolute paths, unsafe symlinks/hardlinks, and
9
+ # device/special-file entries. Intentionally has NO unsafe fallback.
10
+ _archive_member_is_safe() {
11
+ local member="$1"
12
+ [[ -n "$member" && "$member" != /* && "$member" != *\\* ]] || return 1
13
+ case "/$member/" in
14
+ */../*) return 1 ;;
15
+ esac
16
+ }
17
+
18
+ _archive_link_is_safe() {
19
+ local member="$1" target="$2" part depth=0
20
+ local -a _archive_parts
21
+ [[ -n "$target" && "$target" != /* && "$target" != *\\* ]] || return 1
22
+ IFS=/ read -r -a _archive_parts <<<"$(dirname "$member")/$target"
23
+ for part in "${_archive_parts[@]}"; do
24
+ case "$part" in
25
+ ''|.) ;;
26
+ ..) ((depth > 0)) || return 1; ((depth -= 1)) ;;
27
+ *) ((depth += 1)) ;;
28
+ esac
29
+ done
30
+ }
31
+
32
+ safe_extract_tar() {
33
+ local archive="$1" outdir="$2" strip_components="${3:-0}"
34
+ local member listing verbose mode line target
35
+ listing=$(tar -tf "$archive" 2>/dev/null) || return 1
36
+ while IFS= read -r member; do
37
+ _archive_member_is_safe "$member" || return 1
38
+ done <<<"$listing"
39
+ verbose=$(tar -tvf "$archive" 2>/dev/null) || return 1
40
+ while IFS= read -r line; do
41
+ mode=${line%% *}
42
+ case "${mode:0:1}" in
43
+ l)
44
+ member=${line%% -> *}; member=${member##* }
45
+ target=${line#* -> }
46
+ _archive_link_is_safe "$member" "$target" || return 1
47
+ ;;
48
+ h)
49
+ member=${line%% link to *}; member=${member##* }
50
+ target=${line#* link to }
51
+ _archive_link_is_safe "$member" "$target" || return 1
52
+ ;;
53
+ b|c|p) return 1 ;;
54
+ esac
55
+ done <<<"$verbose"
56
+ mkdir -p "$outdir" || return 1
57
+ tar -xf "$archive" -C "$outdir" --strip-components="$strip_components" \
58
+ --no-same-owner --no-same-permissions
59
+ }
60
+
7
61
 
8
- if ! declare -f safe_extract_tar >/dev/null 2>&1; then
9
- safe_extract_tar() {
10
- local archive="$1" outdir="$2" strip_components="${3:-0}"
11
- tar -xzf "$archive" -C "$outdir" --strip-components="$strip_components"
12
- }
13
- fi
14
62
 
15
63
  : "${KARNEL_DATA:=${XDG_DATA_HOME:-$HOME/.local/share}/karnel-data}"
16
64
  : "${KARNEL_CACHE:=${XDG_CACHE_HOME:-$HOME/.cache}/karnel}"
@@ -47,7 +47,7 @@ install_crush() {
47
47
  log_info "Downloading Crush v${CRUSH_VERSION} for Android arm64..."
48
48
 
49
49
  local tmpdir
50
- tmpdir=$(mktemp -d)
50
+ tmpdir=$(mktemp -d "${KARNEL_CACHE:-${TMPDIR:-$HOME/.cache/karnel}}/karnel-crush.XXXXXX" 2>/dev/null) || tmpdir=$(mktemp -d) || return 1
51
51
  if curl -fsSL --connect-timeout 15 --max-time 120 "$url" -o "$tmpdir/$tarball" 2>>"$LOG_FILE"; then
52
52
  if verify_github_release_asset charmbracelet/crush "v${CRUSH_VERSION}" "$tarball" "$tmpdir/$tarball" &&
53
53
  extract_tarball "$tmpdir/$tarball" "$tmpdir"; then
@@ -256,13 +256,13 @@ _droid_ubuntu_install_bin() {
256
256
  return 1
257
257
  fi
258
258
  _droid_proot_ubuntu /bin/bash -c '
259
- mkdir -p /tmp/droid-install &&
260
- curl -fsSL "$1" -o /tmp/droid-install/droid &&
261
- { [ -z "$2" ] || [ "$(sha256sum /tmp/droid-install/droid | awk "{print \$1}")" = "$2" ]; } &&
259
+ d=$(mktemp -d) &&
260
+ curl -fsSL "$1" -o "$d/droid" &&
261
+ { [ -z "$2" ] || [ "$(sha256sum "$d/droid" | awk "{print \$1}")" = "$2" ]; } &&
262
262
  mkdir -p /usr/local/bin &&
263
- mv /tmp/droid-install/droid /usr/local/bin/droid &&
263
+ mv "$d/droid" /usr/local/bin/droid &&
264
264
  chmod +x /usr/local/bin/droid &&
265
- rm -rf /tmp/droid-install
265
+ rm -rf "$d"
266
266
  ' bash "$binary_url" "$expected" &>>"$LOG_FILE"
267
267
 
268
268
  local droid_bin="$(_droid_detect_ubuntu_root)/usr/local/bin/droid"
@@ -438,12 +438,12 @@ _update_droid_proot_impl() {
438
438
  fi
439
439
  _droid_proot_ubuntu /bin/bash -c '
440
440
  rm -f /usr/local/bin/droid &&
441
- mkdir -p /tmp/droid-update &&
442
- curl -fsSL "$1" -o /tmp/droid-update/droid &&
443
- { [ -z "$2" ] || [ "$(sha256sum /tmp/droid-update/droid | awk "{print \$1}")" = "$2" ]; } &&
444
- mv /tmp/droid-update/droid /usr/local/bin/droid &&
441
+ d=$(mktemp -d) &&
442
+ curl -fsSL "$1" -o "$d/droid" &&
443
+ { [ -z "$2" ] || [ "$(sha256sum "$d/droid" | awk "{print \$1}")" = "$2" ]; } &&
444
+ mv "$d/droid" /usr/local/bin/droid &&
445
445
  chmod +x /usr/local/bin/droid &&
446
- rm -rf /tmp/droid-update
446
+ rm -rf "$d"
447
447
  ' bash "$binary_url" "$expected" &>>"$LOG_FILE"
448
448
 
449
449
  local ubuntu_root
@@ -3,13 +3,61 @@
3
3
  import "@/utils/log"
4
4
  import "@/utils/version"
5
5
  import "@/utils/install"
6
+ # Safe, self-contained tar extractor (independent of framework import).
7
+ # Rejects path traversal, absolute paths, unsafe symlinks/hardlinks, and
8
+ # device/special-file entries. Intentionally has NO unsafe fallback.
9
+ _archive_member_is_safe() {
10
+ local member="$1"
11
+ [[ -n "$member" && "$member" != /* && "$member" != *\\* ]] || return 1
12
+ case "/$member/" in
13
+ */../*) return 1 ;;
14
+ esac
15
+ }
16
+
17
+ _archive_link_is_safe() {
18
+ local member="$1" target="$2" part depth=0
19
+ local -a _archive_parts
20
+ [[ -n "$target" && "$target" != /* && "$target" != *\\* ]] || return 1
21
+ IFS=/ read -r -a _archive_parts <<<"$(dirname "$member")/$target"
22
+ for part in "${_archive_parts[@]}"; do
23
+ case "$part" in
24
+ ''|.) ;;
25
+ ..) ((depth > 0)) || return 1; ((depth -= 1)) ;;
26
+ *) ((depth += 1)) ;;
27
+ esac
28
+ done
29
+ }
30
+
31
+ safe_extract_tar() {
32
+ local archive="$1" outdir="$2" strip_components="${3:-0}"
33
+ local member listing verbose mode line target
34
+ listing=$(tar -tf "$archive" 2>/dev/null) || return 1
35
+ while IFS= read -r member; do
36
+ _archive_member_is_safe "$member" || return 1
37
+ done <<<"$listing"
38
+ verbose=$(tar -tvf "$archive" 2>/dev/null) || return 1
39
+ while IFS= read -r line; do
40
+ mode=${line%% *}
41
+ case "${mode:0:1}" in
42
+ l)
43
+ member=${line%% -> *}; member=${member##* }
44
+ target=${line#* -> }
45
+ _archive_link_is_safe "$member" "$target" || return 1
46
+ ;;
47
+ h)
48
+ member=${line%% link to *}; member=${member##* }
49
+ target=${line#* link to }
50
+ _archive_link_is_safe "$member" "$target" || return 1
51
+ ;;
52
+ b|c|p) return 1 ;;
53
+ esac
54
+ done <<<"$verbose"
55
+ mkdir -p "$outdir" || return 1
56
+ tar -xf "$archive" -C "$outdir" --strip-components="$strip_components" \
57
+ --no-same-owner --no-same-permissions
58
+ }
59
+
6
60
 
7
- if ! declare -f safe_extract_tar >/dev/null 2>&1; then
8
- safe_extract_tar() {
9
- local archive="$1" outdir="$2" strip_components="${3:-0}"
10
- tar -xf "$archive" -C "$outdir" --strip-components="$strip_components"
11
- }
12
- fi
13
61
 
14
62
  KEELCODE_PACKAGE="@keelcode-ai/keelcode"
15
63
  : "${KARNEL_DATA:=${XDG_DATA_HOME:-$HOME/.local/share}/karnel-data}"