karnel-termux 0.0.1

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 (258) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +454 -0
  3. package/install.sh +272 -0
  4. package/karnel/bin/karnel +77 -0
  5. package/karnel/cli/commands/brain.sh +1553 -0
  6. package/karnel/cli/commands/cleanup.sh +66 -0
  7. package/karnel/cli/commands/doctor.sh +1528 -0
  8. package/karnel/cli/commands/env.sh +233 -0
  9. package/karnel/cli/commands/help.sh +8 -0
  10. package/karnel/cli/commands/ia.sh +502 -0
  11. package/karnel/cli/commands/init.sh +1274 -0
  12. package/karnel/cli/commands/install.sh +718 -0
  13. package/karnel/cli/commands/list.sh +399 -0
  14. package/karnel/cli/commands/open.sh +106 -0
  15. package/karnel/cli/commands/pg.sh +719 -0
  16. package/karnel/cli/commands/reinstall.sh +663 -0
  17. package/karnel/cli/commands/show.sh +90 -0
  18. package/karnel/cli/commands/start.sh +54 -0
  19. package/karnel/cli/commands/status.sh +96 -0
  20. package/karnel/cli/commands/uninstall.sh +668 -0
  21. package/karnel/cli/commands/update.sh +723 -0
  22. package/karnel/cli/commands/upgrade.sh +40 -0
  23. package/karnel/cli/commands/version.sh +3 -0
  24. package/karnel/cli/commands/voice.sh +230 -0
  25. package/karnel/cli/karnel.sh +706 -0
  26. package/karnel/modules/ai.sh +135 -0
  27. package/karnel/modules/auto.sh +114 -0
  28. package/karnel/modules/db.sh +132 -0
  29. package/karnel/modules/deploy.sh +74 -0
  30. package/karnel/modules/dev.sh +148 -0
  31. package/karnel/modules/editor.sh +115 -0
  32. package/karnel/modules/lang.sh +124 -0
  33. package/karnel/modules/npm.sh +146 -0
  34. package/karnel/modules/shell.sh +338 -0
  35. package/karnel/modules/ui.sh +139 -0
  36. package/karnel/modules/voice.sh +118 -0
  37. package/karnel/tools/ai/all.sh +209 -0
  38. package/karnel/tools/ai/antigravity-cli/README.md +45 -0
  39. package/karnel/tools/ai/antigravity-cli/bin/agy +28 -0
  40. package/karnel/tools/ai/antigravity-cli/helper/agy_helper.c +39 -0
  41. package/karnel/tools/ai/antigravity-cli/install.sh +469 -0
  42. package/karnel/tools/ai/claude-code/README.md +45 -0
  43. package/karnel/tools/ai/claude-code/bin/claude +29 -0
  44. package/karnel/tools/ai/claude-code/helper/claude_helper.c +42 -0
  45. package/karnel/tools/ai/claude-code/install.sh +278 -0
  46. package/karnel/tools/ai/cline/install.sh +160 -0
  47. package/karnel/tools/ai/codegraph/README.md +43 -0
  48. package/karnel/tools/ai/codegraph/bin/codegraph +5 -0
  49. package/karnel/tools/ai/codegraph/install.sh +160 -0
  50. package/karnel/tools/ai/codex/README.md +44 -0
  51. package/karnel/tools/ai/codex/install.sh +104 -0
  52. package/karnel/tools/ai/command-code/README.md +62 -0
  53. package/karnel/tools/ai/command-code/install.sh +136 -0
  54. package/karnel/tools/ai/crush/README.md +17 -0
  55. package/karnel/tools/ai/crush/install.sh +89 -0
  56. package/karnel/tools/ai/ctx7/README.md +26 -0
  57. package/karnel/tools/ai/ctx7/install.sh +61 -0
  58. package/karnel/tools/ai/engram/README.md +44 -0
  59. package/karnel/tools/ai/engram/install.sh +127 -0
  60. package/karnel/tools/ai/freebuff/README.md +52 -0
  61. package/karnel/tools/ai/freebuff/bin/freebuff +28 -0
  62. package/karnel/tools/ai/freebuff/helper/freebuff_helper.c +47 -0
  63. package/karnel/tools/ai/freebuff/install.sh +303 -0
  64. package/karnel/tools/ai/gemini-cli/README.md +46 -0
  65. package/karnel/tools/ai/gemini-cli/install.sh +111 -0
  66. package/karnel/tools/ai/gentle-ai/README.md +42 -0
  67. package/karnel/tools/ai/gentle-ai/install.sh +253 -0
  68. package/karnel/tools/ai/gentle-ai/termux-patches.go +256 -0
  69. package/karnel/tools/ai/gga/README.md +49 -0
  70. package/karnel/tools/ai/gga/install.sh +134 -0
  71. package/karnel/tools/ai/hermes-agent/README.md +50 -0
  72. package/karnel/tools/ai/hermes-agent/install.sh +120 -0
  73. package/karnel/tools/ai/kilocode-cli/README.md +45 -0
  74. package/karnel/tools/ai/kilocode-cli/bin/kilocode +21 -0
  75. package/karnel/tools/ai/kilocode-cli/helper/kilocode_helper.c +47 -0
  76. package/karnel/tools/ai/kilocode-cli/install.sh +179 -0
  77. package/karnel/tools/ai/kimchi-code/README.md +53 -0
  78. package/karnel/tools/ai/kimchi-code/install.sh +221 -0
  79. package/karnel/tools/ai/kimi-code/README.md +45 -0
  80. package/karnel/tools/ai/kimi-code/install.sh +111 -0
  81. package/karnel/tools/ai/kiro/README.md +17 -0
  82. package/karnel/tools/ai/kiro/install.sh +134 -0
  83. package/karnel/tools/ai/mimocode/README.md +43 -0
  84. package/karnel/tools/ai/mimocode/bin/mimo +28 -0
  85. package/karnel/tools/ai/mimocode/helper/mimocode_helper.c +47 -0
  86. package/karnel/tools/ai/mimocode/install.sh +287 -0
  87. package/karnel/tools/ai/minimax-cli/README.md +45 -0
  88. package/karnel/tools/ai/minimax-cli/install.sh +111 -0
  89. package/karnel/tools/ai/mistral-vibe/README.md +46 -0
  90. package/karnel/tools/ai/mistral-vibe/install.sh +119 -0
  91. package/karnel/tools/ai/odysseus/README.md +35 -0
  92. package/karnel/tools/ai/odysseus/install.sh +198 -0
  93. package/karnel/tools/ai/ollama/README.md +44 -0
  94. package/karnel/tools/ai/ollama/install.sh +78 -0
  95. package/karnel/tools/ai/omni-route/README.md +111 -0
  96. package/karnel/tools/ai/omni-route/install.sh +165 -0
  97. package/karnel/tools/ai/openclaude/README.md +46 -0
  98. package/karnel/tools/ai/openclaude/install.sh +110 -0
  99. package/karnel/tools/ai/openclaw/README.md +47 -0
  100. package/karnel/tools/ai/openclaw/install.sh +112 -0
  101. package/karnel/tools/ai/opencode/README.md +51 -0
  102. package/karnel/tools/ai/opencode/bin/opencode +28 -0
  103. package/karnel/tools/ai/opencode/helper/opencode_helper.c +57 -0
  104. package/karnel/tools/ai/opencode/install.sh +290 -0
  105. package/karnel/tools/ai/openspec/README.md +34 -0
  106. package/karnel/tools/ai/openspec/install.sh +61 -0
  107. package/karnel/tools/ai/pi/README.md +46 -0
  108. package/karnel/tools/ai/pi/install.sh +104 -0
  109. package/karnel/tools/ai/qwen-code/README.md +45 -0
  110. package/karnel/tools/ai/qwen-code/install.sh +111 -0
  111. package/karnel/tools/auto/all.sh +57 -0
  112. package/karnel/tools/auto/n8n/README.md +47 -0
  113. package/karnel/tools/auto/n8n/install.sh +102 -0
  114. package/karnel/tools/db/all.sh +61 -0
  115. package/karnel/tools/db/mariadb/README.md +43 -0
  116. package/karnel/tools/db/mariadb/install.sh +65 -0
  117. package/karnel/tools/db/mongodb/README.md +42 -0
  118. package/karnel/tools/db/mongodb/install.sh +73 -0
  119. package/karnel/tools/db/postgresql/README.md +45 -0
  120. package/karnel/tools/db/postgresql/install.sh +65 -0
  121. package/karnel/tools/db/redis/README.md +46 -0
  122. package/karnel/tools/db/redis/install.sh +64 -0
  123. package/karnel/tools/db/sqlite/README.md +44 -0
  124. package/karnel/tools/db/sqlite/install.sh +65 -0
  125. package/karnel/tools/deploy/all.sh +43 -0
  126. package/karnel/tools/deploy/netlify/install.sh +41 -0
  127. package/karnel/tools/deploy/railway/install.sh +109 -0
  128. package/karnel/tools/deploy/vercel/install.sh +43 -0
  129. package/karnel/tools/dev/all.sh +77 -0
  130. package/karnel/tools/dev/bat/README.md +44 -0
  131. package/karnel/tools/dev/bat/install.sh +82 -0
  132. package/karnel/tools/dev/bc/README.md +44 -0
  133. package/karnel/tools/dev/bc/install.sh +82 -0
  134. package/karnel/tools/dev/cloudflared/README.md +43 -0
  135. package/karnel/tools/dev/cloudflared/install.sh +82 -0
  136. package/karnel/tools/dev/curl/README.md +43 -0
  137. package/karnel/tools/dev/curl/install.sh +82 -0
  138. package/karnel/tools/dev/fzf/README.md +44 -0
  139. package/karnel/tools/dev/fzf/install.sh +82 -0
  140. package/karnel/tools/dev/gh/README.md +43 -0
  141. package/karnel/tools/dev/gh/install.sh +82 -0
  142. package/karnel/tools/dev/html2text/README.md +44 -0
  143. package/karnel/tools/dev/html2text/install.sh +82 -0
  144. package/karnel/tools/dev/imagemagick/README.md +44 -0
  145. package/karnel/tools/dev/imagemagick/install.sh +82 -0
  146. package/karnel/tools/dev/jq/README.md +44 -0
  147. package/karnel/tools/dev/jq/install.sh +82 -0
  148. package/karnel/tools/dev/lsd/README.md +44 -0
  149. package/karnel/tools/dev/lsd/install.sh +82 -0
  150. package/karnel/tools/dev/make/README.md +44 -0
  151. package/karnel/tools/dev/make/install.sh +82 -0
  152. package/karnel/tools/dev/ncurses/README.md +42 -0
  153. package/karnel/tools/dev/ncurses/install.sh +82 -0
  154. package/karnel/tools/dev/openssh/README.md +43 -0
  155. package/karnel/tools/dev/openssh/install.sh +75 -0
  156. package/karnel/tools/dev/proot/README.md +43 -0
  157. package/karnel/tools/dev/proot/install.sh +82 -0
  158. package/karnel/tools/dev/shfmt/README.md +44 -0
  159. package/karnel/tools/dev/shfmt/install.sh +82 -0
  160. package/karnel/tools/dev/tmate/README.md +44 -0
  161. package/karnel/tools/dev/tmate/install.sh +82 -0
  162. package/karnel/tools/dev/tmux/README.md +43 -0
  163. package/karnel/tools/dev/tmux/install.sh +75 -0
  164. package/karnel/tools/dev/translate/README.md +44 -0
  165. package/karnel/tools/dev/translate/install.sh +82 -0
  166. package/karnel/tools/dev/tree/README.md +44 -0
  167. package/karnel/tools/dev/tree/install.sh +82 -0
  168. package/karnel/tools/dev/udocker/README.md +44 -0
  169. package/karnel/tools/dev/udocker/install.sh +82 -0
  170. package/karnel/tools/dev/wget/README.md +44 -0
  171. package/karnel/tools/dev/wget/install.sh +82 -0
  172. package/karnel/tools/editor/all.sh +59 -0
  173. package/karnel/tools/editor/code-server/README.md +42 -0
  174. package/karnel/tools/editor/code-server/install.sh +74 -0
  175. package/karnel/tools/editor/neovim/README.md +43 -0
  176. package/karnel/tools/editor/neovim/install.sh +64 -0
  177. package/karnel/tools/editor/nvchad/README.md +45 -0
  178. package/karnel/tools/editor/nvchad/install.sh +105 -0
  179. package/karnel/tools/lang/all.sh +63 -0
  180. package/karnel/tools/lang/clang/README.md +43 -0
  181. package/karnel/tools/lang/clang/install.sh +79 -0
  182. package/karnel/tools/lang/golang/README.md +43 -0
  183. package/karnel/tools/lang/golang/install.sh +79 -0
  184. package/karnel/tools/lang/nodejs/README.md +43 -0
  185. package/karnel/tools/lang/nodejs/install.sh +79 -0
  186. package/karnel/tools/lang/perl/README.md +43 -0
  187. package/karnel/tools/lang/perl/install.sh +79 -0
  188. package/karnel/tools/lang/php/README.md +43 -0
  189. package/karnel/tools/lang/php/install.sh +79 -0
  190. package/karnel/tools/lang/python/README.md +43 -0
  191. package/karnel/tools/lang/python/install.sh +79 -0
  192. package/karnel/tools/lang/rust/README.md +43 -0
  193. package/karnel/tools/lang/rust/install.sh +79 -0
  194. package/karnel/tools/npm/all.sh +90 -0
  195. package/karnel/tools/npm/live-server/README.md +43 -0
  196. package/karnel/tools/npm/live-server/install.sh +96 -0
  197. package/karnel/tools/npm/localtunnel/README.md +43 -0
  198. package/karnel/tools/npm/localtunnel/install.sh +112 -0
  199. package/karnel/tools/npm/markserv/README.md +43 -0
  200. package/karnel/tools/npm/markserv/install.sh +95 -0
  201. package/karnel/tools/npm/ncu/README.md +43 -0
  202. package/karnel/tools/npm/ncu/install.sh +95 -0
  203. package/karnel/tools/npm/nestjs/README.md +43 -0
  204. package/karnel/tools/npm/nestjs/install.sh +95 -0
  205. package/karnel/tools/npm/ngrok/README.md +44 -0
  206. package/karnel/tools/npm/ngrok/install.sh +95 -0
  207. package/karnel/tools/npm/prettier/README.md +43 -0
  208. package/karnel/tools/npm/prettier/install.sh +95 -0
  209. package/karnel/tools/npm/psqlformat/README.md +43 -0
  210. package/karnel/tools/npm/psqlformat/install.sh +95 -0
  211. package/karnel/tools/npm/turbopack/README.md +8 -0
  212. package/karnel/tools/npm/turbopack/install.sh +42 -0
  213. package/karnel/tools/npm/typescript/README.md +43 -0
  214. package/karnel/tools/npm/typescript/install.sh +95 -0
  215. package/karnel/tools/npm/vercel/README.md +43 -0
  216. package/karnel/tools/npm/vercel/install.sh +95 -0
  217. package/karnel/tools/shell/all.sh +67 -0
  218. package/karnel/tools/shell/better-npm/README.md +43 -0
  219. package/karnel/tools/shell/better-npm/install.sh +85 -0
  220. package/karnel/tools/shell/fzf-tab/README.md +44 -0
  221. package/karnel/tools/shell/fzf-tab/install.sh +85 -0
  222. package/karnel/tools/shell/history-substring/README.md +43 -0
  223. package/karnel/tools/shell/history-substring/install.sh +85 -0
  224. package/karnel/tools/shell/powerlevel10k/README.md +43 -0
  225. package/karnel/tools/shell/powerlevel10k/install.sh +85 -0
  226. package/karnel/tools/shell/you-should-use/README.md +43 -0
  227. package/karnel/tools/shell/you-should-use/install.sh +85 -0
  228. package/karnel/tools/shell/zsh-autopair/README.md +44 -0
  229. package/karnel/tools/shell/zsh-autopair/install.sh +85 -0
  230. package/karnel/tools/shell/zsh-autosuggestions/README.md +43 -0
  231. package/karnel/tools/shell/zsh-autosuggestions/install.sh +85 -0
  232. package/karnel/tools/shell/zsh-completions/README.md +43 -0
  233. package/karnel/tools/shell/zsh-completions/install.sh +85 -0
  234. package/karnel/tools/shell/zsh-defer/README.md +43 -0
  235. package/karnel/tools/shell/zsh-defer/install.sh +85 -0
  236. package/karnel/tools/shell/zsh-syntax-highlighting/README.md +43 -0
  237. package/karnel/tools/shell/zsh-syntax-highlighting/install.sh +72 -0
  238. package/karnel/tools/ui/all.sh +61 -0
  239. package/karnel/tools/ui/banner/README.md +42 -0
  240. package/karnel/tools/ui/banner/install.sh +160 -0
  241. package/karnel/tools/ui/cursor/README.md +42 -0
  242. package/karnel/tools/ui/cursor/install.sh +58 -0
  243. package/karnel/tools/ui/extra-keys/README.md +43 -0
  244. package/karnel/tools/ui/extra-keys/install.sh +62 -0
  245. package/karnel/tools/ui/font/README.md +43 -0
  246. package/karnel/tools/ui/font/install.sh +63 -0
  247. package/karnel/tools/voice/all.sh +27 -0
  248. package/karnel/tools/voice/install.sh +10 -0
  249. package/karnel/tools/voice/uninstall.sh +8 -0
  250. package/karnel/utils/banner.sh +492 -0
  251. package/karnel/utils/bootstrap.sh +25 -0
  252. package/karnel/utils/colors.sh +33 -0
  253. package/karnel/utils/dialogrc +30 -0
  254. package/karnel/utils/env.sh +53 -0
  255. package/karnel/utils/log.sh +567 -0
  256. package/karnel/utils/version.sh +205 -0
  257. package/package.json +42 -0
  258. package/scripts/npm-install.js +60 -0
