karnel-termux 4.7.7 → 4.9.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 (215) hide show
  1. package/README.md +46 -5
  2. package/install.sh +2 -2
  3. package/karnel/cli/commands/backup.sh +13 -2
  4. package/karnel/cli/commands/doctor/fixes.sh +111 -13
  5. package/karnel/cli/commands/doctor.sh +112 -10
  6. package/karnel/cli/commands/init.sh +2 -2
  7. package/karnel/cli/commands/install.sh +155 -118
  8. package/karnel/cli/commands/list.sh +106 -13
  9. package/karnel/cli/commands/open.sh +28 -8
  10. package/karnel/cli/commands/reinstall.sh +79 -46
  11. package/karnel/cli/commands/restore.sh +16 -0
  12. package/karnel/cli/commands/robin.sh +656 -0
  13. package/karnel/cli/commands/search.sh +1 -0
  14. package/karnel/cli/commands/show.sh +1 -0
  15. package/karnel/cli/commands/start.sh +12 -2
  16. package/karnel/cli/commands/status.sh +11 -0
  17. package/karnel/cli/commands/uninstall.sh +47 -0
  18. package/karnel/cli/commands/update.sh +43 -0
  19. package/karnel/cli/commands/version.sh +2 -0
  20. package/karnel/cli/commands/voice.sh +11 -6
  21. package/karnel/cli/karnel.sh +115 -69
  22. package/karnel/modules/ai.sh +21 -6
  23. package/karnel/modules/deploy.sh +4 -0
  24. package/karnel/modules/dev.sh +19 -46
  25. package/karnel/modules/games.sh +81 -4
  26. package/karnel/modules/network.sh +88 -0
  27. package/karnel/modules/osint.sh +123 -0
  28. package/karnel/modules/shell.sh +1 -1
  29. package/karnel/modules/ui.sh +4 -0
  30. package/karnel/modules/utils.sh +88 -0
  31. package/karnel/modules/voice.sh +8 -2
  32. package/karnel/tools/ai/all.sh +1 -0
  33. package/karnel/tools/ai/antigravity-cli/install.sh +0 -0
  34. package/karnel/tools/ai/claude-code/install.sh +0 -0
  35. package/karnel/tools/ai/cline/install.sh +8 -8
  36. package/karnel/tools/ai/codegraph/install.sh +8 -5
  37. package/karnel/tools/ai/codex/install.sh +0 -0
  38. package/karnel/tools/ai/command-code/install.sh +0 -0
  39. package/karnel/tools/ai/copilot-termux/install.sh +0 -0
  40. package/karnel/tools/ai/crush/install.sh +1 -1
  41. package/karnel/tools/ai/ctx7/install.sh +0 -0
  42. package/karnel/tools/ai/engram/install.sh +5 -2
  43. package/karnel/tools/ai/freebuff/install.sh +0 -0
  44. package/karnel/tools/ai/gemini-cli/install.sh +0 -0
  45. package/karnel/tools/ai/gentle-ai/install.sh +1 -1
  46. package/karnel/tools/ai/hermes-agent/install.sh +0 -0
  47. package/karnel/tools/ai/kilocode-cli/install.sh +0 -0
  48. package/karnel/tools/ai/kimchi-code/install.sh +3 -1
  49. package/karnel/tools/ai/kimi-code/install.sh +0 -0
  50. package/karnel/tools/ai/kiro/install.sh +0 -0
  51. package/karnel/tools/ai/mimocode/install.sh +0 -0
  52. package/karnel/tools/ai/minimax-cli/install.sh +0 -0
  53. package/karnel/tools/ai/mistral-vibe/install.sh +0 -0
  54. package/karnel/tools/ai/odysseus/install.sh +0 -0
  55. package/karnel/tools/ai/ollama/install.sh +0 -0
  56. package/karnel/tools/ai/omni-route/install.sh +1 -1
  57. package/karnel/tools/ai/openclaude/install.sh +0 -0
  58. package/karnel/tools/ai/openclaw/install.sh +0 -0
  59. package/karnel/tools/ai/opencode/install.sh +0 -0
  60. package/karnel/tools/ai/openspec/install.sh +0 -0
  61. package/karnel/tools/ai/pi/install.sh +0 -0
  62. package/karnel/tools/ai/qoder/README.md +50 -0
  63. package/karnel/tools/ai/qoder/bin/qodercli +28 -0
  64. package/karnel/tools/ai/qoder/helper/qoder_helper.c +47 -0
  65. package/karnel/tools/ai/qoder/install.sh +367 -0
  66. package/karnel/tools/ai/qwen-code/install.sh +0 -0
  67. package/karnel/tools/auto/all.sh +1 -1
  68. package/karnel/tools/auto/n8n/install.sh +0 -0
  69. package/karnel/tools/db/all.sh +1 -1
  70. package/karnel/tools/db/mariadb/install.sh +0 -0
  71. package/karnel/tools/db/mongodb/install.sh +0 -0
  72. package/karnel/tools/db/postgresql/install.sh +0 -0
  73. package/karnel/tools/db/sqlite/install.sh +0 -0
  74. package/karnel/tools/deploy/all.sh +2 -2
  75. package/karnel/tools/deploy/netlify/install.sh +0 -0
  76. package/karnel/tools/deploy/railway/install.sh +1 -1
  77. package/karnel/tools/deploy/vercel/install.sh +0 -0
  78. package/karnel/tools/dev/all.sh +36 -13
  79. package/karnel/tools/dev/bat/install.sh +0 -0
  80. package/karnel/tools/dev/bc/install.sh +0 -0
  81. package/karnel/tools/dev/cloudflared/install.sh +0 -0
  82. package/karnel/tools/dev/curl/install.sh +0 -0
  83. package/karnel/tools/dev/fzf/install.sh +36 -9
  84. package/karnel/tools/dev/gh/install.sh +0 -0
  85. package/karnel/tools/dev/html2text/install.sh +0 -0
  86. package/karnel/tools/dev/imagemagick/install.sh +0 -0
  87. package/karnel/tools/dev/jq/install.sh +0 -0
  88. package/karnel/tools/dev/lsd/install.sh +0 -0
  89. package/karnel/tools/dev/make/install.sh +0 -0
  90. package/karnel/tools/dev/ncurses/install.sh +0 -0
  91. package/karnel/tools/dev/proot/install.sh +0 -0
  92. package/karnel/tools/dev/shfmt/install.sh +0 -0
  93. package/karnel/tools/dev/snyk/install.sh +0 -0
  94. package/karnel/tools/dev/tmate/install.sh +0 -0
  95. package/karnel/tools/dev/translate/install.sh +0 -0
  96. package/karnel/tools/dev/tree/install.sh +0 -0
  97. package/karnel/tools/dev/udocker/install.sh +0 -0
  98. package/karnel/tools/dev/wget/install.sh +0 -0
  99. package/karnel/tools/editor/all.sh +1 -1
  100. package/karnel/tools/editor/code-server/install.sh +0 -0
  101. package/karnel/tools/games/all.sh +1 -1
  102. package/karnel/tools/games/arcade/install.sh +0 -0
  103. package/karnel/tools/games/buzz/install.sh +0 -0
  104. package/karnel/tools/games/ctfgod/install.sh +0 -0
  105. package/karnel/tools/games/detective/install.sh +0 -0
  106. package/karnel/tools/games/pet-friends/install.sh +0 -0
  107. package/karnel/tools/games/tamagotchi/install.sh +0 -0
  108. package/karnel/tools/lang/all.sh +2 -1
  109. package/karnel/tools/lang/bun/bin/bun +27 -0
  110. package/karnel/tools/lang/bun/install.sh +318 -0
  111. package/karnel/tools/lang/bun/src/bun-shim.c +352 -0
  112. package/karnel/tools/lang/bun/src/bun_wrapper.c +55 -0
  113. package/karnel/tools/lang/clang/install.sh +0 -0
  114. package/karnel/tools/lang/golang/install.sh +0 -0
  115. package/karnel/tools/lang/nodejs/install.sh +0 -0
  116. package/karnel/tools/lang/perl/install.sh +0 -0
  117. package/karnel/tools/lang/php/install.sh +0 -0
  118. package/karnel/tools/lang/python/install.sh +0 -0
  119. package/karnel/tools/lang/rust/install.sh +0 -0
  120. package/karnel/tools/network/all.sh +65 -0
  121. package/karnel/tools/network/dark/README.md +45 -0
  122. package/karnel/tools/network/dark/dark.py +709 -0
  123. package/karnel/tools/network/dark/install.sh +51 -0
  124. package/karnel/tools/network/dedsec-network/README.md +42 -0
  125. package/karnel/tools/network/dedsec-network/dedsec-network.py +709 -0
  126. package/karnel/tools/network/dedsec-network/install.sh +50 -0
  127. package/karnel/tools/npm/all.sh +1 -1
  128. package/karnel/tools/npm/live-server/install.sh +0 -0
  129. package/karnel/tools/npm/localtunnel/install.sh +0 -0
  130. package/karnel/tools/npm/markserv/install.sh +0 -0
  131. package/karnel/tools/npm/ncu/install.sh +0 -0
  132. package/karnel/tools/npm/nestjs/install.sh +0 -0
  133. package/karnel/tools/npm/ngrok/install.sh +0 -0
  134. package/karnel/tools/npm/prettier/install.sh +0 -0
  135. package/karnel/tools/npm/psqlformat/install.sh +0 -0
  136. package/karnel/tools/npm/turbopack/install.sh +2 -0
  137. package/karnel/tools/npm/typescript/install.sh +0 -0
  138. package/karnel/tools/npm/vercel/install.sh +0 -0
  139. package/karnel/tools/osint/all.sh +65 -0
  140. package/karnel/tools/osint/robin/README.md +99 -0
  141. package/karnel/tools/osint/robin/common.sh +258 -0
  142. package/karnel/tools/osint/robin/install.sh +548 -0
  143. package/karnel/tools/osint/robin/requirements-termux.txt +33 -0
  144. package/karnel/tools/shell/all.sh +1 -1
  145. package/karnel/tools/shell/better-npm/install.sh +0 -0
  146. package/karnel/tools/shell/fzf-tab/install.sh +0 -0
  147. package/karnel/tools/shell/history-substring/install.sh +0 -0
  148. package/karnel/tools/shell/powerlevel10k/install.sh +0 -0
  149. package/karnel/tools/shell/you-should-use/install.sh +0 -0
  150. package/karnel/tools/shell/zsh-autopair/install.sh +0 -0
  151. package/karnel/tools/shell/zsh-autosuggestions/install.sh +0 -0
  152. package/karnel/tools/shell/zsh-completions/install.sh +0 -0
  153. package/karnel/tools/shell/zsh-defer/install.sh +0 -0
  154. package/karnel/tools/shell/zsh-syntax-highlighting/install.sh +0 -0
  155. package/karnel/tools/ui/all.sh +1 -1
  156. package/karnel/tools/ui/banner/install.sh +0 -0
  157. package/karnel/tools/ui/cursor/install.sh +0 -0
  158. package/karnel/tools/ui/extra-keys/install.sh +0 -0
  159. package/karnel/tools/ui/font/install.sh +0 -0
  160. package/karnel/tools/utils/all.sh +88 -0
  161. package/karnel/tools/utils/applaunch/README.md +43 -0
  162. package/karnel/tools/{dev → utils}/applaunch/install.sh +3 -3
  163. package/karnel/tools/utils/fconv/README.md +41 -0
  164. package/karnel/tools/{dev → utils}/fconv/install.sh +3 -3
  165. package/karnel/tools/utils/filecheck/README.md +41 -0
  166. package/karnel/tools/{dev → utils}/filecheck/install.sh +3 -3
  167. package/karnel/tools/utils/httptmux/README.md +42 -0
  168. package/karnel/tools/{dev → utils}/httptmux/install.sh +0 -0
  169. package/karnel/tools/utils/notes/README.md +41 -0
  170. package/karnel/tools/{dev → utils}/notes/install.sh +3 -3
  171. package/karnel/tools/utils/passman/README.md +42 -0
  172. package/karnel/tools/{dev → utils}/passman/install.sh +3 -3
  173. package/karnel/tools/utils/qrcode/README.md +41 -0
  174. package/karnel/tools/utils/qrcode/install.sh +50 -0
  175. package/karnel/tools/utils/qrcode/qrcode.py +89 -0
  176. package/karnel/tools/utils/splash/README.md +41 -0
  177. package/karnel/tools/{dev → utils}/splash/install.sh +3 -3
  178. package/karnel/tools/utils/treex/README.md +41 -0
  179. package/karnel/tools/{dev → utils}/treex/install.sh +3 -3
  180. package/karnel/tools/utils/websites/README.md +41 -0
  181. package/karnel/tools/{dev → utils}/websites/install.sh +3 -3
  182. package/karnel/tools/utils/zork/README.md +43 -0
  183. package/karnel/tools/{dev → utils}/zork/install.sh +3 -3
  184. package/karnel/utils/banner.sh +8 -6
  185. package/karnel/utils/bootstrap.sh +1 -1
  186. package/karnel/utils/env.sh +16 -2
  187. package/karnel/utils/log.sh +0 -1
  188. package/karnel/utils/tools.sh +9 -2
  189. package/package.json +6 -1
  190. package/scripts/check-package.js +45 -0
  191. package/scripts/completion.bash +8 -3
  192. package/scripts/completion.zsh +8 -13
  193. package/karnel/cli/commands/doctor/system.sh +0 -87
  194. package/karnel/tools/dev/applaunch/__pycache__/applaunch.cpython-314.pyc +0 -0
  195. package/karnel/tools/dev/fconv/__pycache__/fconv.cpython-314.pyc +0 -0
  196. package/karnel/tools/dev/filecheck/__pycache__/filecheck.cpython-314.pyc +0 -0
  197. package/karnel/tools/dev/notes/__pycache__/notes.cpython-314.pyc +0 -0
  198. package/karnel/tools/dev/passman/__pycache__/passman.cpython-314.pyc +0 -0
  199. package/karnel/tools/dev/splash/__pycache__/splash.cpython-314.pyc +0 -0
  200. package/karnel/tools/dev/websites/__pycache__/websites.cpython-314.pyc +0 -0
  201. package/karnel/tools/games/arcade/__pycache__/arcade.cpython-314.pyc +0 -0
  202. package/karnel/tools/games/buzz/__pycache__/buzz.cpython-314.pyc +0 -0
  203. package/karnel/tools/games/ctfgod/__pycache__/ctfgod.cpython-314.pyc +0 -0
  204. package/karnel/tools/games/detective/__pycache__/detective.cpython-314.pyc +0 -0
  205. package/karnel/tools/games/pet-friends/__pycache__/pet-friends.cpython-314.pyc +0 -0
  206. package/karnel/tools/games/tamagotchi/__pycache__/tamagotchi.cpython-314.pyc +0 -0
  207. package/karnel/tools/games/terminal-arcade/__pycache__/terminal-arcade.cpython-314.pyc +0 -0
  208. /package/karnel/tools/{dev → utils}/applaunch/applaunch.py +0 -0
  209. /package/karnel/tools/{dev → utils}/fconv/fconv.py +0 -0
  210. /package/karnel/tools/{dev → utils}/filecheck/filecheck.py +0 -0
  211. /package/karnel/tools/{dev → utils}/notes/notes.py +0 -0
  212. /package/karnel/tools/{dev → utils}/passman/passman.py +0 -0
  213. /package/karnel/tools/{dev → utils}/splash/splash.py +0 -0
  214. /package/karnel/tools/{dev → utils}/treex/treex.py +0 -0
  215. /package/karnel/tools/{dev → utils}/websites/websites.py +0 -0
