karnel-termux 4.7.7 → 4.8.0

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 (49) hide show
  1. package/README.md +39 -4
  2. package/karnel/cli/commands/backup.sh +8 -0
  3. package/karnel/cli/commands/doctor/system.sh +2 -0
  4. package/karnel/cli/commands/doctor.sh +8 -0
  5. package/karnel/cli/commands/install.sh +139 -84
  6. package/karnel/cli/commands/list.sh +32 -0
  7. package/karnel/cli/commands/open.sh +10 -6
  8. package/karnel/cli/commands/reinstall.sh +11 -0
  9. package/karnel/cli/commands/robin.sh +656 -0
  10. package/karnel/cli/commands/show.sh +1 -0
  11. package/karnel/cli/commands/start.sh +5 -0
  12. package/karnel/cli/commands/status.sh +11 -0
  13. package/karnel/cli/commands/uninstall.sh +9 -0
  14. package/karnel/cli/commands/update.sh +9 -0
  15. package/karnel/cli/commands/version.sh +2 -0
  16. package/karnel/cli/karnel.sh +35 -25
  17. package/karnel/modules/dev.sh +19 -46
  18. package/karnel/modules/osint.sh +123 -0
  19. package/karnel/tools/ai/crush/install.sh +1 -1
  20. package/karnel/tools/ai/omni-route/install.sh +1 -1
  21. package/karnel/tools/deploy/railway/install.sh +1 -1
  22. package/karnel/tools/dev/all.sh +45 -2
  23. package/karnel/tools/dev/fzf/install.sh +36 -9
  24. package/karnel/tools/npm/turbopack/install.sh +2 -0
  25. package/karnel/tools/osint/all.sh +65 -0
  26. package/karnel/tools/osint/robin/README.md +99 -0
  27. package/karnel/tools/osint/robin/common.sh +258 -0
  28. package/karnel/tools/osint/robin/install.sh +548 -0
  29. package/karnel/tools/osint/robin/requirements-termux.txt +33 -0
  30. package/karnel/utils/env.sh +16 -2
  31. package/karnel/utils/tools.sh +9 -2
  32. package/package.json +6 -1
  33. package/scripts/check-package.js +45 -0
  34. package/scripts/completion.bash +8 -3
  35. package/scripts/completion.zsh +8 -1
  36. package/karnel/tools/dev/applaunch/__pycache__/applaunch.cpython-314.pyc +0 -0
  37. package/karnel/tools/dev/fconv/__pycache__/fconv.cpython-314.pyc +0 -0
  38. package/karnel/tools/dev/filecheck/__pycache__/filecheck.cpython-314.pyc +0 -0
  39. package/karnel/tools/dev/notes/__pycache__/notes.cpython-314.pyc +0 -0
  40. package/karnel/tools/dev/passman/__pycache__/passman.cpython-314.pyc +0 -0
  41. package/karnel/tools/dev/splash/__pycache__/splash.cpython-314.pyc +0 -0
  42. package/karnel/tools/dev/websites/__pycache__/websites.cpython-314.pyc +0 -0
  43. package/karnel/tools/games/arcade/__pycache__/arcade.cpython-314.pyc +0 -0
  44. package/karnel/tools/games/buzz/__pycache__/buzz.cpython-314.pyc +0 -0
  45. package/karnel/tools/games/ctfgod/__pycache__/ctfgod.cpython-314.pyc +0 -0
  46. package/karnel/tools/games/detective/__pycache__/detective.cpython-314.pyc +0 -0
  47. package/karnel/tools/games/pet-friends/__pycache__/pet-friends.cpython-314.pyc +0 -0
  48. package/karnel/tools/games/tamagotchi/__pycache__/tamagotchi.cpython-314.pyc +0 -0
  49. package/karnel/tools/games/terminal-arcade/__pycache__/terminal-arcade.cpython-314.pyc +0 -0