@@ -0,0 +1,567 @@
1
+ #!/usr/bin/env bash
2
+
3
+ import "@/utils/colors"
4
+
5
+ # ===== LOG FUNCTIONS =====
6
+
7
+ log_info() {
8
+ echo -e " ${CYAN}➜${D_CYAN} $*${D_NC}"
9
+ }
10
+
11
+ log_success() {
12
+ echo -e " ${GREEN}✔${D_GREEN} $*${D_NC}"
13
+ }
14
+
15
+ log_warn() {
16
+ echo -e " ${YELLOW}⚠${D_YELLOW} $*${D_NC}"
17
+ }
18
+
19
+ log_error() {
20
+ echo -e " ${RED}✖${D_RED} $*${D_NC}" >&2
21
+ }
22
+
23
+ log_debug() {
24
+ if [[ "${KARNEL_DEBUG:-0}" == "1" ]]; then
25
+ echo -e " ${PURPLE}⚙${D_PURPLE} [DEBUG] $*${D_NC}"
26
+ fi
27
+ }
28
+
29
+ list_item() {
30
+ echo -e " ${GRAY}•${D_NC} $*"
31
+ }
32
+
33
+ list_item_check() {
34
+ local status="$1"
35
+ local text="$2"
36
+
37
+ case "$status" in
38
+ "done" | "success")
39
+ echo -e " ${GREEN}✔${D_NC} $text"
40
+ ;;
41
+ "pending")
42
+ echo -e " ${YELLOW}⏳${D_NC} $text"
43
+ ;;
44
+ "error" | "fail")
45
+ echo -e " ${RED}✖${D_NC} $text"
46
+ ;;
47
+ *)
48
+ echo -e " ${GRAY}•${D_NC} $text"
49
+ ;;
50
+ esac
51
+ }
52
+
53
+ # ===== SEPARATOR FUNCTIONS =====
54
+
55
+ separator() {
56
+ local cols=$(tput cols)
57
+ local line=$(printf "%${cols}s")
58
+ echo -e "${GRAY}${line// /─}${NC}"
59
+ }
60
+
61
+ separator_double() {
62
+ local cols=$(tput cols)
63
+ local line=$(printf "%${cols}s")
64
+ echo -e "${GRAY}${line// /═}${NC}"
65
+ echo -e "${GRAY}${line// /═}${NC}"
66
+ }
67
+
68
+ separator_section() {
69
+ local title="$1"
70
+ local cols=$(tput cols)
71
+ local padding=$(( (cols - ${#title} - 2) / 2 ))
72
+ local line=$(printf "%${padding}s")
73
+
74
+ echo -e "${GRAY}${line// /─} ${D_CYAN}${title}${GRAY} ${line// /─}${NC}"
75
+ }
76
+
77
+ box_large() {
78
+ local text="$1"
79
+ local len=${#text}
80
+ local line=$(printf "%$((len + 4))s")
81
+
82
+ echo -e "${GRAY}╔${line// /═}╗${NC}"
83
+ echo -e "${GRAY}║${D_CYAN} $text ${GRAY}║${NC}"
84
+ echo -e "${GRAY}╚${line// /═}╝${NC}"
85
+ }
86
+
87
+ box_with_subtitle() {
88
+ local title="$1"
89
+ local subtitle="$2"
90
+ local max_len=$(( ${#title} > ${#subtitle} ? ${#title} : ${#subtitle} ))
91
+ local line=$(printf "%$((max_len + 2))s")
92
+
93
+ echo -e "${GRAY}╭${line// /─}╮${NC}"
94
+ echo -e "${GRAY}│${D_CYAN} $title${GRAY}$(printf "%$((max_len - ${#title}))s") │${NC}"
95
+ echo -e "${GRAY}│${D_PURPLE} $subtitle${GRAY}$(printf "%$((max_len - ${#subtitle}))s") │${NC}"
96
+ echo -e "${GRAY}╰${line// /─}╯${NC}"
97
+ }
98
+
99
+ # ===== CENTER TEXT =====
100
+
101
+ center_text() {
102
+ local cols=$(tput cols)
103
+ local text="$1"
104
+ local padding=$(( (cols - ${#text}) / 2 ))
105
+
106
+ # Remover códigos ANSI para calcular padding correcto
107
+ local clean_text=$(echo -e "$text" | sed 's/\x1b\[[0-9;]*m//g')
108
+ local clean_len=${#clean_text}
109
+ padding=$(( (cols - clean_len) / 2 ))
110
+
111
+ printf "%${padding}s" ""
112
+ echo -e "$text"
113
+ }
114
+
115
+ # ===== BOX FUNCTIONS =====
116
+
117
+ # Draw a box around the given text
118
+ box() {
119
+ local text="$1"
120
+ local len=${#text}
121
+ local line=$(printf "%$((len + 2))s")
122
+
123
+ echo -e "${GRAY}╭${line// /─}╮${NC}"
124
+ echo -e "${GRAY}│${D_CYAN} $text ${GRAY}│${NC}"
125
+ echo -e "${GRAY}╰${line// /─}╯${NC}"
126
+ }
127
+
128
+ # ===== TABLE FUNCTIONS =====
129
+
130
+ # ===== INTERNAL TABLE STATE =====
131
+ TABLE_HEADERS=()
132
+ TABLE_ROWS=()
133
+ TABLE_WIDTHS=()
134
+
135
+ # ===== START TABLE =====
136
+ table_start() {
137
+ TABLE_HEADERS=("$@")
138
+ TABLE_ROWS=()
139
+ }
140
+
141
+ # ===== ADD ROW =====
142
+ # Uso simple: table_row "valor1" "valor2" "valor3"
143
+ # Por defecto: col 1 → D_GREEN, col 2 → D_CYAN, resto → sin color
144
+ # También acepta colores custom: table_row "${RED}valor${NC}" ...
145
+ table_row() {
146
+ local -a colored=()
147
+ local i=0
148
+ for field in "$@"; do
149
+ # Solo aplicar color por defecto si el campo no contiene ya un escape ANSI
150
+ if [[ "$field" != *$'\x1b['* ]]; then
151
+ case $i in
152
+ 0) colored+=("${D_GREEN}${field}${NC}") ;;
153
+ 1) colored+=("${D_CYAN}${field}${NC}") ;;
154
+ *) colored+=("${D_NC}${field}${NC}") ;;
155
+ esac
156
+ else
157
+ colored+=("$field")
158
+ fi
159
+ ((i++))
160
+ done
161
+ local IFS=$'\x1F'
162
+ TABLE_ROWS+=("${colored[*]}")
163
+ }
164
+
165
+ # ===== STRIP ANSI =====
166
+ # Elimina códigos de escape ANSI para medir la longitud visual real
167
+ strip_ansi() {
168
+ echo -e "$1" | sed 's/\x1b\[[0-9;]*m//g'
169
+ }
170
+
171
+ # ===== CALCULATE COLUMN WIDTHS =====
172
+ table_calc_widths() {
173
+ local cols=${#TABLE_HEADERS[@]}
174
+
175
+ for ((i = 0; i < cols; i++)); do
176
+ TABLE_WIDTHS[$i]=${#TABLE_HEADERS[$i]}
177
+ done
178
+
179
+ for row in "${TABLE_ROWS[@]}"; do
180
+ IFS=$'\x1F' read -r -a fields <<<"$row"
181
+ for ((i = 0; i < cols; i++)); do
182
+ local visual
183
+ visual=$(strip_ansi "${fields[$i]}")
184
+ local len=${#visual}
185
+ ((len > TABLE_WIDTHS[$i])) && TABLE_WIDTHS[$i]=$len
186
+ done
187
+ done
188
+ }
189
+
190
+ # ===== BORDER HELPERS =====
191
+ # Genera una línea horizontal con los caracteres correctos según posición
192
+ # $1: char izquierdo, $2: char relleno, $3: char separador, $4: char derecho
193
+ table_border() {
194
+ local left="$1" fill="$2" sep="$3" right="$4"
195
+ echo -ne "${GRAY}${left}"
196
+ local last=$((${#TABLE_WIDTHS[@]} - 1))
197
+ for i in "${!TABLE_WIDTHS[@]}"; do
198
+ local w="${TABLE_WIDTHS[$i]}"
199
+ local line=$(printf "%$((w + 2))s")
200
+ echo -ne "${line// /${fill}}"
201
+ if ((i < last)); then
202
+ echo -ne "${sep}"
203
+ fi
204
+ done
205
+ echo -e "${right}${NC}"
206
+ }
207
+
208
+ # ===== RENDER TABLE =====
209
+ table_end() {
210
+ table_calc_widths
211
+
212
+ local cols=${#TABLE_HEADERS[@]}
213
+
214
+ # Top border: ┌───┬───┐
215
+ table_border "┌" "─" "┬" "┐"
216
+
217
+ # Headers (D_RED por defecto)
218
+ echo -ne "${GRAY}│${NC}"
219
+ for ((i = 0; i < cols; i++)); do
220
+ printf " ${D_RED}%-${TABLE_WIDTHS[$i]}s ${GRAY}│${NC}" "${TABLE_HEADERS[$i]}"
221
+ done
222
+ echo
223
+
224
+ # Middle border: ├───┼───┤
225
+ table_border "├" "─" "┼" "┤"
226
+
227
+ # Rows
228
+ for row in "${TABLE_ROWS[@]}"; do
229
+ IFS=$'\x1F' read -r -a fields <<<"$row"
230
+
231
+ echo -ne "${GRAY}│${NC}"
232
+ for ((i = 0; i < cols; i++)); do
233
+ local display="${fields[$i]}"
234
+ local visual
235
+ visual=$(strip_ansi "$display")
236
+
237
+ local pad=$((TABLE_WIDTHS[$i] - ${#visual}))
238
+ local spaces
239
+ printf -v spaces "%${pad}s" ""
240
+
241
+ printf " %b%s ${GRAY}│${NC}" "$display" "$spaces"
242
+ done
243
+ echo
244
+ done
245
+
246
+ # Bottom border: └───┴───┘
247
+ table_border "└" "─" "┴" "┘"
248
+ }
249
+
250
+ # ===== READ FUNCTIONS =====
251
+ # El segundo argumento es el nombre de la variable donde se guarda el resultado.
252
+
253
+ # --- Texto simple ---
254
+ # Uso: read_input "Prompt" VAR_NAME
255
+ read_input() {
256
+ local prompt="$1"
257
+ local var="$2"
258
+ local _val
259
+
260
+ echo -e -n " ${GRAY}┌─${D_CYAN} ${prompt} ${NC}\n" >&2
261
+ echo -e -n " ${GRAY}└─${D_CYAN}▶ ${D_NC}" >&2
262
+ read -r _val
263
+ read -r "$var" <<<"$_val"
264
+ }
265
+
266
+ # --- Entrada censurada (contraseñas, tokens, API keys) ---
267
+ # Lee carácter por carácter y muestra ● para cada uno.
268
+ # Uso: read_secret "Prompt" VAR_NAME
269
+ read_secret() {
270
+ local prompt="$1"
271
+ local var="$2"
272
+ local _val=""
273
+ local char
274
+
275
+ echo -e -n " ${GRAY}┌─${D_CYAN} ${prompt} ${NC}\n" >&2
276
+ echo -e -n " ${GRAY}│${D_DIM} (input will be hidden)${D_NC}\n" >&2
277
+ echo -e -n " ${GRAY}└─${D_CYAN}▶ ${D_NC}" >&2
278
+
279
+ local old_stty
280
+ old_stty=$(stty -g 2>/dev/null)
281
+ stty -echo -icanon min 1 time 0 2>/dev/null
282
+
283
+ while true; do
284
+ char=$(dd bs=1 count=1 2>/dev/null)
285
+ if [[ "$char" == $'\n' ]] || [[ "$char" == $'\r' ]] || [[ -z "$char" ]]; then
286
+ break
287
+ fi
288
+ if [[ "$char" == $'\177' ]] || [[ "$char" == $'\b' ]] || [[ "$char" == $'\x7f' ]]; then
289
+ if [[ -n "$_val" ]]; then
290
+ _val="${_val%?}"
291
+ echo -ne "\b \b" >&2
292
+ fi
293
+ else
294
+ _val+="$char"
295
+ echo -ne "●" >&2
296
+ fi
297
+ done
298
+
299
+ stty "$old_stty" 2>/dev/null
300
+ echo >&2
301
+ read -r "$var" <<<"$_val"
302
+ }
303
+
304
+ # --- Confirmación s/n ---
305
+ # Uso: read_confirm "¿Continuar?" VAR_NAME
306
+ # Retorna 0 si sí, 1 si no. VAR_NAME recibe "y" o "n"
307
+ read_confirm() {
308
+ local prompt="$1"
309
+ local var="$2"
310
+ local _val
311
+
312
+ if [[ ! -t 0 ]]; then
313
+ read -r "$var" <<<"n"
314
+ return 1
315
+ fi
316
+
317
+ while true; do
318
+ echo -e -n " ${GRAY}┌─${D_YELLOW} ${prompt} ${GRAY}[${D_GREEN}y${GRAY}/${D_RED}n${GRAY}]${D_NC}\n" >&2
319
+ echo -e -n " ${GRAY}└─${D_YELLOW}▶ ${D_NC}" >&2
320
+ read -rn1 _val
321
+ echo >&2
322
+ case "${_val,,}" in
323
+ y)
324
+ read -r "$var" <<<"y"
325
+ return 0
326
+ ;;
327
+ n)
328
+ read -r "$var" <<<"n"
329
+ return 1
330
+ ;;
331
+ *) echo -e " ${RED}✖${D_NC} Reply ${D_GREEN}y${D_NC} o ${D_RED}n${D_NC}" >&2 ;;
332
+ esac
333
+ done
334
+ }
335
+
336
+ # --- Selección de opciones ---
337
+ # Uso: read_select "Prompt" VAR_NAME "Opción1" "Opción2" ...
338
+ # VAR_NAME recibe el texto de la opción elegida
339
+ read_select() {
340
+ local prompt="$1"
341
+ local var="$2"
342
+ shift 2
343
+ local -a options=("$@")
344
+ local selected=0
345
+ local total=${#options[@]}
346
+ local cols
347
+ cols=$(tput cols)
348
+ local margin=6
349
+ local max_width=$((cols - margin))
350
+
351
+ _render_select() {
352
+ echo -e " ${GRAY}┌─${D_CYAN} ${prompt}${NC}" >&2
353
+ for ((i = 0; i < total; i++)); do
354
+ local text="${options[$i]}"
355
+ if (( ${#text} > max_width )); then
356
+ text="${text:0:$((max_width - 3))}..."
357
+ fi
358
+ if ((i == selected)); then
359
+ echo -e " ${GRAY}│ ${D_CYAN}▶ ${WHITE}${text}${D_NC}" >&2
360
+ else
361
+ echo -e " ${GRAY}│ ${GRAY}${text}${D_NC}" >&2
362
+ fi
363
+ done
364
+ echo -e -n " ${GRAY}└─${D_NC} ${GRAY}↑↓ move Enter confirm${D_NC}" >&2
365
+ }
366
+
367
+ local lines=$((total + 1))
368
+
369
+ tput civis
370
+ _render_select
371
+
372
+ while true; do
373
+ IFS= read -rsn1 key
374
+ if [[ "$key" == $'\x1b' ]]; then
375
+ read -rsn2 -t 0.1 rest
376
+ key="${key}${rest}"
377
+ fi
378
+
379
+ case "$key" in
380
+ $'\x1b[A' | k) ((selected > 0)) && ((selected--)) ;;
381
+ $'\x1b[B' | j) ((selected < total - 1)) && ((selected++)) ;;
382
+ '') break ;;
383
+ esac
384
+
385
+ echo -en "\r\033[${lines}A\033[J" >&2
386
+ _render_select
387
+ done
388
+
389
+ echo >&2
390
+ tput cnorm
391
+
392
+ read -r "$var" <<<"${options[$selected]}"
393
+ echo -e " ${GRAY}└─${D_CYAN}▶ ${D_NC}${options[$selected]}${D_NC}" >&2
394
+ }
395
+
396
+ # ===== LOADING SPINNER =====
397
+
398
+ loading() {
399
+ local message="$1"
400
+ shift
401
+
402
+ local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
403
+ local delay=0.08
404
+ local tmpfile
405
+ tmpfile="$(mktemp)"
406
+
407
+ printf " ${CYAN}⠋${D_CYAN} %s${NC}" "$message"
408
+
409
+ "$@" >"$tmpfile" 2>&1 &
410
+ local cmd_pid=$!
411
+
412
+ mkdir -p "$KARNEL_CACHE"
413
+ echo "$cmd_pid" >> "$KARNEL_CACHE/.loading_pids"
414
+
415
+ local frame_idx=0
416
+ while kill -0 "$cmd_pid" 2>/dev/null; do
417
+ printf "\r ${CYAN}%s${D_CYAN} %s${NC}" "${frames[$frame_idx]}" "$message"
418
+ frame_idx=$(( (frame_idx + 1) % ${#frames[@]} ))
419
+ sleep "$delay"
420
+ done
421
+
422
+ wait "$cmd_pid"
423
+ local exit_code=$?
424
+
425
+ if [[ $exit_code -eq 0 ]]; then
426
+ printf "\r ${GREEN}✔${D_GREEN} %s${NC}\n" "$message"
427
+ [[ -s "$tmpfile" ]] && cat "$tmpfile"
428
+ elif [[ $exit_code -eq 2 ]]; then
429
+ printf "\r ${CYAN}➜${D_CYAN} %s${NC}\n" "$message"
430
+ [[ -s "$tmpfile" ]] && cat "$tmpfile"
431
+ else
432
+ printf "\r ${RED}✖${D_RED} %s${NC}\n" "$message"
433
+ cat "$tmpfile"
434
+ fi
435
+
436
+ rm -f "$tmpfile"
437
+ return $exit_code
438
+ }
439
+
440
+ # ===== PROGRESS BAR =====
441
+
442
+ _progress_current=0
443
+ _progress_total=0
444
+ _progress_width=50
445
+
446
+ progress_bar() {
447
+ local current=$1
448
+ local total=$2
449
+ local width=${3:-50}
450
+ _progress_current=$current
451
+ _progress_total=$total
452
+ _progress_width=$width
453
+ local percentage=$((current * 100 / total))
454
+ local filled=$((current * width / total))
455
+ local empty=$((width - filled))
456
+
457
+ local bar=""
458
+ for ((i = 0; i < filled; i++)); do bar+="█"; done
459
+ for ((i = 0; i < empty; i++)); do bar+="░"; done
460
+
461
+ printf "\r ${D_CYAN}[${D_NC}${D_GREEN}%s${D_NC}${D_CYAN}]${D_NC} %3d%%" "$bar" "$percentage"
462
+ }
463
+
464
+ progress_start() {
465
+ local total=$1
466
+ local message="${2:-Progress}"
467
+ _progress_current=0
468
+ _progress_total=$total
469
+ _progress_width=50
470
+ printf " ${D_CYAN}%s${D_NC}" "$message"
471
+ printf "\n ${D_CYAN}[${D_NC}"
472
+ for ((i = 0; i < _progress_width; i++)); do
473
+ printf "${D_NC}░${D_CYAN}"
474
+ done
475
+ printf "${D_CYAN}]${D_NC} 0%%\n"
476
+ printf "\033[1A"
477
+ progress_bar 0 "$total"
478
+ }
479
+
480
+ progress_update() {
481
+ local current=$1
482
+ local total=$2
483
+ local width="${_progress_width:-50}"
484
+ local percentage=$((current * 100 / total))
485
+ local filled=$((current * width / total))
486
+ local empty=$((width - filled))
487
+
488
+ local bar=""
489
+ for ((i = 0; i < filled; i++)); do bar+="█"; done
490
+ for ((i = 0; i < empty; i++)); do bar+="░"; done
491
+
492
+ printf "\r ${D_CYAN}[${D_NC}${D_GREEN}%s${D_NC}${D_CYAN}]${D_NC} %3d%%" "$bar" "$percentage"
493
+ }
494
+
495
+ progress_done() {
496
+ local total=$1
497
+ progress_update "$total" "$total"
498
+ printf "\n ${GREEN}✔${D_NC} Complete\n"
499
+ }
500
+
501
+ # ===== STEP FUNCTIONS =====
502
+
503
+ step_start() {
504
+ local step="$1"
505
+ local message="$2"
506
+ echo -e " ${D_CYAN}[$step]${D_NC} $message"
507
+ }
508
+
509
+ step_success() {
510
+ local step="$1"
511
+ local message="$2"
512
+ echo -e " ${GREEN}[$step]${D_GREEN} $message ✔${NC}"
513
+ }
514
+
515
+ step_error() {
516
+ local step="$1"
517
+ local message="$2"
518
+ echo -e " ${RED}[$step]${D_RED} $message ✖${NC}" >&2
519
+ }
520
+
521
+ # ===== STATUS ICONS =====
522
+
523
+ icon_success() {
524
+ echo -e "${GREEN}✓${NC}"
525
+ }
526
+
527
+ icon_error() {
528
+ echo -e "${RED}✗${NC}"
529
+ }
530
+
531
+ icon_warning() {
532
+ echo -e "${YELLOW}⚠${NC}"
533
+ }
534
+
535
+ icon_info() {
536
+ echo -e "${CYAN}ℹ${NC}"
537
+ }
538
+
539
+ icon_arrow() {
540
+ echo -e "${D_CYAN}→${NC}"
541
+ }
542
+
543
+ # ===== BADGE FUNCTIONS =====
544
+
545
+ badge() {
546
+ local text="$1"
547
+ local color="${2:-D_CYAN}"
548
+ echo -e "${!color}[ $text ]${NC}"
549
+ }
550
+
551
+ badge_new() {
552
+ echo -e "${D_GREEN}[ NEW ]${NC}"
553
+ }
554
+
555
+ badge_beta() {
556
+ echo -e "${D_YELLOW}[ BETA ]${NC}"
557
+ }
558
+
559
+ badge_deprecated() {
560
+ echo -e "${D_RED}[ DEPRECATED ]${NC}"
561
+ }
562
+
563
+ # ===== TIP FUNCTION =====
564
+
565
+ log_tip() {
566
+ echo -e " ${D_CYAN}●${NC} $*"
567
+ }