karnel-termux 4.9.5 → 4.10.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.
- package/README.md +31 -1
- package/karnel/cli/commands/install.sh +11 -0
- package/karnel/cli/commands/list.sh +32 -0
- package/karnel/cli/commands/open.sh +6 -0
- package/karnel/cli/commands/plugin.sh +147 -0
- package/karnel/cli/commands/reinstall.sh +8 -0
- package/karnel/cli/commands/uninstall.sh +8 -0
- package/karnel/cli/commands/update.sh +8 -0
- package/karnel/cli/karnel.sh +14 -6
- package/karnel/modules/plugin.sh +34 -0
- package/karnel/modules/security.sh +22 -0
- package/karnel/tools/ai/opencode/install.sh +38 -131
- package/karnel/tools/plugins/install.sh +150 -0
- package/karnel/tools/security/all.sh +42 -0
- package/karnel/tools/security/template.sh +35 -0
- package/karnel/utils/banner.sh +36 -22
- package/karnel/utils/bootstrap.sh +3 -0
- package/karnel/utils/env.sh +2 -1
- package/karnel/utils/install.sh +107 -0
- package/karnel/utils/proot.sh +26 -0
- package/package.json +1 -1
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.9.
|
|
11
|
+
<img src="https://img.shields.io/badge/version-4.9.6-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">
|
|
@@ -44,6 +44,8 @@ Created by **Israel Marques**.
|
|
|
44
44
|
- **Professional editor** — code-server (VS Code in browser)
|
|
45
45
|
- **Second brain** — Memory system with AI search and idea graph
|
|
46
46
|
- **Voice commands** — Speak to your AI agents
|
|
47
|
+
- **Plugin system** — Install community plugins from GitHub: `karnel plugin install <user/repo>`
|
|
48
|
+
- **Security tools** — Nmap, Hydra, SQLMap, Metasploit and more: `karnel install security`
|
|
47
49
|
|
|
48
50
|
> [!IMPORTANT]
|
|
49
51
|
> Designed exclusively for **Termux on Android**. Does not work on other platforms.
|
|
@@ -125,6 +127,34 @@ karnel
|
|
|
125
127
|
| `utils` | fconv, notes, treex, passman, applaunch, qrcode, zork and more | `karnel install utils` |
|
|
126
128
|
| `osint` | Robin v2.8, Tor, Streamlit, and LLM providers | `karnel install osint` |
|
|
127
129
|
| `voice` | Speech-to-agent through Termux:API | `karnel install voice` |
|
|
130
|
+
| `plugin` | Plugin manager — install extensions from GitHub | `karnel install plugin` |
|
|
131
|
+
| `security` | Nmap, Hydra, SQLMap, Metasploit, Gobuster and more | `karnel install security` |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Plugin System
|
|
136
|
+
|
|
137
|
+
Extend Karnel with community plugins from GitHub:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
karnel plugin install <user/repo> # Install a plugin
|
|
141
|
+
karnel plugin list # List installed plugins
|
|
142
|
+
karnel plugin remove <name> # Uninstall a plugin
|
|
143
|
+
karnel plugin create <name> # Scaffold a new plugin
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Each plugin needs a `karnel-plugin.json` manifest at the root of its repo. Commands go in a `commands/` directory — Karnel discovers them automatically at startup.
|
|
147
|
+
|
|
148
|
+
## Security Tools
|
|
149
|
+
|
|
150
|
+
Install security auditing tools:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
karnel install security # Install all
|
|
154
|
+
karnel install security --nmap --hydra --sqlmap # Install specific ones
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Includes: Nmap, Hydra, Nikto, SQLMap, Gobuster, Dirb, WPScan, John the Ripper, Aircrack-ng, Metasploit.
|
|
128
158
|
|
|
129
159
|
---
|
|
130
160
|
|
|
@@ -152,6 +152,14 @@ _install_full_module() {
|
|
|
152
152
|
import "@/modules/utils"
|
|
153
153
|
install_utils
|
|
154
154
|
;;
|
|
155
|
+
plugin)
|
|
156
|
+
import "@/modules/plugin"
|
|
157
|
+
install_plugin_module
|
|
158
|
+
;;
|
|
159
|
+
security)
|
|
160
|
+
import "@/modules/security"
|
|
161
|
+
install_security
|
|
162
|
+
;;
|
|
155
163
|
*)
|
|
156
164
|
log_warn "Unknown install target: $target"
|
|
157
165
|
echo "Run 'karnel install' to see available targets"
|
|
@@ -806,6 +814,9 @@ _install_specific_tools() {
|
|
|
806
814
|
utils)
|
|
807
815
|
_batch_tool_action "utils" "install" "${tools[@]}"
|
|
808
816
|
;;
|
|
817
|
+
security)
|
|
818
|
+
_batch_tool_action "security" "install" "${tools[@]}"
|
|
819
|
+
;;
|
|
809
820
|
*)
|
|
810
821
|
log_warn "Unknown install target: $module"
|
|
811
822
|
echo "Run 'karnel install' to see available targets"
|
|
@@ -76,6 +76,14 @@ list_main() {
|
|
|
76
76
|
utils)
|
|
77
77
|
_list_utils
|
|
78
78
|
;;
|
|
79
|
+
plugin)
|
|
80
|
+
import "@/tools/plugins/install"
|
|
81
|
+
echo "Installed Plugins:"
|
|
82
|
+
_list_plugins
|
|
83
|
+
;;
|
|
84
|
+
security)
|
|
85
|
+
_list_security
|
|
86
|
+
;;
|
|
79
87
|
voice)
|
|
80
88
|
_list_voice
|
|
81
89
|
;;
|
|
@@ -523,6 +531,30 @@ _grep_config() {
|
|
|
523
531
|
fi
|
|
524
532
|
}
|
|
525
533
|
|
|
534
|
+
# ===== LIST SECURITY =====
|
|
535
|
+
_list_security() {
|
|
536
|
+
echo
|
|
537
|
+
box "Security Tools"
|
|
538
|
+
echo
|
|
539
|
+
log_info "Available security tools:"
|
|
540
|
+
echo
|
|
541
|
+
table_start "Tool" "Install Flag" "Command" "Status"
|
|
542
|
+
table_row "Nmap" "--nmap" "nmap" "$(_check_cmd "nmap")"
|
|
543
|
+
table_row "Hydra" "--hydra" "hydra" "$(_check_cmd "hydra")"
|
|
544
|
+
table_row "Nikto" "--nikto" "nikto" "$(_check_cmd "nikto")"
|
|
545
|
+
table_row "SQLMap" "--sqlmap" "sqlmap" "$(_check_cmd "sqlmap")"
|
|
546
|
+
table_row "Gobuster" "--gobuster" "gobuster" "$(_check_cmd "gobuster")"
|
|
547
|
+
table_row "Dirb" "--dirb" "dirb" "$(_check_cmd "dirb")"
|
|
548
|
+
table_row "WPScan" "--wpscan" "wpscan" "$(_check_cmd "wpscan")"
|
|
549
|
+
table_row "John the Ripper" "--john" "john" "$(_check_cmd "john")"
|
|
550
|
+
table_row "Aircrack-ng" "--aircrack-ng" "aircrack-ng" "$(_check_cmd "aircrack-ng")"
|
|
551
|
+
table_row "Metasploit" "--metasploit" "msfconsole" "$(_check_cmd "msfconsole")"
|
|
552
|
+
table_end
|
|
553
|
+
echo
|
|
554
|
+
log_info "Install all: ${D_CYAN}karnel install security${NC}"
|
|
555
|
+
echo
|
|
556
|
+
}
|
|
557
|
+
|
|
526
558
|
# ===== LIST VOICE =====
|
|
527
559
|
_list_voice() {
|
|
528
560
|
echo
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import "@/tools/plugins/install"
|
|
2
|
+
|
|
3
|
+
plugin_main() {
|
|
4
|
+
if [[ $# -eq 0 ]]; then
|
|
5
|
+
plugin_help
|
|
6
|
+
return
|
|
7
|
+
fi
|
|
8
|
+
|
|
9
|
+
local subcmd="$1"
|
|
10
|
+
shift
|
|
11
|
+
|
|
12
|
+
case "$subcmd" in
|
|
13
|
+
install)
|
|
14
|
+
if [[ $# -lt 1 ]]; then
|
|
15
|
+
log_error "Usage: karnel plugin install <user/repo>"
|
|
16
|
+
return 1
|
|
17
|
+
fi
|
|
18
|
+
install_plugin "$1"
|
|
19
|
+
;;
|
|
20
|
+
remove|uninstall)
|
|
21
|
+
if [[ $# -lt 1 ]]; then
|
|
22
|
+
log_error "Usage: karnel plugin remove <name>"
|
|
23
|
+
return 1
|
|
24
|
+
fi
|
|
25
|
+
uninstall_plugin "$1"
|
|
26
|
+
;;
|
|
27
|
+
update)
|
|
28
|
+
if [[ $# -lt 1 ]]; then
|
|
29
|
+
log_error "Usage: karnel plugin update <name>"
|
|
30
|
+
return 1
|
|
31
|
+
fi
|
|
32
|
+
update_plugin "$1"
|
|
33
|
+
;;
|
|
34
|
+
list|ls)
|
|
35
|
+
_list_plugins
|
|
36
|
+
;;
|
|
37
|
+
search)
|
|
38
|
+
_search_plugins
|
|
39
|
+
;;
|
|
40
|
+
create|scaffold)
|
|
41
|
+
if [[ $# -lt 1 ]]; then
|
|
42
|
+
log_error "Usage: karnel plugin create <name>"
|
|
43
|
+
return 1
|
|
44
|
+
fi
|
|
45
|
+
_scaffold_plugin "$1"
|
|
46
|
+
;;
|
|
47
|
+
*)
|
|
48
|
+
log_error "Unknown plugin subcommand: $subcmd"
|
|
49
|
+
plugin_help
|
|
50
|
+
return 1
|
|
51
|
+
;;
|
|
52
|
+
esac
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
plugin_help() {
|
|
56
|
+
echo
|
|
57
|
+
box "Plugin Manager"
|
|
58
|
+
echo
|
|
59
|
+
log_info "Usage: karnel plugin <subcommand> [options]"
|
|
60
|
+
echo
|
|
61
|
+
separator_section "Subcommands"
|
|
62
|
+
echo
|
|
63
|
+
printf " ${D_CYAN}%-20s${NC} %s\n" "install <user/repo>" "Install a plugin from GitHub"
|
|
64
|
+
printf " ${D_CYAN}%-20s${NC} %s\n" "remove <name>" "Uninstall a plugin"
|
|
65
|
+
printf " ${D_CYAN}%-20s${NC} %s\n" "update <name>" "Update a plugin"
|
|
66
|
+
printf " ${D_CYAN}%-20s${NC} %s\n" "list" "List installed plugins"
|
|
67
|
+
printf " ${D_CYAN}%-20s${NC} %s\n" "search" "Search available plugins in the registry"
|
|
68
|
+
printf " ${D_CYAN}%-20s${NC} %s\n" "create <name>" "Scaffold a new plugin"
|
|
69
|
+
echo
|
|
70
|
+
echo "Plugins are installed from GitHub repos."
|
|
71
|
+
echo "Each plugin must have a karnel-plugin.json manifest at root."
|
|
72
|
+
echo
|
|
73
|
+
separator_section "Examples"
|
|
74
|
+
echo
|
|
75
|
+
echo " karnel plugin install username/my-karnel-plugin"
|
|
76
|
+
echo " karnel plugin list"
|
|
77
|
+
echo " karnel plugin remove my-karnel-plugin"
|
|
78
|
+
echo " karnel plugin search"
|
|
79
|
+
echo " karnel plugin create my-plugin"
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_search_plugins() {
|
|
83
|
+
local registry_url="https://raw.githubusercontent.com/israelmarques1024-dotcom/karnel-plugins/main/registry.json"
|
|
84
|
+
log_info "Fetching plugin registry..."
|
|
85
|
+
local data
|
|
86
|
+
data="$(curl -sfL "$registry_url" 2>/dev/null)" || {
|
|
87
|
+
log_error "Failed to fetch registry. Check internet connection."
|
|
88
|
+
return 1
|
|
89
|
+
}
|
|
90
|
+
local count
|
|
91
|
+
count="$(echo "$data" | sed -n 's/.*"plugins": \[\(.*\)\]/\1/p' | grep -o '"name"' | wc -l)"
|
|
92
|
+
if [[ "$count" -eq 0 ]]; then
|
|
93
|
+
echo " No plugins available in the registry yet."
|
|
94
|
+
echo " Be the first: https://github.com/israelmarques1024-dotcom/karnel-plugins"
|
|
95
|
+
return 0
|
|
96
|
+
fi
|
|
97
|
+
echo
|
|
98
|
+
box "Available Plugins ($count)"
|
|
99
|
+
echo
|
|
100
|
+
local names
|
|
101
|
+
names="$(echo "$data" | sed 's/.*"plugins":\[//;s/\]$//' | tr '}' '\n' | while IFS= read -r entry; do
|
|
102
|
+
[[ -z "$entry" ]] && continue
|
|
103
|
+
local n d r c
|
|
104
|
+
n="$(echo "$entry" | sed -n 's/.*"name":"\([^"]*\)".*/\1/p')"
|
|
105
|
+
d="$(echo "$entry" | sed -n 's/.*"description":"\([^"]*\)".*/\1/p')"
|
|
106
|
+
r="$(echo "$entry" | sed -n 's/.*"repo":"\([^"]*\)".*/\1/p')"
|
|
107
|
+
printf " ${D_GREEN}%-20s${NC} %s\n" "$n" "$d"
|
|
108
|
+
printf " ${D_CYAN} install:${NC} karnel plugin install %s\n" "$r"
|
|
109
|
+
done)"
|
|
110
|
+
echo "$names"
|
|
111
|
+
echo
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
_scaffold_plugin() {
|
|
115
|
+
local name="$1"
|
|
116
|
+
local dir="$(_plugin_dir "$name")"
|
|
117
|
+
|
|
118
|
+
if [[ -d "$dir" ]]; then
|
|
119
|
+
log_error "Plugin '$name' already exists"
|
|
120
|
+
return 1
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
mkdir -p "$dir/commands" "$dir/tools"
|
|
124
|
+
|
|
125
|
+
cat > "$dir/karnel-plugin.json" <<EOF
|
|
126
|
+
{
|
|
127
|
+
"name": "$name",
|
|
128
|
+
"version": "1.0.0",
|
|
129
|
+
"description": "My Karnel plugin",
|
|
130
|
+
"commands": ["hello"],
|
|
131
|
+
"tools": []
|
|
132
|
+
}
|
|
133
|
+
EOF
|
|
134
|
+
|
|
135
|
+
cat > "$dir/commands/hello.sh" <<'EOF'
|
|
136
|
+
hello_main() {
|
|
137
|
+
echo "Hello from plugin '$1'!"
|
|
138
|
+
echo "Args: $*"
|
|
139
|
+
}
|
|
140
|
+
EOF
|
|
141
|
+
|
|
142
|
+
chmod +x "$dir/commands/"*.sh
|
|
143
|
+
log_success "Plugin '$name' scaffolded at $dir"
|
|
144
|
+
echo "Edit $dir/karnel-plugin.json to configure"
|
|
145
|
+
echo "Add commands in $dir/commands/"
|
|
146
|
+
echo "Run: karnel hello"
|
|
147
|
+
}
|
|
@@ -143,6 +143,14 @@ _reinstall_full_module() {
|
|
|
143
143
|
import "@/modules/utils"
|
|
144
144
|
reinstall_utils
|
|
145
145
|
;;
|
|
146
|
+
plugin)
|
|
147
|
+
import "@/modules/plugin"
|
|
148
|
+
reinstall_plugin_module
|
|
149
|
+
;;
|
|
150
|
+
security)
|
|
151
|
+
import "@/modules/security"
|
|
152
|
+
reinstall_security
|
|
153
|
+
;;
|
|
146
154
|
*)
|
|
147
155
|
log_warn "Unknown reinstall target: $target"
|
|
148
156
|
echo "Run 'karnel reinstall' to see available targets"
|
|
@@ -137,6 +137,14 @@ _uninstall_full_module() {
|
|
|
137
137
|
import "@/modules/utils"
|
|
138
138
|
uninstall_utils
|
|
139
139
|
;;
|
|
140
|
+
plugin)
|
|
141
|
+
import "@/modules/plugin"
|
|
142
|
+
uninstall_plugin_module
|
|
143
|
+
;;
|
|
144
|
+
security)
|
|
145
|
+
import "@/modules/security"
|
|
146
|
+
uninstall_security
|
|
147
|
+
;;
|
|
140
148
|
games)
|
|
141
149
|
import "@/tools/games/all"
|
|
142
150
|
uninstall_all_games
|
|
@@ -143,6 +143,14 @@ _update_full_module() {
|
|
|
143
143
|
import "@/modules/utils"
|
|
144
144
|
update_utils
|
|
145
145
|
;;
|
|
146
|
+
plugin)
|
|
147
|
+
import "@/modules/plugin"
|
|
148
|
+
update_plugin_module
|
|
149
|
+
;;
|
|
150
|
+
security)
|
|
151
|
+
import "@/modules/security"
|
|
152
|
+
update_security
|
|
153
|
+
;;
|
|
146
154
|
deploy)
|
|
147
155
|
import "@/modules/deploy"
|
|
148
156
|
update_deploy
|
package/karnel/cli/karnel.sh
CHANGED
|
@@ -36,16 +36,21 @@ karnel_main() {
|
|
|
36
36
|
|
|
37
37
|
local command_file="$KARNEL_PATH/cli/commands/$cmd.sh"
|
|
38
38
|
|
|
39
|
-
# verificar si existe el comando
|
|
40
39
|
if [[ -f "$command_file" ]]; then
|
|
41
40
|
import "@/cli/commands/$cmd"
|
|
42
41
|
"${cmd}_main" "$@"
|
|
43
|
-
|
|
44
|
-
log_error "Command not found: $cmd"
|
|
45
|
-
echo
|
|
46
|
-
karnel_help
|
|
47
|
-
return 1
|
|
42
|
+
return $?
|
|
48
43
|
fi
|
|
44
|
+
|
|
45
|
+
import "@/tools/plugins/install"
|
|
46
|
+
if _plugin_dispatch "$cmd" "$@"; then
|
|
47
|
+
return $?
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
log_error "Command not found: $cmd"
|
|
51
|
+
echo
|
|
52
|
+
karnel_help
|
|
53
|
+
return 1
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
karnel_help() {
|
|
@@ -72,6 +77,7 @@ karnel_help() {
|
|
|
72
77
|
printf " ${D_CYAN}%-12s${NC} %s\n" "list" "List available tools in a module"
|
|
73
78
|
printf " ${D_CYAN}%-12s${NC} %s\n" "open" "Open docs in browser for a module"
|
|
74
79
|
printf " ${D_CYAN}%-12s${NC} %s\n" "pg" "PostgreSQL database manager"
|
|
80
|
+
printf " ${D_CYAN}%-12s${NC} %s\n" "plugin" "Plugin manager — install, list, remove"
|
|
75
81
|
printf " ${D_CYAN}%-12s${NC} %s\n" "reinstall" "Uninstall + install a module"
|
|
76
82
|
printf " ${D_CYAN}%-12s${NC} %s\n" "restore" "Restore Termux from a backup"
|
|
77
83
|
printf " ${D_CYAN}%-12s${NC} %s\n" "robin" "Dark Web OSINT tool (Tor + LLM)"
|
|
@@ -109,6 +115,8 @@ karnel_help() {
|
|
|
109
115
|
printf " ${D_GREEN}%-10s${NC} %s\n" "npm" "Node.js global npm packages"
|
|
110
116
|
printf " ${D_GREEN}%-10s${NC} %s\n" "osint" "OSINT Tools (Robin — Dark Web + LLM)"
|
|
111
117
|
printf " ${D_GREEN}%-10s${NC} %s\n" "network" "Network tools (Dark Web, DedSec Network)"
|
|
118
|
+
printf " ${D_GREEN}%-10s${NC} %s\n" "plugin" "Plugin manager — install plugins from GitHub"
|
|
119
|
+
printf " ${D_GREEN}%-10s${NC} %s\n" "security" "Nmap, Hydra, Metasploit, SQLMap, Gobuster, etc."
|
|
112
120
|
printf " ${D_GREEN}%-10s${NC} %s\n" "shell" "ZSH + Oh My Zsh + 10 plugins"
|
|
113
121
|
printf " ${D_GREEN}%-10s${NC} %s\n" "ui" "Font, Cursor, Extra-keys, Banner"
|
|
114
122
|
printf " ${D_GREEN}%-10s${NC} %s\n" "voice" "Speech-to-agent via microphone"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
install_plugin_module() {
|
|
2
|
+
separator
|
|
3
|
+
box "Plugin Manager"
|
|
4
|
+
separator
|
|
5
|
+
|
|
6
|
+
log_info "Plugin system is built-in. No additional installation needed."
|
|
7
|
+
echo
|
|
8
|
+
log_info "Installing example plugin..."
|
|
9
|
+
install_plugin "israelmarques1024-dotcom/karnel-termux" || true
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
uninstall_plugin_module() {
|
|
13
|
+
log_info "Plugin system is built-in. Nothing to uninstall."
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
update_plugin_module() {
|
|
17
|
+
log_info "Updating all plugins..."
|
|
18
|
+
mkdir -p "$PLUGINS_DIR"
|
|
19
|
+
for dir in "$PLUGINS_DIR"/*/; do
|
|
20
|
+
[[ -d "$dir" ]] || continue
|
|
21
|
+
local name; name="$(basename "$dir")"
|
|
22
|
+
update_plugin "$name"
|
|
23
|
+
done
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
reinstall_plugin_module() {
|
|
27
|
+
log_info "Reinstalling all plugins..."
|
|
28
|
+
mkdir -p "$PLUGINS_DIR"
|
|
29
|
+
for dir in "$PLUGINS_DIR"/*/; do
|
|
30
|
+
[[ -d "$dir" ]] || continue
|
|
31
|
+
local name; name="$(basename "$dir")"
|
|
32
|
+
reinstall_plugin "$name"
|
|
33
|
+
done
|
|
34
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
install_security() {
|
|
2
|
+
separator
|
|
3
|
+
box "Installing Security Tools"
|
|
4
|
+
separator
|
|
5
|
+
import "@/tools/security/all"
|
|
6
|
+
install_all_security
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
uninstall_security() {
|
|
10
|
+
import "@/tools/security/all"
|
|
11
|
+
uninstall_all_security
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
update_security() {
|
|
15
|
+
import "@/tools/security/all"
|
|
16
|
+
update_all_security
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
reinstall_security() {
|
|
20
|
+
import "@/tools/security/all"
|
|
21
|
+
reinstall_all_security
|
|
22
|
+
}
|
|
@@ -3,54 +3,18 @@
|
|
|
3
3
|
import "@/utils/log"
|
|
4
4
|
import "@/utils/version"
|
|
5
5
|
import "@/utils/colors"
|
|
6
|
+
import "@/utils/proot"
|
|
7
|
+
import "@/utils/install"
|
|
6
8
|
|
|
7
9
|
LOG_FILE="$KARNEL_CACHE/install_ai.log"
|
|
8
10
|
OPENCODE_DATA_DIR="$HOME/.local/share/karnel-data/opencode"
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
root="$(find /data/data/com.termux -maxdepth 10 -type d \
|
|
13
|
-
-name "rootfs" -path "*/containers/ubuntu/*" 2>/dev/null | head -1)"
|
|
14
|
-
|
|
15
|
-
if [ -z "$root" ]; then
|
|
16
|
-
root="$(find /data/data/com.termux -maxdepth 10 -type d \
|
|
17
|
-
-name "ubuntu" -path "*/installed-rootfs/*" 2>/dev/null | head -1)"
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
echo "$root"
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
_opencode_proot_ubuntu() {
|
|
24
|
-
proot-distro login \
|
|
25
|
-
--shared-tmp \
|
|
26
|
-
ubuntu \
|
|
27
|
-
-- "$@"
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
_get_latest_opencode_version() {
|
|
31
|
-
curl -fsSL https://api.github.com/repos/anomalyco/opencode/releases/latest |
|
|
32
|
-
grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'
|
|
12
|
+
_install_opencode_deps() {
|
|
13
|
+
loading "Installing glibc and dependencies" _install_opencode_deps_impl
|
|
33
14
|
}
|
|
34
15
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
_opencode_install_deps_native_impl() {
|
|
40
|
-
if [[ ! -f $PREFIX/etc/apt/sources.list.d/glibc.list ]]; then
|
|
41
|
-
if ! pkg install glibc-repo -y &>>"$LOG_FILE"; then
|
|
42
|
-
log_error "Failed to install glibc-repo"
|
|
43
|
-
return 1
|
|
44
|
-
fi
|
|
45
|
-
fi
|
|
46
|
-
|
|
47
|
-
if [[ ! -f $PREFIX/glibc/lib/libc.so.6 ]]; then
|
|
48
|
-
if ! pkg install glibc -y &>>"$LOG_FILE"; then
|
|
49
|
-
log_error "Failed to install glibc"
|
|
50
|
-
return 1
|
|
51
|
-
fi
|
|
52
|
-
fi
|
|
53
|
-
|
|
16
|
+
_install_opencode_deps_impl() {
|
|
17
|
+
install_glibc || return 1
|
|
54
18
|
declare -A DEPS=(
|
|
55
19
|
["git"]="git"
|
|
56
20
|
["ripgrep"]="rg"
|
|
@@ -61,18 +25,7 @@ _opencode_install_deps_native_impl() {
|
|
|
61
25
|
["curl"]="curl"
|
|
62
26
|
["tar"]="tar"
|
|
63
27
|
)
|
|
64
|
-
|
|
65
|
-
local pkg_name bin_name
|
|
66
|
-
for pkg_name in "${!DEPS[@]}"; do
|
|
67
|
-
bin_name="${DEPS[$pkg_name]}"
|
|
68
|
-
if ! command -v "$bin_name" &>/dev/null; then
|
|
69
|
-
if ! pkg install "$pkg_name" -y &>>"$LOG_FILE"; then
|
|
70
|
-
log_error "Failed to install $pkg_name"
|
|
71
|
-
return 1
|
|
72
|
-
fi
|
|
73
|
-
fi
|
|
74
|
-
done
|
|
75
|
-
|
|
28
|
+
install_deps DEPS || return 1
|
|
76
29
|
return 0
|
|
77
30
|
}
|
|
78
31
|
|
|
@@ -82,34 +35,21 @@ _download_opencode_binary() {
|
|
|
82
35
|
|
|
83
36
|
_download_opencode_binary_impl() {
|
|
84
37
|
local latest_version
|
|
85
|
-
latest_version=$(
|
|
38
|
+
latest_version=$(github_latest_tag anomalyco/opencode)
|
|
86
39
|
if [ -z "$latest_version" ]; then
|
|
87
40
|
log_error "Failed to fetch latest OpenCode version"
|
|
88
41
|
return 1
|
|
89
42
|
fi
|
|
90
43
|
|
|
91
44
|
mkdir -p "$OPENCODE_DATA_DIR"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if ! curl -fsSL "$download_url" -o "$OPENCODE_DATA_DIR/$tarball" &>>"$LOG_FILE"; then
|
|
97
|
-
log_error "Failed to download OpenCode binary"
|
|
98
|
-
return 1
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
if ! tar -zxf "$OPENCODE_DATA_DIR/$tarball" -C "$OPENCODE_DATA_DIR" &>>"$LOG_FILE"; then
|
|
102
|
-
log_error "Failed to extract OpenCode binary"
|
|
103
|
-
return 1
|
|
104
|
-
fi
|
|
105
|
-
|
|
106
|
-
rm -f "$OPENCODE_DATA_DIR/$tarball"
|
|
45
|
+
github_download_and_extract \
|
|
46
|
+
anomalyco/opencode "$latest_version" \
|
|
47
|
+
"opencode-linux-arm64.tar.gz" "$OPENCODE_DATA_DIR" || return 1
|
|
107
48
|
|
|
108
49
|
if [ ! -f "$OPENCODE_DATA_DIR/opencode" ]; then
|
|
109
50
|
log_error "OpenCode binary not found after extraction"
|
|
110
51
|
return 1
|
|
111
52
|
fi
|
|
112
|
-
|
|
113
53
|
chmod +x "$OPENCODE_DATA_DIR/opencode"
|
|
114
54
|
return 0
|
|
115
55
|
}
|
|
@@ -119,23 +59,14 @@ _compile_opencode_helper() {
|
|
|
119
59
|
}
|
|
120
60
|
|
|
121
61
|
_compile_opencode_helper_impl() {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return 1
|
|
126
|
-
fi
|
|
127
|
-
|
|
128
|
-
if ! cc -O2 -o "$PREFIX/bin/opencode" "$HELPER_SRC" &>>"$LOG_FILE"; then
|
|
129
|
-
log_error "Failed to compile opencode helper"
|
|
130
|
-
return 1
|
|
131
|
-
fi
|
|
132
|
-
|
|
133
|
-
chmod +x "$PREFIX/bin/opencode"
|
|
62
|
+
compile_helper \
|
|
63
|
+
"$KARNEL_PATH/tools/ai/opencode/helper/opencode_helper.c" \
|
|
64
|
+
"$PREFIX/bin/opencode" || return 1
|
|
134
65
|
return 0
|
|
135
66
|
}
|
|
136
67
|
|
|
137
68
|
_install_opencode_native() {
|
|
138
|
-
|
|
69
|
+
_install_opencode_deps || return 1
|
|
139
70
|
_download_opencode_binary || return 1
|
|
140
71
|
_compile_opencode_helper || return 1
|
|
141
72
|
log_success "OpenCode installed natively"
|
|
@@ -148,48 +79,35 @@ _install_opencode_proot() {
|
|
|
148
79
|
|
|
149
80
|
_install_opencode_proot_impl() {
|
|
150
81
|
mkdir -p "$(dirname "$LOG_FILE")"
|
|
82
|
+
proot_install_ubuntu ubuntu:24.04
|
|
151
83
|
|
|
152
|
-
|
|
153
|
-
pkg install proot-distro -y &>>"$LOG_FILE"
|
|
154
|
-
fi
|
|
155
|
-
|
|
156
|
-
if [ ! -d "$(_opencode_detect_ubuntu_root)" ]; then
|
|
157
|
-
proot-distro install ubuntu:24.04 &>>"$LOG_FILE"
|
|
158
|
-
fi
|
|
159
|
-
|
|
160
|
-
_opencode_proot_ubuntu /bin/bash -c \
|
|
84
|
+
proot_ubuntu /bin/bash -c \
|
|
161
85
|
'apt-get update && apt-get upgrade -y && apt-get install -y curl ca-certificates' \
|
|
162
86
|
&>>"$LOG_FILE"
|
|
163
87
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
88
|
+
proot_ubuntu /bin/bash -c '
|
|
89
|
+
export SHELL=/bin/bash
|
|
90
|
+
export TMPDIR=/tmp
|
|
91
|
+
export HOME=/root
|
|
92
|
+
curl -fsSL https://opencode.ai/install | bash -s -- --no-modify-path
|
|
93
|
+
' &>>"$LOG_FILE"
|
|
170
94
|
|
|
171
95
|
local ubuntu_root
|
|
172
|
-
ubuntu_root="$(
|
|
173
|
-
|
|
96
|
+
ubuntu_root="$(detect_ubuntu_root)"
|
|
174
97
|
if [ -z "$ubuntu_root" ]; then
|
|
175
98
|
log_error "Ubuntu rootfs not found"
|
|
176
99
|
return 1
|
|
177
100
|
fi
|
|
178
101
|
|
|
179
102
|
local opencode_bin="$ubuntu_root/root/.opencode/bin/opencode"
|
|
180
|
-
|
|
181
103
|
if [ ! -f "$opencode_bin" ]; then
|
|
182
104
|
log_error "OpenCode binary not found after install"
|
|
183
105
|
return 1
|
|
184
106
|
fi
|
|
185
107
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return 1
|
|
190
|
-
fi
|
|
191
|
-
sed "s|__UBUNTU_ROOTFS__|$ubuntu_root|g" "$wrapper_src" >"$PREFIX/bin/opencode"
|
|
192
|
-
chmod +x "$PREFIX/bin/opencode"
|
|
108
|
+
generate_wrapper \
|
|
109
|
+
"$KARNEL_PATH/tools/ai/opencode/bin/opencode" \
|
|
110
|
+
"$ubuntu_root" "$PREFIX/bin/opencode" || return 1
|
|
193
111
|
|
|
194
112
|
if ! grep -q '.opencode/bin' "$ubuntu_root/root/.bashrc" 2>/dev/null; then
|
|
195
113
|
printf '\n# opencode\nexport PATH=/root/.opencode/bin:$PATH\n' >>"$ubuntu_root/root/.bashrc"
|
|
@@ -205,18 +123,13 @@ install_opencode() {
|
|
|
205
123
|
fi
|
|
206
124
|
|
|
207
125
|
log_info "Select installation method for OpenCode:"
|
|
208
|
-
|
|
209
126
|
read_select "Installation method" SELECTED_METHOD \
|
|
210
127
|
"Native (recommended) - Compile with glibc support" \
|
|
211
128
|
"Proot-distro (alternative) - Ubuntu container"
|
|
212
129
|
|
|
213
130
|
case "$SELECTED_METHOD" in
|
|
214
|
-
*Native*)
|
|
215
|
-
|
|
216
|
-
;;
|
|
217
|
-
*Proot-distro*)
|
|
218
|
-
_install_opencode_proot
|
|
219
|
-
;;
|
|
131
|
+
*Native*) _install_opencode_native ;;
|
|
132
|
+
*Proot-distro*) _install_opencode_proot ;;
|
|
220
133
|
esac
|
|
221
134
|
}
|
|
222
135
|
|
|
@@ -236,13 +149,11 @@ uninstall_opencode() {
|
|
|
236
149
|
return 0
|
|
237
150
|
fi
|
|
238
151
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if [ -f "$ubuntu_bashrc" ]; then
|
|
245
|
-
sed -i '/# opencode/d; /export PATH=\/root\/.opencode\/bin/d' "$ubuntu_bashrc"
|
|
152
|
+
proot_ubuntu /bin/bash -c 'rm -rf /root/.opencode' &>>"$LOG_FILE"
|
|
153
|
+
local ubuntu_root
|
|
154
|
+
ubuntu_root="$(detect_ubuntu_root)/root/.bashrc"
|
|
155
|
+
if [ -f "$ubuntu_root" ]; then
|
|
156
|
+
sed -i '/# opencode/d; /export PATH=\/root\/.opencode\/bin/d' "$ubuntu_root"
|
|
246
157
|
fi
|
|
247
158
|
|
|
248
159
|
if rm -f "$PREFIX/bin/opencode" &>>"$LOG_FILE"; then
|
|
@@ -264,9 +175,8 @@ _do_update_opencode() {
|
|
|
264
175
|
return $?
|
|
265
176
|
fi
|
|
266
177
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
_opencode_proot_ubuntu /bin/bash -c '
|
|
178
|
+
proot_ubuntu /bin/bash -c 'rm -rf /root/.opencode' &>>"$LOG_FILE"
|
|
179
|
+
proot_ubuntu /bin/bash -c '
|
|
270
180
|
export SHELL=/bin/bash
|
|
271
181
|
export TMPDIR=/tmp
|
|
272
182
|
export HOME=/root
|
|
@@ -274,14 +184,11 @@ _do_update_opencode() {
|
|
|
274
184
|
' &>>"$LOG_FILE"
|
|
275
185
|
|
|
276
186
|
local ubuntu_root
|
|
277
|
-
ubuntu_root="$(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if [ ! -f "$opencode_bin" ]; then
|
|
187
|
+
ubuntu_root="$(detect_ubuntu_root)"
|
|
188
|
+
if [ -z "$ubuntu_root" ] || [ ! -f "$ubuntu_root/root/.opencode/bin/opencode" ]; then
|
|
281
189
|
log_error "OpenCode binary not found after update"
|
|
282
190
|
return 1
|
|
283
191
|
fi
|
|
284
|
-
|
|
285
192
|
return 0
|
|
286
193
|
}
|
|
287
194
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
PLUGINS_DIR="${KARNEL_DATA}/plugins"
|
|
2
|
+
|
|
3
|
+
_plugin_dir() {
|
|
4
|
+
echo "$PLUGINS_DIR/$1"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
_plugin_manifest() {
|
|
8
|
+
echo "$(_plugin_dir "$1")/karnel-plugin.json"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
_plugin_installed() {
|
|
12
|
+
[[ -f "$(_plugin_manifest "$1")" ]]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
_plugin_name_from_repo() {
|
|
16
|
+
local repo="$1"
|
|
17
|
+
basename "$repo" | sed 's/\.git$//'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
install_plugin() {
|
|
21
|
+
local repo="$1"
|
|
22
|
+
local name
|
|
23
|
+
name="$(_plugin_name_from_repo "$repo")"
|
|
24
|
+
|
|
25
|
+
if _plugin_installed "$name"; then
|
|
26
|
+
log_info "Plugin '$name' is already installed"
|
|
27
|
+
return 2
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
mkdir -p "$PLUGINS_DIR"
|
|
31
|
+
log_info "Installing plugin '$name' from $repo..."
|
|
32
|
+
|
|
33
|
+
if ! git clone "https://github.com/$repo.git" "$(_plugin_dir "$name")" 2>/dev/null; then
|
|
34
|
+
log_error "Failed to clone $repo"
|
|
35
|
+
return 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
if [[ ! -f "$(_plugin_manifest "$name")" ]]; then
|
|
39
|
+
log_warn "Plugin '$name' has no karnel-plugin.json manifest"
|
|
40
|
+
log_info "Creating default manifest..."
|
|
41
|
+
cat > "$(_plugin_manifest "$name")" <<MANIFEST
|
|
42
|
+
{
|
|
43
|
+
"name": "$name",
|
|
44
|
+
"version": "1.0.0",
|
|
45
|
+
"description": "Plugin installed from $repo",
|
|
46
|
+
"commands": [],
|
|
47
|
+
"tools": []
|
|
48
|
+
}
|
|
49
|
+
MANIFEST
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
chmod +x "$(_plugin_dir "$name")/commands/"*.sh 2>/dev/null || true
|
|
53
|
+
|
|
54
|
+
log_success "Plugin '$name' installed"
|
|
55
|
+
return 0
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
uninstall_plugin() {
|
|
59
|
+
local name="$1"
|
|
60
|
+
|
|
61
|
+
if ! _plugin_installed "$name"; then
|
|
62
|
+
log_info "Plugin '$name' is not installed"
|
|
63
|
+
return 2
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
log_info "Removing plugin '$name'..."
|
|
67
|
+
rm -rf "$(_plugin_dir "$name")"
|
|
68
|
+
log_success "Plugin '$name' removed"
|
|
69
|
+
return 0
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
update_plugin() {
|
|
73
|
+
local name="$1"
|
|
74
|
+
|
|
75
|
+
if ! _plugin_installed "$name"; then
|
|
76
|
+
log_info "Plugin '$name' is not installed"
|
|
77
|
+
return 2
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
log_info "Updating plugin '$name'..."
|
|
81
|
+
if ! git -C "$(_plugin_dir "$name")" pull 2>/dev/null; then
|
|
82
|
+
log_error "Failed to update '$name'"
|
|
83
|
+
return 1
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
log_success "Plugin '$name' updated"
|
|
87
|
+
return 0
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
reinstall_plugin() {
|
|
91
|
+
local name="$1"
|
|
92
|
+
uninstall_plugin "$name"
|
|
93
|
+
local repo
|
|
94
|
+
repo="$(git -C "$(_plugin_dir "$name")" remote get-url origin 2>/dev/null || echo "")"
|
|
95
|
+
repo="${repo#https://github.com/}"
|
|
96
|
+
repo="${repo%.git}"
|
|
97
|
+
if [[ -n "$repo" ]]; then
|
|
98
|
+
install_plugin "$repo"
|
|
99
|
+
else
|
|
100
|
+
log_error "Cannot determine repository for '$name'"
|
|
101
|
+
return 1
|
|
102
|
+
fi
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
_list_plugins() {
|
|
106
|
+
mkdir -p "$PLUGINS_DIR"
|
|
107
|
+
local found=0
|
|
108
|
+
for dir in "$PLUGINS_DIR"/*/; do
|
|
109
|
+
[[ -d "$dir" ]] || continue
|
|
110
|
+
local name
|
|
111
|
+
name="$(basename "$dir")"
|
|
112
|
+
if [[ -f "$dir/karnel-plugin.json" ]]; then
|
|
113
|
+
local desc
|
|
114
|
+
desc="$(sed -n 's/.*"description": "\(.*\)",/\1/p' "$dir/karnel-plugin.json" 2>/dev/null || echo "No description")"
|
|
115
|
+
printf " ${D_GREEN}%-20s${NC} %s\n" "$name" "$desc"
|
|
116
|
+
found=1
|
|
117
|
+
fi
|
|
118
|
+
done
|
|
119
|
+
[[ $found -eq 0 ]] && echo " No plugins installed"
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
_plugin_commands() {
|
|
123
|
+
mkdir -p "$PLUGINS_DIR"
|
|
124
|
+
for dir in "$PLUGINS_DIR"/*/; do
|
|
125
|
+
[[ -d "$dir" ]] || continue
|
|
126
|
+
local cmd_dir="$dir/commands"
|
|
127
|
+
[[ -d "$cmd_dir" ]] || continue
|
|
128
|
+
for cmd_file in "$cmd_dir"/*.sh; do
|
|
129
|
+
[[ -f "$cmd_file" ]] || continue
|
|
130
|
+
local cmd_name
|
|
131
|
+
cmd_name="$(basename "$cmd_file" .sh)"
|
|
132
|
+
echo "$cmd_file:$cmd_name"
|
|
133
|
+
done
|
|
134
|
+
done
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
_plugin_dispatch() {
|
|
138
|
+
local cmd="$1"
|
|
139
|
+
shift
|
|
140
|
+
while IFS=':' read -r cmd_file cmd_name; do
|
|
141
|
+
if [[ "$cmd_name" == "$cmd" ]]; then
|
|
142
|
+
source "$cmd_file"
|
|
143
|
+
if declare -f "${cmd_name}_main" &>/dev/null; then
|
|
144
|
+
"${cmd_name}_main" "$@"
|
|
145
|
+
return $?
|
|
146
|
+
fi
|
|
147
|
+
fi
|
|
148
|
+
done < <(_plugin_commands)
|
|
149
|
+
return 1
|
|
150
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
SECURITY_TOOLS=(
|
|
2
|
+
"nmap"
|
|
3
|
+
"hydra"
|
|
4
|
+
"nikto"
|
|
5
|
+
"sqlmap"
|
|
6
|
+
"gobuster"
|
|
7
|
+
"dirb"
|
|
8
|
+
"wpscan"
|
|
9
|
+
"john"
|
|
10
|
+
"aircrack-ng"
|
|
11
|
+
"metasploit"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
for _tool in "${SECURITY_TOOLS[@]}"; do
|
|
15
|
+
source "$(dirname "${BASH_SOURCE[0]}")/$_tool/install.sh"
|
|
16
|
+
done
|
|
17
|
+
|
|
18
|
+
_batch_security() {
|
|
19
|
+
local action="$1"
|
|
20
|
+
local action_past="$2"
|
|
21
|
+
local -n count_var="$3"
|
|
22
|
+
for tool in "${SECURITY_TOOLS[@]}"; do
|
|
23
|
+
func_name="${action}_${tool//-/_}"
|
|
24
|
+
loading "${action_past^}ing ${tool}" "$func_name"
|
|
25
|
+
case $? in
|
|
26
|
+
0) ((count_var++)) ;;
|
|
27
|
+
2) ((skipped_count++)) ;;
|
|
28
|
+
1) ((failed_count++)) ;;
|
|
29
|
+
esac
|
|
30
|
+
done
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
install_all_security() {
|
|
34
|
+
local installed_count=0 skipped_count=0 failed_count=0
|
|
35
|
+
_batch_security "install" "install" installed_count
|
|
36
|
+
echo
|
|
37
|
+
log_success "Security: $installed_count installed, $skipped_count skipped, $failed_count failed"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
uninstall_all_security() { _batch_security "uninstall" "uninstall" _unused; }
|
|
41
|
+
update_all_security() { _batch_security "update" "update" _unused; }
|
|
42
|
+
reinstall_all_security() { _batch_security "reinstall" "reinstall" _unused; }
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Template for security tool installers.
|
|
2
|
+
# Copy this file and replace TOOL_NAME with the actual tool name.
|
|
3
|
+
|
|
4
|
+
_TOOL="tool"
|
|
5
|
+
_TOOL_PKG="$1"
|
|
6
|
+
|
|
7
|
+
install_${_TOOL}() {
|
|
8
|
+
if command -v "$_TOOL" &>/dev/null; then
|
|
9
|
+
log_info "$_TOOL is already installed"
|
|
10
|
+
return 2
|
|
11
|
+
fi
|
|
12
|
+
log_info "Installing $_TOOL..."
|
|
13
|
+
if pkg install -y "$_TOOL_PKG" 2>/dev/null || apt install -y "$_TOOL_PKG" 2>/dev/null; then
|
|
14
|
+
log_success "$_TOOL installed"
|
|
15
|
+
return 0
|
|
16
|
+
fi
|
|
17
|
+
log_error "Failed to install $_TOOL"
|
|
18
|
+
return 1
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
uninstall_${_TOOL}() {
|
|
22
|
+
log_info "Removing $_TOOL..."
|
|
23
|
+
pkg uninstall -y "$_TOOL_PKG" 2>/dev/null || true
|
|
24
|
+
log_success "$_TOOL removed"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
update_${_TOOL}() {
|
|
28
|
+
log_info "$_TOOL updated via package manager"
|
|
29
|
+
return 2
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
reinstall_${_TOOL}() {
|
|
33
|
+
uninstall_$_TOOL
|
|
34
|
+
install_$_TOOL
|
|
35
|
+
}
|
package/karnel/utils/banner.sh
CHANGED
|
@@ -103,23 +103,37 @@ _repeat() {
|
|
|
103
103
|
# ================================================================
|
|
104
104
|
# Counters
|
|
105
105
|
# ================================================================
|
|
106
|
-
_count_ai() {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
_count_ai() {
|
|
107
|
+
local reg="$KARNEL_PATH/tools/ai/all.sh"
|
|
108
|
+
local c=0
|
|
109
|
+
if [[ -f "$reg" ]]; then
|
|
110
|
+
while IFS= read -r line; do
|
|
111
|
+
[[ "$line" =~ ^[[:space:]]*\"([^\"]+)\" ]] || continue
|
|
112
|
+
local entry="${BASH_REMATCH[1]}"
|
|
113
|
+
local bin="${entry##*:}"
|
|
114
|
+
command -v "$bin" &>/dev/null && ((c++))
|
|
115
|
+
done < <(grep -E '^\s+"' "$reg" 2>/dev/null || true)
|
|
116
|
+
fi
|
|
117
|
+
echo "$c"
|
|
118
|
+
}
|
|
119
|
+
_count_lang() { local c=0; for cmd in node python rustc go clang php perl bun; do command -v "$cmd" &>/dev/null && ((c++)); done; echo "$c"; }
|
|
120
|
+
_count_db() { local c=0; command -v pg_ctl &>/dev/null && ((c++)); command -v mariadb &>/dev/null && ((c++)); command -v sqlite3 &>/dev/null && ((c++)); command -v mongod &>/dev/null && ((c++)); command -v redis-cli &>/dev/null && ((c++)); echo "$c"; }
|
|
121
|
+
_count_doctor() {
|
|
122
|
+
local doc_sh="$KARNEL_PATH/cli/commands/doctor/code_langs.sh"
|
|
123
|
+
if [[ -f "$doc_sh" ]]; then
|
|
124
|
+
local count; count=$(grep -c 'LANG_TOOLS\[' "$doc_sh" 2>/dev/null || echo 0)
|
|
125
|
+
echo "$count"
|
|
126
|
+
else echo "0"; fi
|
|
117
127
|
}
|
|
118
|
-
|
|
119
|
-
if
|
|
120
|
-
local
|
|
121
|
-
[[ -
|
|
122
|
-
|
|
128
|
+
_pg_status() {
|
|
129
|
+
if command -v pg_ctl &>/dev/null; then
|
|
130
|
+
local data="$KARNEL_DATA/pg/data"
|
|
131
|
+
if [[ -d "$data" ]] && pg_ctl status -D "$data" &>/dev/null 2>&1; then
|
|
132
|
+
echo "ON"
|
|
133
|
+
else
|
|
134
|
+
echo "OFF"
|
|
135
|
+
fi
|
|
136
|
+
else echo "—"; fi
|
|
123
137
|
}
|
|
124
138
|
|
|
125
139
|
# ================================================================
|
|
@@ -236,16 +250,16 @@ _render_frame_line() {
|
|
|
236
250
|
# ================================================================
|
|
237
251
|
# Panel
|
|
238
252
|
# ================================================================
|
|
239
|
-
PANEL_HEADERS=("AI" "Lang" "DB" "
|
|
240
|
-
PANEL_ICONS=("◆" "</>" "⛁" "
|
|
253
|
+
PANEL_HEADERS=("AI" "Lang" "DB" "Doctor" "PG")
|
|
254
|
+
PANEL_ICONS=("◆" "</>" "⛁" "◈" "🐘")
|
|
241
255
|
|
|
242
256
|
_panel_value() {
|
|
243
257
|
case $1 in
|
|
244
258
|
0) echo "${KAI_VAL:-$(_count_ai)}" ;;
|
|
245
259
|
1) echo "${KLANG_VAL:-$(_count_lang)}" ;;
|
|
246
260
|
2) echo "${KDB_VAL:-$(_count_db)}" ;;
|
|
247
|
-
3) echo "${
|
|
248
|
-
4) echo "${
|
|
261
|
+
3) echo "${KDOCTOR_VAL:-$(_count_doctor)}" ;;
|
|
262
|
+
4) echo "${KPG_VAL:-$(_pg_status)}" ;;
|
|
249
263
|
esac
|
|
250
264
|
}
|
|
251
265
|
|
|
@@ -430,8 +444,8 @@ _render_animated() {
|
|
|
430
444
|
KAI_VAL=$(_count_ai)
|
|
431
445
|
KLANG_VAL=$(_count_lang)
|
|
432
446
|
KDB_VAL=$(_count_db)
|
|
433
|
-
|
|
434
|
-
|
|
447
|
+
KDOCTOR_VAL=$(_count_doctor)
|
|
448
|
+
KPG_VAL=$(_pg_status)
|
|
435
449
|
|
|
436
450
|
# Cache banner for clear() override (capture only, no terminal output)
|
|
437
451
|
_banner_output=$(_render 2>/dev/null) || true
|
|
@@ -7,6 +7,9 @@ __KARNEL_BOOTSTRAP_LOADED=1
|
|
|
7
7
|
# registro de imports
|
|
8
8
|
declare -A __KARNEL_IMPORTED
|
|
9
9
|
|
|
10
|
+
# CAUTION: import() calls `source` from within a function. Any `declare` (without -g)
|
|
11
|
+
# in the sourced file creates LOCAL variables scoped to import(), not globals.
|
|
12
|
+
# Always use plain assignments (VAR=val) or `declare -g` for globals in sourced files.
|
|
10
13
|
import() {
|
|
11
14
|
local base="${KARNEL_PATH}"
|
|
12
15
|
local resolved="${1//@/$base}.sh"
|
package/karnel/utils/env.sh
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
KARNEL_VERSION="4.
|
|
3
|
+
KARNEL_VERSION="4.10.0"
|
|
4
4
|
|
|
5
5
|
# -------------------------
|
|
6
6
|
# Directorios del usuario
|
|
@@ -26,6 +26,7 @@ KARNEL_CLI="$KARNEL_PATH/cli"
|
|
|
26
26
|
KARNEL_TOOLS="$KARNEL_DATA/tools"
|
|
27
27
|
KARNEL_RUN="$KARNEL_CACHE/run"
|
|
28
28
|
KARNEL_LOGS="$KARNEL_CACHE/logs"
|
|
29
|
+
KARNEL_PLUGINS="$KARNEL_DATA/plugins"
|
|
29
30
|
|
|
30
31
|
# -------------------------
|
|
31
32
|
# Crear directorios
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
LOG_FILE="${LOG_FILE:-$KARNEL_CACHE/install_ai.log}"
|
|
4
|
+
|
|
5
|
+
# ── Dependency installation ────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
declare -A _INSTALL_DEPS_CACHE
|
|
8
|
+
|
|
9
|
+
install_deps() {
|
|
10
|
+
local -n deps=$1
|
|
11
|
+
local pkg_name bin_name
|
|
12
|
+
for pkg_name in "${!deps[@]}"; do
|
|
13
|
+
bin_name="${deps[$pkg_name]}"
|
|
14
|
+
if ! command -v "$bin_name" &>/dev/null; then
|
|
15
|
+
if ! pkg install "$pkg_name" -y &>>"$LOG_FILE"; then
|
|
16
|
+
log_error "Failed to install $pkg_name"
|
|
17
|
+
return 1
|
|
18
|
+
fi
|
|
19
|
+
fi
|
|
20
|
+
done
|
|
21
|
+
return 0
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# ── Glibc installation ─────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
install_glibc() {
|
|
27
|
+
if [[ ! -f $PREFIX/etc/apt/sources.list.d/glibc.list ]]; then
|
|
28
|
+
if ! pkg install glibc-repo -y &>>"$LOG_FILE"; then
|
|
29
|
+
log_error "Failed to install glibc-repo"
|
|
30
|
+
return 1
|
|
31
|
+
fi
|
|
32
|
+
fi
|
|
33
|
+
if [[ ! -f $PREFIX/glibc/lib/libc.so.6 ]]; then
|
|
34
|
+
if ! pkg install glibc -y &>>"$LOG_FILE"; then
|
|
35
|
+
log_error "Failed to install glibc"
|
|
36
|
+
return 1
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
return 0
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# ── GitHub release helpers ─────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
github_latest_tag() {
|
|
45
|
+
local repo="$1"
|
|
46
|
+
curl -fsSL "https://api.github.com/repos/$repo/releases/latest" |
|
|
47
|
+
grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
github_download_release() {
|
|
51
|
+
local repo="$1" version="$2" asset="$3" outdir="$4"
|
|
52
|
+
local url="https://github.com/$repo/releases/download/$version/$asset"
|
|
53
|
+
local tmpfile="$outdir/$(basename "$asset")"
|
|
54
|
+
mkdir -p "$outdir"
|
|
55
|
+
if ! curl -fsSL "$url" -o "$tmpfile" &>>"$LOG_FILE"; then
|
|
56
|
+
log_error "Failed to download $asset from $repo"
|
|
57
|
+
return 1
|
|
58
|
+
fi
|
|
59
|
+
echo "$tmpfile"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
extract_tarball() {
|
|
63
|
+
local tarball="$1" outdir="$2"
|
|
64
|
+
if ! tar -zxf "$tarball" -C "$outdir" &>>"$LOG_FILE"; then
|
|
65
|
+
log_error "Failed to extract $tarball"
|
|
66
|
+
return 1
|
|
67
|
+
fi
|
|
68
|
+
rm -f "$tarball"
|
|
69
|
+
return 0
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
github_download_and_extract() {
|
|
73
|
+
local repo="$1" version="$2" asset="$3" outdir="$4"
|
|
74
|
+
local tarball
|
|
75
|
+
tarball=$(github_download_release "$repo" "$version" "$asset" "$outdir") || return 1
|
|
76
|
+
extract_tarball "$tarball" "$outdir" || return 1
|
|
77
|
+
return 0
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# ── C helper compilation ───────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
compile_helper() {
|
|
83
|
+
local src="$1" out="$2"
|
|
84
|
+
if [ ! -f "$src" ]; then
|
|
85
|
+
log_error "Helper source not found at $src"
|
|
86
|
+
return 1
|
|
87
|
+
fi
|
|
88
|
+
if ! cc -O2 -o "$out" "$src" &>>"$LOG_FILE"; then
|
|
89
|
+
log_error "Failed to compile $src"
|
|
90
|
+
return 1
|
|
91
|
+
fi
|
|
92
|
+
chmod +x "$out"
|
|
93
|
+
return 0
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# ── Wrapper generator ─────────────────────────────────────────
|
|
97
|
+
|
|
98
|
+
generate_wrapper() {
|
|
99
|
+
local template="$1" ubuntu_root="$2" output="$3"
|
|
100
|
+
if [ ! -f "$template" ]; then
|
|
101
|
+
log_error "Wrapper template not found at $template"
|
|
102
|
+
return 1
|
|
103
|
+
fi
|
|
104
|
+
sed "s|__UBUNTU_ROOTFS__|$ubuntu_root|g" "$template" >"$output"
|
|
105
|
+
chmod +x "$output"
|
|
106
|
+
return 0
|
|
107
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
detect_ubuntu_root() {
|
|
4
|
+
local root
|
|
5
|
+
root="$(find /data/data/com.termux -maxdepth 10 -type d \
|
|
6
|
+
-name "rootfs" -path "*/containers/ubuntu/*" 2>/dev/null | head -1)"
|
|
7
|
+
if [ -z "$root" ]; then
|
|
8
|
+
root="$(find /data/data/com.termux -maxdepth 10 -type d \
|
|
9
|
+
-name "ubuntu" -path "*/installed-rootfs/*" 2>/dev/null | head -1)"
|
|
10
|
+
fi
|
|
11
|
+
echo "$root"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
proot_ubuntu() {
|
|
15
|
+
proot-distro login --shared-tmp ubuntu -- "$@"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
proot_install_ubuntu() {
|
|
19
|
+
local dist="${1:-ubuntu:24.04}"
|
|
20
|
+
if ! command -v proot-distro &>/dev/null; then
|
|
21
|
+
pkg install proot-distro -y &>>"$LOG_FILE"
|
|
22
|
+
fi
|
|
23
|
+
if [ ! -d "$(detect_ubuntu_root)" ]; then
|
|
24
|
+
proot-distro install "$dist" &>>"$LOG_FILE"
|
|
25
|
+
fi
|
|
26
|
+
}
|
package/package.json
CHANGED