@@ -0,0 +1,99 @@
1
+ # Robin OSINT
2
+
3
+ Robin is an independent, AI-assisted dark-web OSINT project. Karnel installs a
4
+ tested Robin release, Tor, native Termux scientific packages, and a local
5
+ Streamlit interface.
6
+
7
+ Upstream project: https://github.com/apurvsinghgautam/robin
8
+
9
+ ## Responsible Use
10
+
11
+ Use Robin only for lawful, authorized, and ethical research. Tor improves
12
+ connection privacy but does not guarantee anonymity. Robin automatically
13
+ retrieves web pages. Do not execute or open unknown files.
14
+
15
+ Queries, URLs, collected content, and summaries can be sent directly to the
16
+ configured LLM provider outside Tor. Third parties may process and retain that
17
+ data. Investigations are stored locally as plain JSON. Minimize personal data,
18
+ follow applicable laws and institutional policies, and independently verify AI
19
+ output before treating it as evidence.
20
+
21
+ The web interface is bound to `127.0.0.1`. Never expose port `8501` publicly.
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ karnel install osint --robin
27
+ karnel robin config
28
+ karnel robin doctor
29
+ karnel robin start
30
+ ```
31
+
32
+ Open `http://127.0.0.1:8501` after the health check succeeds.
33
+
34
+ For an intentional non-interactive first start:
35
+
36
+ ```bash
37
+ karnel robin start --accept-responsible-use
38
+ ```
39
+
40
+ ## Commands
41
+
42
+ | Command | Description |
43
+ | --- | --- |
44
+ | `karnel robin start` | Start Tor when needed and launch the local UI |
45
+ | `karnel robin stop` | Stop the managed Streamlit process |
46
+ | `karnel robin status` | Show installation, Tor, UI, config, and data status |
47
+ | `karnel robin config` | Show the protected configuration path and variables |
48
+ | `karnel robin doctor` | Run local dependency and service diagnostics |
49
+ | `karnel robin doctor --network` | Also verify an HTTP request through Tor |
50
+ | `karnel robin update` | Reconcile the installation with Karnel's pinned release |
51
+ | `karnel robin purge-data` | Permanently remove config and investigations after confirmation |
52
+
53
+ ## Data Locations
54
+
55
+ Karnel separates executable code from persistent user data:
56
+
57
+ | Data | Location |
58
+ | --- | --- |
59
+ | Upstream source | `$KARNEL_TOOLS/osint/robin/app` |
60
+ | Python environment | `$KARNEL_TOOLS/osint/robin/.venv` |
61
+ | Provider configuration | `$KARNEL_CONFIG/robin/.env` |
62
+ | Saved investigations | `$KARNEL_DATA/robin/investigations` |
63
+ | Runtime log | `$KARNEL_LOGS/robin.log` |
64
+ | Installation log | `$KARNEL_CACHE/install_osint.log` |
65
+
66
+ Uninstall and reinstall preserve configuration and investigations. API keys and
67
+ investigations are intentionally excluded from ordinary Karnel backups. Use
68
+ `karnel robin purge-data` only when permanent deletion is intended.
69
+
70
+ ## Provider Configuration
71
+
72
+ Supported variables include:
73
+
74
+ - `OPENAI_API_KEY`
75
+ - `ANTHROPIC_API_KEY`
76
+ - `GOOGLE_API_KEY`
77
+ - `OPENROUTER_API_KEY`
78
+ - `OPENROUTER_BASE_URL`
79
+ - `OLLAMA_BASE_URL`
80
+ - `LLAMA_CPP_BASE_URL`
81
+ - `CUSTOM_API_BASE_URL`
82
+ - `CUSTOM_API_KEY`
83
+ - `CUSTOM_API_MODEL`
84
+
85
+ Never commit or display secret values. Existing files are repaired to mode
86
+ `0600`; configuration directories use mode `0700`.
87
+
88
+ ## Troubleshooting
89
+
90
+ Run `karnel robin doctor`. The default doctor is local and does not call an LLM
91
+ or consume provider credits. `--network` performs a small request through Tor.
92
+
93
+ Streamlit can take up to one minute to become healthy on a mobile device. The
94
+ start command waits for the health endpoint instead of relying only on a PID.
95
+ Android may still stop background processes because of battery optimization or
96
+ phantom-process limits.
97
+
98
+ Robin is third-party software distributed under its upstream license. Karnel is
99
+ not affiliated with the upstream author or any LLM provider.
@@ -0,0 +1,258 @@
1
+ #!/usr/bin/env bash
2
+ # Public constants and layout state are consumed by separately imported modules.
3
+ # shellcheck disable=SC2034
4
+
5
+ ROBIN_REPO="https://github.com/apurvsinghgautam/robin.git"
6
+ ROBIN_DOCS_URL="https://github.com/apurvsinghgautam/robin"
7
+ ROBIN_VERSION="v2.8"
8
+ ROBIN_COMMIT="3c346fc6ba89034e71be38f3fa2912a633596435"
9
+ ROBIN_NOTICE_VERSION="2026-07-18.1"
10
+
11
+ ROBIN_ROOT="${ROBIN_ROOT:-$KARNEL_TOOLS/osint/robin}"
12
+ ROBIN_MANAGED_APP_DIR="$ROBIN_ROOT/app"
13
+ ROBIN_MANAGED_VENV_DIR="$ROBIN_ROOT/.venv"
14
+ ROBIN_CONFIG_DIR="${ROBIN_CONFIG_DIR:-$KARNEL_CONFIG/robin}"
15
+ ROBIN_ENV_FILE="$ROBIN_CONFIG_DIR/.env"
16
+ ROBIN_DATA_DIR="${ROBIN_DATA_DIR:-$KARNEL_DATA/robin}"
17
+ ROBIN_INVESTIGATIONS_DIR="$ROBIN_DATA_DIR/investigations"
18
+ ROBIN_PID_FILE="${ROBIN_PID_FILE:-$KARNEL_RUN/robin.pid}"
19
+ ROBIN_LOCK_DIR="${ROBIN_LOCK_DIR:-$KARNEL_RUN/robin.lock}"
20
+ ROBIN_LOG="${ROBIN_LOG:-$KARNEL_LOGS/robin.log}"
21
+ ROBIN_PORT="${ROBIN_PORT:-8501}"
22
+ ROBIN_START_TIMEOUT="${ROBIN_START_TIMEOUT:-60}"
23
+ ROBIN_PROC_ROOT="${ROBIN_PROC_ROOT:-/proc}"
24
+ ROBIN_ACK_FILE="$ROBIN_CONFIG_DIR/responsible-use"
25
+
26
+ _robin_refresh_layout() {
27
+ if [[ -d "$ROBIN_ROOT/.git" && ! -d "$ROBIN_MANAGED_APP_DIR/.git" ]]; then
28
+ ROBIN_LAYOUT="legacy"
29
+ ROBIN_APP_DIR="$ROBIN_ROOT"
30
+ ROBIN_VENV_DIR="$ROBIN_ROOT/.venv"
31
+ ROBIN_ACTIVE_ENV_FILE="$ROBIN_ROOT/.env"
32
+ ROBIN_ACTIVE_INVESTIGATIONS_DIR="$ROBIN_ROOT/investigations"
33
+ else
34
+ ROBIN_LAYOUT="managed"
35
+ ROBIN_APP_DIR="$ROBIN_MANAGED_APP_DIR"
36
+ ROBIN_VENV_DIR="$ROBIN_MANAGED_VENV_DIR"
37
+ ROBIN_ACTIVE_ENV_FILE="$ROBIN_ENV_FILE"
38
+ ROBIN_ACTIVE_INVESTIGATIONS_DIR="$ROBIN_INVESTIGATIONS_DIR"
39
+ fi
40
+ }
41
+
42
+ _robin_refresh_layout
43
+
44
+ _robin_is_installed() {
45
+ [[ -d "$ROBIN_APP_DIR/.git" && -x "$ROBIN_VENV_DIR/bin/python" ]]
46
+ }
47
+
48
+ _robin_python_path() {
49
+ if [[ -x "$ROBIN_VENV_DIR/bin/python" ]]; then
50
+ printf '%s\n' "$ROBIN_VENV_DIR/bin/python"
51
+ elif command -v python3 &>/dev/null; then
52
+ command -v python3
53
+ else
54
+ return 1
55
+ fi
56
+ }
57
+
58
+ _robin_socket_open() {
59
+ local host="$1"
60
+ local port="$2"
61
+ local python
62
+ python=$(_robin_python_path) || return 1
63
+
64
+ "$python" -c '
65
+ import socket
66
+ import sys
67
+
68
+ try:
69
+ with socket.create_connection((sys.argv[1], int(sys.argv[2])), timeout=1):
70
+ pass
71
+ except OSError:
72
+ raise SystemExit(1)
73
+ ' "$host" "$port" &>/dev/null
74
+ }
75
+
76
+ _robin_http_healthy() {
77
+ if command -v curl &>/dev/null; then
78
+ [[ "$(curl --fail --silent --show-error --max-time 2 \
79
+ "http://127.0.0.1:$ROBIN_PORT/_stcore/health" 2>/dev/null)" == "ok" ]]
80
+ return $?
81
+ fi
82
+
83
+ local python
84
+ python=$(_robin_python_path) || return 1
85
+ "$python" -c '
86
+ import sys
87
+ import urllib.request
88
+
89
+ try:
90
+ with urllib.request.urlopen(sys.argv[1], timeout=2) as response:
91
+ body = response.read().decode().strip()
92
+ except Exception:
93
+ raise SystemExit(1)
94
+ raise SystemExit(0 if body == "ok" else 1)
95
+ ' "http://127.0.0.1:$ROBIN_PORT/_stcore/health" &>/dev/null
96
+ }
97
+
98
+ _robin_proc_start_time() {
99
+ local pid="$1"
100
+ local -a stat_fields=()
101
+ [[ -r "$ROBIN_PROC_ROOT/$pid/stat" ]] || return 1
102
+ read -r -a stat_fields < "$ROBIN_PROC_ROOT/$pid/stat" || return 1
103
+ [[ ${#stat_fields[@]} -ge 22 ]] || return 1
104
+ [[ "${stat_fields[2]}" != "Z" && "${stat_fields[2]}" != "X" ]] || return 1
105
+ printf '%s\n' "${stat_fields[21]}"
106
+ }
107
+
108
+ _robin_process_matches() {
109
+ local pid="$1"
110
+ local recorded_start="${2:-}"
111
+ [[ "$pid" =~ ^[1-9][0-9]*$ ]] || return 1
112
+ kill -0 "$pid" 2>/dev/null || return 1
113
+
114
+ local current_start
115
+ current_start=$(_robin_proc_start_time "$pid") || return 1
116
+ if [[ -n "$recorded_start" && "$current_start" != "$recorded_start" ]]; then
117
+ return 1
118
+ fi
119
+
120
+ local cmdline=""
121
+ if [[ -r "$ROBIN_PROC_ROOT/$pid/cmdline" ]]; then
122
+ cmdline=$(tr '\0' ' ' < "$ROBIN_PROC_ROOT/$pid/cmdline")
123
+ fi
124
+ [[ "$cmdline" == *"streamlit"* && "$cmdline" == *"ui.py"* ]] || return 1
125
+
126
+ local process_cwd=""
127
+ process_cwd=$(readlink -f "$ROBIN_PROC_ROOT/$pid/cwd" 2>/dev/null || true)
128
+ [[ "$process_cwd" == "$ROBIN_APP_DIR" ]] || return 1
129
+ }
130
+
131
+ _robin_read_pid() {
132
+ ROBIN_PID=""
133
+ ROBIN_PID_START=""
134
+ [[ -r "$ROBIN_PID_FILE" ]] || return 1
135
+ read -r ROBIN_PID ROBIN_PID_START < "$ROBIN_PID_FILE" || return 1
136
+ [[ "$ROBIN_PID" =~ ^[1-9][0-9]*$ && "$ROBIN_PID_START" =~ ^[1-9][0-9]*$ ]]
137
+ }
138
+
139
+ _robin_managed_process_running() {
140
+ _robin_read_pid || return 1
141
+ _robin_process_matches "$ROBIN_PID" "$ROBIN_PID_START"
142
+ }
143
+
144
+ _robin_runtime_active() {
145
+ _robin_managed_process_running || _robin_socket_open 127.0.0.1 "$ROBIN_PORT"
146
+ }
147
+
148
+ _robin_find_matching_processes() {
149
+ local process_dir pid
150
+ for process_dir in "$ROBIN_PROC_ROOT"/[0-9]*; do
151
+ [[ -d "$process_dir" ]] || continue
152
+ pid=${process_dir##*/}
153
+ _robin_process_matches "$pid" && printf '%s\n' "$pid"
154
+ done
155
+ }
156
+
157
+ _robin_write_pid() {
158
+ local pid="$1"
159
+ local start_time
160
+ start_time=$(_robin_proc_start_time "$pid") || return 1
161
+ mkdir -p "$KARNEL_RUN"
162
+ chmod 700 "$KARNEL_RUN" 2>/dev/null || true
163
+ local temporary="$ROBIN_PID_FILE.tmp.$$"
164
+ (umask 077; printf '%s %s\n' "$pid" "$start_time" > "$temporary") || return 1
165
+ mv "$temporary" "$ROBIN_PID_FILE"
166
+ }
167
+
168
+ _robin_acquire_lock() {
169
+ mkdir -p "$KARNEL_RUN"
170
+ chmod 700 "$KARNEL_RUN" 2>/dev/null || true
171
+
172
+ if mkdir "$ROBIN_LOCK_DIR" 2>/dev/null; then
173
+ (umask 077; printf '%s\n' "$$" > "$ROBIN_LOCK_DIR/pid")
174
+ return 0
175
+ fi
176
+
177
+ local owner=""
178
+ [[ -r "$ROBIN_LOCK_DIR/pid" ]] && read -r owner < "$ROBIN_LOCK_DIR/pid"
179
+ if [[ "$owner" =~ ^[1-9][0-9]*$ ]] && kill -0 "$owner" 2>/dev/null; then
180
+ log_error "Another Robin operation is already running (PID: $owner)"
181
+ return 1
182
+ fi
183
+
184
+ rm -f "$ROBIN_LOCK_DIR/pid"
185
+ rmdir "$ROBIN_LOCK_DIR" 2>/dev/null || {
186
+ log_error "Could not clear stale Robin lock: $ROBIN_LOCK_DIR"
187
+ return 1
188
+ }
189
+ mkdir "$ROBIN_LOCK_DIR" || return 1
190
+ (umask 077; printf '%s\n' "$$" > "$ROBIN_LOCK_DIR/pid")
191
+ }
192
+
193
+ _robin_release_lock() {
194
+ rm -f "$ROBIN_LOCK_DIR/pid"
195
+ rmdir "$ROBIN_LOCK_DIR" 2>/dev/null || true
196
+ }
197
+
198
+ _robin_rotate_log() {
199
+ [[ -f "$ROBIN_LOG" ]] || return 0
200
+ local size
201
+ size=$(wc -c < "$ROBIN_LOG" 2>/dev/null || printf '0')
202
+ if (( size > 1048576 )); then
203
+ mv -f "$ROBIN_LOG" "$ROBIN_LOG.1"
204
+ fi
205
+ }
206
+
207
+ _robin_print_disclaimer() {
208
+ echo
209
+ box "ATENCAO - USO RESPONSAVEL"
210
+ echo
211
+ log_warn "Use Robin somente em pesquisas legais, autorizadas e eticas."
212
+ log_info "Tor melhora a privacidade da conexao, mas nao garante anonimato."
213
+ log_info "O Robin acessa paginas automaticamente; nao execute nem abra arquivos desconhecidos."
214
+ log_info "Consultas, URLs, conteudo coletado e resumos podem ser enviados diretamente"
215
+ log_info "ao provedor de IA configurado, fora da rede Tor, e processados por terceiros."
216
+ log_info "Investigacoes sao salvas localmente em texto simples. Minimize dados pessoais"
217
+ log_info "e siga as leis, politicas institucionais e termos dos provedores aplicaveis."
218
+ log_info "Resultados de IA podem estar errados e nao constituem evidencia verificada."
219
+ log_info "A interface deve permanecer em 127.0.0.1; nunca exponha a porta $ROBIN_PORT."
220
+ log_info "Robin e um projeto independente: $ROBIN_DOCS_URL"
221
+ echo
222
+ }
223
+
224
+ _robin_notice_accepted() {
225
+ [[ -r "$ROBIN_ACK_FILE" ]] || return 1
226
+ grep -qx "notice_version=$ROBIN_NOTICE_VERSION" "$ROBIN_ACK_FILE" 2>/dev/null
227
+ }
228
+
229
+ _robin_require_acknowledgement() {
230
+ local explicit_accept="${1:-false}"
231
+ _robin_notice_accepted && return 0
232
+
233
+ if [[ "$explicit_accept" == "true" ]]; then
234
+ :
235
+ elif [[ -t 0 ]]; then
236
+ log_info "Digite 'yes' para confirmar que leu e aceita o aviso acima:"
237
+ local confirmation=""
238
+ read -r confirmation
239
+ if [[ "$confirmation" != "yes" ]]; then
240
+ log_error "Confirmacao necessaria para iniciar o Robin"
241
+ return 1
242
+ fi
243
+ else
244
+ log_error "Uso nao interativo requer: karnel robin start --accept-responsible-use"
245
+ return 1
246
+ fi
247
+
248
+ mkdir -p "$ROBIN_CONFIG_DIR"
249
+ chmod 700 "$ROBIN_CONFIG_DIR" 2>/dev/null || true
250
+ local temporary="$ROBIN_ACK_FILE.tmp.$$"
251
+ {
252
+ umask 077
253
+ printf 'notice_version=%s\naccepted_at=%s\n' \
254
+ "$ROBIN_NOTICE_VERSION" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$temporary"
255
+ } || return 1
256
+ mv "$temporary" "$ROBIN_ACK_FILE"
257
+ log_success "Confirmacao registrada para o aviso $ROBIN_NOTICE_VERSION"
258
+ }