@@ -0,0 +1,656 @@
1
+ #!/usr/bin/env bash
2
+
3
+ import "@/utils/log"
4
+ import "@/utils/colors"
5
+ import "@/tools/osint/robin/common"
6
+
7
+ _robin_ensure_installed() {
8
+ if ! _robin_is_installed; then
9
+ log_error "Robin is not completely installed"
10
+ log_info "Install or repair it with: karnel install osint --robin"
11
+ return 1
12
+ fi
13
+ }
14
+
15
+ _robin_configured_provider_count() {
16
+ local env_file="$1"
17
+ local key value provider
18
+ local -A providers=()
19
+ [[ -r "$env_file" ]] || {
20
+ printf '0\n'
21
+ return
22
+ }
23
+
24
+ while IFS='=' read -r key value; do
25
+ [[ "$key" =~ ^[A-Z][A-Z0-9_]*$ ]] || continue
26
+ value="${value%\"}"
27
+ value="${value#\"}"
28
+ [[ -n "$value" && "$value" != your_* && "$value" != change_me* ]] || continue
29
+ case "$key" in
30
+ OPENAI_API_KEY) provider="openai" ;;
31
+ ANTHROPIC_API_KEY) provider="anthropic" ;;
32
+ GOOGLE_API_KEY) provider="google" ;;
33
+ OPENROUTER_API_KEY|OPENROUTER_BASE_URL) provider="openrouter" ;;
34
+ OLLAMA_BASE_URL) provider="ollama" ;;
35
+ LLAMA_CPP_BASE_URL) provider="llama-cpp" ;;
36
+ CUSTOM_API_BASE_URL|CUSTOM_API_KEY|CUSTOM_API_MODEL) provider="custom" ;;
37
+ *) continue ;;
38
+ esac
39
+ providers["$provider"]=1
40
+ done < "$env_file"
41
+ printf '%s\n' "${#providers[@]}"
42
+ }
43
+
44
+ _robin_terminate_managed_process() {
45
+ local pid="$1"
46
+ local start_time="$2"
47
+ _robin_process_matches "$pid" "$start_time" || return 0
48
+ kill "$pid" 2>/dev/null || return 1
49
+
50
+ local attempt
51
+ for ((attempt = 0; attempt < 15; attempt++)); do
52
+ _robin_process_matches "$pid" "$start_time" || return 0
53
+ sleep 1
54
+ done
55
+ _robin_process_matches "$pid" "$start_time" || return 0
56
+ log_warn "Robin did not stop gracefully; sending SIGKILL"
57
+ kill -9 "$pid" 2>/dev/null || return 1
58
+
59
+ for ((attempt = 0; attempt < 5; attempt++)); do
60
+ _robin_process_matches "$pid" "$start_time" || return 0
61
+ sleep 1
62
+ done
63
+ ! _robin_process_matches "$pid" "$start_time"
64
+ }
65
+
66
+ _robin_start_tor() {
67
+ if _robin_socket_open 127.0.0.1 9050; then
68
+ log_info "Tor SOCKS proxy ja esta disponivel"
69
+ return 0
70
+ fi
71
+ if ! command -v tor &>/dev/null; then
72
+ log_error "Tor is not installed. Run: pkg install tor"
73
+ return 1
74
+ fi
75
+
76
+ log_info "Iniciando Tor..."
77
+ tor --RunAsDaemon 1 &>>"$ROBIN_LOG" || {
78
+ log_error "Falha ao iniciar o Tor"
79
+ return 1
80
+ }
81
+
82
+ local attempt
83
+ for ((attempt = 0; attempt < 30; attempt++)); do
84
+ if _robin_socket_open 127.0.0.1 9050; then
85
+ log_success "Tor SOCKS proxy pronto em 127.0.0.1:9050"
86
+ return 0
87
+ fi
88
+ sleep 1
89
+ done
90
+
91
+ log_error "Tor iniciou, mas o proxy SOCKS nao ficou pronto em 30 segundos"
92
+ return 1
93
+ }
94
+
95
+ robin_main() {
96
+ local subcommand="${1:-help}"
97
+ [[ $# -gt 0 ]] && shift
98
+
99
+ case "$subcommand" in
100
+ help|--help|-h)
101
+ _robin_help
102
+ return
103
+ ;;
104
+ start|stop|status|config|doctor|update|purge-data)
105
+ _robin_print_disclaimer
106
+ ;;
107
+ *)
108
+ log_error "Unknown robin subcommand: $subcommand"
109
+ echo
110
+ _robin_help
111
+ return 1
112
+ ;;
113
+ esac
114
+
115
+ case "$subcommand" in
116
+ start) _robin_start "$@" ;;
117
+ stop) _robin_stop "$@" ;;
118
+ status) _robin_status "$@" ;;
119
+ config) _robin_config "$@" ;;
120
+ doctor) _robin_doctor "$@" ;;
121
+ update) _robin_update "$@" ;;
122
+ purge-data) _robin_purge_data "$@" ;;
123
+ esac
124
+ }
125
+
126
+ _robin_start() {
127
+ local accept=false
128
+ while [[ $# -gt 0 ]]; do
129
+ case "$1" in
130
+ --accept-responsible-use) accept=true ;;
131
+ --help|-h) _robin_help; return ;;
132
+ *) log_error "Unknown start option: $1"; return 1 ;;
133
+ esac
134
+ shift
135
+ done
136
+
137
+ _robin_ensure_installed || return 1
138
+ _robin_require_acknowledgement "$accept" || return 1
139
+ _robin_acquire_lock || return 1
140
+ local rc=0
141
+ local launched_pid=""
142
+ local launched_start=""
143
+
144
+ if _robin_managed_process_running; then
145
+ if _robin_http_healthy; then
146
+ log_warn "Robin ja esta em execucao (PID: $ROBIN_PID)"
147
+ log_info "Acesse: http://127.0.0.1:$ROBIN_PORT"
148
+ _robin_release_lock
149
+ return 0
150
+ fi
151
+ log_error "A Robin process exists but its health endpoint is not responding"
152
+ _robin_release_lock
153
+ return 1
154
+ fi
155
+
156
+ if [[ -f "$ROBIN_PID_FILE" ]]; then
157
+ log_warn "Ignoring a stale Robin PID record; no process was signaled"
158
+ rm -f "$ROBIN_PID_FILE"
159
+ fi
160
+
161
+ if _robin_socket_open 127.0.0.1 "$ROBIN_PORT"; then
162
+ log_error "Port $ROBIN_PORT is already in use by another process"
163
+ _robin_release_lock
164
+ return 1
165
+ fi
166
+
167
+ mkdir -p "$KARNEL_LOGS" "$KARNEL_RUN"
168
+ chmod 700 "$KARNEL_LOGS" "$KARNEL_RUN" 2>/dev/null || true
169
+ _robin_rotate_log
170
+ _robin_start_tor || rc=$?
171
+
172
+ if (( rc == 0 )); then
173
+ log_info "Iniciando Robin Streamlit..."
174
+ (
175
+ umask 077
176
+ cd "$ROBIN_APP_DIR" || exit 1
177
+ nohup "$ROBIN_VENV_DIR/bin/python" -m streamlit run ui.py \
178
+ --server.address 127.0.0.1 \
179
+ --server.port "$ROBIN_PORT" \
180
+ --server.headless true \
181
+ --server.fileWatcherType none \
182
+ --browser.gatherUsageStats false \
183
+ &>>"$ROBIN_LOG" &
184
+ printf '%s\n' "$!"
185
+ ) > "$ROBIN_PID_FILE.launch"
186
+
187
+ read -r launched_pid < "$ROBIN_PID_FILE.launch"
188
+ rm -f "$ROBIN_PID_FILE.launch"
189
+ if [[ ! "$launched_pid" =~ ^[1-9][0-9]*$ ]]; then
190
+ log_error "Failed to capture the Robin process ID"
191
+ rc=1
192
+ else
193
+ sleep 1
194
+ launched_start=$(_robin_proc_start_time "$launched_pid") || rc=1
195
+ if (( rc == 0 )); then
196
+ _robin_write_pid "$launched_pid" || rc=1
197
+ fi
198
+ fi
199
+ fi
200
+
201
+ if (( rc == 0 )); then
202
+ local attempt
203
+ for ((attempt = 0; attempt < ROBIN_START_TIMEOUT; attempt++)); do
204
+ if ! _robin_managed_process_running; then
205
+ rc=1
206
+ break
207
+ fi
208
+ if _robin_http_healthy; then
209
+ log_success "Robin pronto (PID: $ROBIN_PID)"
210
+ log_info "Acesse: http://127.0.0.1:$ROBIN_PORT"
211
+ log_info "Para encerrar: karnel robin stop"
212
+ break
213
+ fi
214
+ sleep 1
215
+ done
216
+ if (( attempt >= ROBIN_START_TIMEOUT )); then
217
+ rc=1
218
+ fi
219
+ fi
220
+
221
+ if (( rc != 0 )); then
222
+ local cleanup_pid="$launched_pid"
223
+ local cleanup_start="$launched_start"
224
+ if _robin_managed_process_running; then
225
+ cleanup_pid="$ROBIN_PID"
226
+ cleanup_start="$ROBIN_PID_START"
227
+ fi
228
+ if [[ -n "$cleanup_pid" && -n "$cleanup_start" ]] &&
229
+ ! _robin_terminate_managed_process "$cleanup_pid" "$cleanup_start"; then
230
+ log_error "Failed to stop the unhealthy Robin process; PID record was preserved"
231
+ if [[ ! -f "$ROBIN_PID_FILE" ]]; then
232
+ _robin_write_pid "$cleanup_pid" || true
233
+ fi
234
+ else
235
+ rm -f "$ROBIN_PID_FILE"
236
+ fi
237
+ log_error "Robin did not become healthy within ${ROBIN_START_TIMEOUT}s"
238
+ log_info "Runtime log: $ROBIN_LOG"
239
+ fi
240
+
241
+ _robin_release_lock
242
+ return "$rc"
243
+ }
244
+
245
+ _robin_stop() {
246
+ if [[ $# -gt 0 ]]; then
247
+ log_error "karnel robin stop does not accept options"
248
+ return 1
249
+ fi
250
+ _robin_acquire_lock || return 1
251
+
252
+ if ! _robin_read_pid; then
253
+ local -a matching_processes=()
254
+ mapfile -t matching_processes < <(_robin_find_matching_processes)
255
+ if (( ${#matching_processes[@]} == 1 )); then
256
+ ROBIN_PID=${matching_processes[0]}
257
+ ROBIN_PID_START=$(_robin_proc_start_time "$ROBIN_PID") || {
258
+ log_error "Could not validate the unmanaged Robin process"
259
+ _robin_release_lock
260
+ return 1
261
+ }
262
+ log_warn "Adopting a validated Robin process without PID metadata (PID: $ROBIN_PID)"
263
+ _robin_write_pid "$ROBIN_PID" || {
264
+ log_error "Could not create safe PID metadata"
265
+ _robin_release_lock
266
+ return 1
267
+ }
268
+ elif (( ${#matching_processes[@]} > 1 )); then
269
+ log_error "Multiple unmanaged Robin processes were found; no process was signaled"
270
+ _robin_release_lock
271
+ return 1
272
+ elif _robin_http_healthy; then
273
+ log_warn "A server responds on port $ROBIN_PORT but its identity is not Robin"
274
+ log_warn "No process was signaled"
275
+ _robin_release_lock
276
+ return 1
277
+ else
278
+ log_info "Robin nao esta em execucao"
279
+ rm -f "$ROBIN_PID_FILE"
280
+ _robin_release_lock
281
+ return 0
282
+ fi
283
+ fi
284
+
285
+ if ! _robin_process_matches "$ROBIN_PID" "$ROBIN_PID_START"; then
286
+ log_warn "Stale or unsafe PID record detected; no process was signaled"
287
+ rm -f "$ROBIN_PID_FILE"
288
+ _robin_release_lock
289
+ return 1
290
+ fi
291
+
292
+ local pid="$ROBIN_PID"
293
+ local start_time="$ROBIN_PID_START"
294
+ log_info "Encerrando Robin (PID: $pid)..."
295
+ if ! _robin_terminate_managed_process "$pid" "$start_time"; then
296
+ log_error "Could not terminate Robin safely; PID record was preserved"
297
+ _robin_release_lock
298
+ return 1
299
+ fi
300
+
301
+ rm -f "$ROBIN_PID_FILE"
302
+ log_success "Robin encerrado"
303
+ log_info "Tor continua em execucao para nao interromper outros aplicativos"
304
+ _robin_release_lock
305
+ }
306
+
307
+ _robin_status() {
308
+ if [[ $# -gt 0 ]]; then
309
+ log_error "karnel robin status does not accept options"
310
+ return 1
311
+ fi
312
+
313
+ echo
314
+ box "Robin Status"
315
+ echo
316
+ local errors=0
317
+
318
+ if [[ -d "$ROBIN_APP_DIR/.git" ]]; then
319
+ local commit version
320
+ commit=$(git -C "$ROBIN_APP_DIR" rev-parse HEAD 2>/dev/null || printf 'unknown')
321
+ version=$(git -C "$ROBIN_APP_DIR" describe --tags --exact-match 2>/dev/null || printf '%s' "${commit:0:7}")
322
+ log_success "Robin: instalado ($version)"
323
+ if [[ "$commit" == "$ROBIN_COMMIT" ]]; then
324
+ log_success "Source pin: verificado"
325
+ else
326
+ log_warn "Source pin: diferente do release Karnel $ROBIN_VERSION"
327
+ fi
328
+ [[ "$ROBIN_LAYOUT" == "legacy" ]] && log_warn "Layout antigo detectado; execute: karnel robin update"
329
+ else
330
+ log_error "Robin source: ausente"
331
+ ((errors++))
332
+ fi
333
+
334
+ if [[ -x "$ROBIN_VENV_DIR/bin/python" ]]; then
335
+ log_success "Virtual env: ok"
336
+ else
337
+ log_error "Virtual env: ausente"
338
+ ((errors++))
339
+ fi
340
+
341
+ if _robin_socket_open 127.0.0.1 9050; then
342
+ log_success "Tor SOCKS: respondendo em 127.0.0.1:9050"
343
+ elif command -v tor &>/dev/null; then
344
+ log_warn "Tor: instalado, proxy parado"
345
+ else
346
+ log_error "Tor: nao instalado"
347
+ ((errors++))
348
+ fi
349
+
350
+ if _robin_managed_process_running; then
351
+ if _robin_http_healthy; then
352
+ log_success "Streamlit: saudavel (PID: $ROBIN_PID)"
353
+ log_info "URL: http://127.0.0.1:$ROBIN_PORT"
354
+ else
355
+ log_error "Streamlit: processo ativo, health check falhou"
356
+ ((errors++))
357
+ fi
358
+ elif [[ -f "$ROBIN_PID_FILE" ]]; then
359
+ log_warn "Streamlit: PID record obsoleto ou inseguro"
360
+ elif _robin_http_healthy; then
361
+ log_warn "Streamlit: servidor nao gerenciado responde na porta $ROBIN_PORT"
362
+ else
363
+ log_info "Streamlit: parado"
364
+ fi
365
+
366
+ local env_file="$ROBIN_ACTIVE_ENV_FILE"
367
+ if [[ -f "$env_file" ]]; then
368
+ local mode providers
369
+ mode=$(stat -c '%a' "$env_file" 2>/dev/null || printf 'unknown')
370
+ providers=$(_robin_configured_provider_count "$env_file")
371
+ if [[ "$mode" == "600" ]]; then
372
+ log_success "Configuracao: protegida ($providers provedor(es) configurado(s))"
373
+ else
374
+ log_warn "Configuracao: permissao $mode; execute karnel robin config para reparar"
375
+ fi
376
+ else
377
+ log_warn "Configuracao: ausente"
378
+ fi
379
+
380
+ if [[ -d "$ROBIN_ACTIVE_INVESTIGATIONS_DIR" ]]; then
381
+ local investigations
382
+ investigations=$(printf '%s\n' "$ROBIN_ACTIVE_INVESTIGATIONS_DIR"/investigation_*.json)
383
+ if [[ "$investigations" == *'*'* ]]; then
384
+ investigations=0
385
+ else
386
+ investigations=$(printf '%s\n' "$investigations" | wc -l)
387
+ fi
388
+ log_info "Investigacoes salvas: $investigations"
389
+ fi
390
+ [[ -f "$ROBIN_LOG" ]] && log_info "Log: $ROBIN_LOG"
391
+ echo
392
+ (( errors == 0 ))
393
+ }
394
+
395
+ _robin_config() {
396
+ if [[ $# -gt 0 ]]; then
397
+ log_error "karnel robin config does not accept options"
398
+ return 1
399
+ fi
400
+ _robin_ensure_installed || return 1
401
+
402
+ _robin_acquire_lock || return 1
403
+ local rc=0
404
+ import "@/tools/osint/robin/install"
405
+ _robin_migrate_legacy_layout || rc=$?
406
+ if (( rc == 0 )); then
407
+ _robin_prepare_persistent_data "$ROBIN_APP_DIR" || rc=$?
408
+ fi
409
+ if (( rc == 0 )); then
410
+ chmod 700 "$ROBIN_CONFIG_DIR" 2>/dev/null || true
411
+ chmod 600 "$ROBIN_ENV_FILE" || rc=$?
412
+ fi
413
+ _robin_release_lock
414
+ (( rc == 0 )) || return "$rc"
415
+
416
+ echo
417
+ box "Configuracao do Robin"
418
+ echo
419
+ log_info "Arquivo protegido: $ROBIN_ENV_FILE"
420
+ log_info "Edite com: nano $ROBIN_ENV_FILE"
421
+ echo
422
+ log_info "Provedores e endpoints suportados:"
423
+ list_item "OPENAI_API_KEY"
424
+ list_item "ANTHROPIC_API_KEY"
425
+ list_item "GOOGLE_API_KEY"
426
+ list_item "OPENROUTER_API_KEY / OPENROUTER_BASE_URL"
427
+ list_item "OLLAMA_BASE_URL"
428
+ list_item "LLAMA_CPP_BASE_URL"
429
+ list_item "CUSTOM_API_BASE_URL / CUSTOM_API_KEY / CUSTOM_API_MODEL"
430
+ echo
431
+ log_warn "Trafego para provedores de IA normalmente nao passa pelo Tor."
432
+ log_warn "Nunca compartilhe ou commite esse arquivo."
433
+ echo
434
+ }
435
+
436
+ _robin_doctor() {
437
+ local network=false
438
+ while [[ $# -gt 0 ]]; do
439
+ case "$1" in
440
+ --network) network=true ;;
441
+ --help|-h) _robin_help; return ;;
442
+ *) log_error "Unknown doctor option: $1"; return 1 ;;
443
+ esac
444
+ shift
445
+ done
446
+
447
+ echo
448
+ box "Robin Doctor - Diagnostico"
449
+ echo
450
+ local errors=0
451
+
452
+ if command -v python3 &>/dev/null; then
453
+ local py_version
454
+ py_version=$(python3 --version 2>&1)
455
+ log_success "Python: $py_version"
456
+ else
457
+ log_error "Python 3: ausente"
458
+ ((errors++))
459
+ fi
460
+
461
+ if [[ -x "$ROBIN_VENV_DIR/bin/python" ]]; then
462
+ log_success "Virtual env: presente"
463
+ import "@/tools/osint/robin/install"
464
+ if _robin_verify_install "$ROBIN_APP_DIR" "$ROBIN_VENV_DIR"; then
465
+ local streamlit_version pyarrow_version
466
+ streamlit_version=$(
467
+ "$ROBIN_VENV_DIR/bin/python" -c 'import streamlit; print(streamlit.__version__)'
468
+ )
469
+ pyarrow_version=$(
470
+ "$ROBIN_VENV_DIR/bin/python" -c 'import pyarrow; print(pyarrow.__version__)'
471
+ )
472
+ log_success "Dependencias Robin: imports verificados"
473
+ log_info "Streamlit $streamlit_version; pyarrow Termux $pyarrow_version"
474
+ else
475
+ log_error "Dependencias Robin: verificacao falhou"
476
+ ((errors++))
477
+ fi
478
+ else
479
+ log_error "Virtual env: ausente"
480
+ ((errors++))
481
+ fi
482
+
483
+ if [[ -d "$ROBIN_APP_DIR/.git" ]]; then
484
+ local commit
485
+ commit=$(git -C "$ROBIN_APP_DIR" rev-parse HEAD 2>/dev/null || printf 'unknown')
486
+ if [[ "$commit" == "$ROBIN_COMMIT" ]]; then
487
+ log_success "Source: $ROBIN_VERSION verificado"
488
+ else
489
+ log_error "Source: commit inesperado ($commit)"
490
+ ((errors++))
491
+ fi
492
+ else
493
+ log_error "Source: ausente"
494
+ ((errors++))
495
+ fi
496
+
497
+ if _robin_socket_open 127.0.0.1 9050; then
498
+ log_success "Tor SOCKS: respondendo"
499
+ elif command -v tor &>/dev/null; then
500
+ log_info "Tor: instalado; o proxy sera iniciado por karnel robin start"
501
+ else
502
+ log_error "Tor: nao instalado"
503
+ ((errors++))
504
+ fi
505
+
506
+ if _robin_socket_open 127.0.0.1 "$ROBIN_PORT"; then
507
+ if _robin_http_healthy; then
508
+ log_success "Streamlit: health endpoint ok"
509
+ else
510
+ log_error "Porta $ROBIN_PORT ocupada sem health check do Robin"
511
+ ((errors++))
512
+ fi
513
+ else
514
+ log_info "Porta $ROBIN_PORT: disponivel"
515
+ fi
516
+
517
+ if [[ -f "$ROBIN_ACTIVE_ENV_FILE" ]]; then
518
+ local mode providers
519
+ mode=$(stat -c '%a' "$ROBIN_ACTIVE_ENV_FILE" 2>/dev/null || printf 'unknown')
520
+ providers=$(_robin_configured_provider_count "$ROBIN_ACTIVE_ENV_FILE")
521
+ if [[ "$mode" == "600" ]]; then
522
+ log_success ".env: permissao 600"
523
+ else
524
+ log_error ".env: permissao insegura ($mode)"
525
+ ((errors++))
526
+ fi
527
+ if (( providers > 0 )); then
528
+ log_success "Provedores configurados: $providers"
529
+ else
530
+ log_warn "Nenhum provedor real detectado; configure antes de investigar"
531
+ fi
532
+ else
533
+ log_error ".env: ausente"
534
+ ((errors++))
535
+ fi
536
+
537
+ if [[ -d "$ROBIN_ACTIVE_INVESTIGATIONS_DIR" && -w "$ROBIN_ACTIVE_INVESTIGATIONS_DIR" ]]; then
538
+ log_success "Diretorio de investigacoes: gravavel"
539
+ else
540
+ log_error "Diretorio de investigacoes: ausente ou sem escrita"
541
+ ((errors++))
542
+ fi
543
+
544
+ if $network; then
545
+ log_info "Verificando uma requisicao HTTPS atraves do Tor..."
546
+ if ! _robin_socket_open 127.0.0.1 9050; then
547
+ log_error "Rede Tor: proxy parado; execute karnel robin start primeiro"
548
+ ((errors++))
549
+ elif curl --fail --silent --show-error --socks5-hostname 127.0.0.1:9050 \
550
+ --max-time 30 --output /dev/null https://example.com; then
551
+ log_success "Rede Tor: requisicao concluida"
552
+ else
553
+ log_error "Rede Tor: requisicao falhou"
554
+ ((errors++))
555
+ fi
556
+ else
557
+ log_info "Teste externo ignorado; use --network para verificar trafego Tor"
558
+ fi
559
+
560
+ echo
561
+ if (( errors == 0 )); then
562
+ log_success "Diagnostico concluido sem erros criticos"
563
+ return 0
564
+ fi
565
+ log_error "Diagnostico encontrou $errors erro(s) critico(s)"
566
+ return 1
567
+ }
568
+
569
+ _robin_update() {
570
+ if [[ $# -gt 0 ]]; then
571
+ log_error "karnel robin update does not accept options"
572
+ return 1
573
+ fi
574
+ _robin_ensure_installed || return 1
575
+ import "@/tools/osint/robin/install"
576
+ update_robin
577
+ local rc=$?
578
+ [[ $rc -eq 2 ]] && return 0
579
+ return "$rc"
580
+ }
581
+
582
+ _robin_purge_data() {
583
+ local confirmed=false
584
+ while [[ $# -gt 0 ]]; do
585
+ case "$1" in
586
+ --yes) confirmed=true ;;
587
+ *) log_error "Unknown purge-data option: $1"; return 1 ;;
588
+ esac
589
+ shift
590
+ done
591
+
592
+ _robin_acquire_lock || return 1
593
+ import "@/tools/osint/robin/install"
594
+ if ! _robin_migrate_legacy_layout; then
595
+ _robin_release_lock
596
+ return 1
597
+ fi
598
+ if _robin_runtime_active; then
599
+ log_error "Stop Robin before deleting data: karnel robin stop"
600
+ _robin_release_lock
601
+ return 1
602
+ fi
603
+ log_warn "This permanently deletes Robin provider configuration and investigations:"
604
+ list_item "$ROBIN_CONFIG_DIR"
605
+ list_item "$ROBIN_DATA_DIR"
606
+
607
+ if ! $confirmed; then
608
+ if [[ ! -t 0 ]]; then
609
+ log_error "Non-interactive purge requires: karnel robin purge-data --yes"
610
+ _robin_release_lock
611
+ return 1
612
+ fi
613
+ log_info "Digite 'PURGE' para confirmar a exclusao permanente:"
614
+ local answer=""
615
+ read -r answer
616
+ [[ "$answer" == "PURGE" ]] || {
617
+ log_info "Exclusao cancelada"
618
+ _robin_release_lock
619
+ return 1
620
+ }
621
+ fi
622
+
623
+ if ! rm -rf "$ROBIN_CONFIG_DIR" "$ROBIN_DATA_DIR"; then
624
+ log_error "Failed to delete Robin data"
625
+ _robin_release_lock
626
+ return 1
627
+ fi
628
+ if [[ -d "$ROBIN_APP_DIR" ]]; then
629
+ _robin_prepare_persistent_data "$ROBIN_APP_DIR" || {
630
+ _robin_release_lock
631
+ return 1
632
+ }
633
+ fi
634
+ log_success "Robin configuration and investigations were permanently deleted"
635
+ _robin_release_lock
636
+ }
637
+
638
+ _robin_help() {
639
+ echo
640
+ box "Robin - OSINT Tool Manager"
641
+ echo
642
+ log_info "Uso: karnel robin <subcomando> [opcoes]"
643
+ echo
644
+ printf " ${D_CYAN}%-14s${NC} %s\n" "start" "Start Tor and the loopback-only web interface"
645
+ printf " ${D_CYAN}%-14s${NC} %s\n" "stop" "Stop the managed Robin interface"
646
+ printf " ${D_CYAN}%-14s${NC} %s\n" "status" "Show installation and runtime state"
647
+ printf " ${D_CYAN}%-14s${NC} %s\n" "config" "Show protected provider configuration"
648
+ printf " ${D_CYAN}%-14s${NC} %s\n" "doctor" "Run local diagnostics; --network tests Tor traffic"
649
+ printf " ${D_CYAN}%-14s${NC} %s\n" "update" "Reconcile with Karnel's pinned Robin release"
650
+ printf " ${D_CYAN}%-14s${NC} %s\n" "purge-data" "Permanently delete config and investigations"
651
+ echo
652
+ log_info "First non-interactive start:"
653
+ list_item "karnel robin start --accept-responsible-use"
654
+ log_info "Documentacao: $ROBIN_DOCS_URL"
655
+ echo
656
+ }
@@ -44,6 +44,7 @@ search_main() {
44
44
  echo
45
45
  separator_section "Brain Memories"
46
46
  echo
47
+ any_found=false
47
48
  if [[ -d "$KARNEL_DATA/brain" ]]; then
48
49
  while IFS= read -r file; do
49
50
  local title
@@ -19,6 +19,7 @@ show_main() {
19
19
  list_item "karnel show db --postgresql"
20
20
  list_item "karnel show dev --gh"
21
21
  list_item "karnel show npm --typescript"
22
+ list_item "karnel show osint --robin"
22
23
  list_item "karnel show backup Show backup docs"
23
24
  list_item "karnel show restore Show restore docs"
24
25
  list_item "karnel show all --<tool>"