omni-catalyst 1.0.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 (237) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1137 -0
  3. package/core/bin/core +85 -0
  4. package/core/bin/omni +21 -0
  5. package/core/cli/commands/--version.sh +8 -0
  6. package/core/cli/commands/brain.sh +1549 -0
  7. package/core/cli/commands/doctor.sh +834 -0
  8. package/core/cli/commands/env.sh +226 -0
  9. package/core/cli/commands/init.sh +1266 -0
  10. package/core/cli/commands/install.sh +759 -0
  11. package/core/cli/commands/list.sh +397 -0
  12. package/core/cli/commands/open.sh +71 -0
  13. package/core/cli/commands/pg.sh +761 -0
  14. package/core/cli/commands/reinstall.sh +694 -0
  15. package/core/cli/commands/show.sh +90 -0
  16. package/core/cli/commands/uninstall.sh +700 -0
  17. package/core/cli/commands/update.sh +754 -0
  18. package/core/cli/commands/voice.sh +170 -0
  19. package/core/cli/core.sh +82 -0
  20. package/core/cli/omni.sh +634 -0
  21. package/core/modules/ai.sh +152 -0
  22. package/core/modules/auto.sh +90 -0
  23. package/core/modules/db.sh +94 -0
  24. package/core/modules/deploy.sh +50 -0
  25. package/core/modules/dev.sh +126 -0
  26. package/core/modules/editor.sh +101 -0
  27. package/core/modules/lang.sh +100 -0
  28. package/core/modules/npm.sh +122 -0
  29. package/core/modules/shell.sh +312 -0
  30. package/core/modules/ui.sh +115 -0
  31. package/core/tools/ai/all.sh +63 -0
  32. package/core/tools/ai/antigravity-cli/README.md +45 -0
  33. package/core/tools/ai/antigravity-cli/bin/agy +28 -0
  34. package/core/tools/ai/antigravity-cli/helper/agy_helper.c +39 -0
  35. package/core/tools/ai/antigravity-cli/install.sh +469 -0
  36. package/core/tools/ai/claude-code/README.md +45 -0
  37. package/core/tools/ai/claude-code/bin/claude +29 -0
  38. package/core/tools/ai/claude-code/helper/claude_helper.c +42 -0
  39. package/core/tools/ai/claude-code/install.sh +278 -0
  40. package/core/tools/ai/codegraph/README.md +43 -0
  41. package/core/tools/ai/codegraph/bin/codegraph +3 -0
  42. package/core/tools/ai/codegraph/install.sh +149 -0
  43. package/core/tools/ai/codex/README.md +44 -0
  44. package/core/tools/ai/codex/install.sh +104 -0
  45. package/core/tools/ai/command-code/README.md +62 -0
  46. package/core/tools/ai/command-code/install.sh +136 -0
  47. package/core/tools/ai/engram/README.md +44 -0
  48. package/core/tools/ai/engram/install.sh +127 -0
  49. package/core/tools/ai/freebuff/README.md +52 -0
  50. package/core/tools/ai/freebuff/bin/freebuff +28 -0
  51. package/core/tools/ai/freebuff/helper/freebuff_helper.c +47 -0
  52. package/core/tools/ai/freebuff/install.sh +301 -0
  53. package/core/tools/ai/gemini-cli/README.md +46 -0
  54. package/core/tools/ai/gemini-cli/install.sh +111 -0
  55. package/core/tools/ai/gentle-ai/README.md +42 -0
  56. package/core/tools/ai/gentle-ai/install.sh +253 -0
  57. package/core/tools/ai/gentle-ai/termux-patches.go +256 -0
  58. package/core/tools/ai/gga/README.md +49 -0
  59. package/core/tools/ai/gga/install.sh +134 -0
  60. package/core/tools/ai/hermes-agent/README.md +50 -0
  61. package/core/tools/ai/hermes-agent/install.sh +80 -0
  62. package/core/tools/ai/heygen/README.md +24 -0
  63. package/core/tools/ai/heygen/install.sh +126 -0
  64. package/core/tools/ai/kilocode-cli/README.md +45 -0
  65. package/core/tools/ai/kilocode-cli/bin/kilocode +21 -0
  66. package/core/tools/ai/kilocode-cli/helper/kilocode_helper.c +47 -0
  67. package/core/tools/ai/kilocode-cli/install.sh +179 -0
  68. package/core/tools/ai/kimchi-code/README.md +8 -0
  69. package/core/tools/ai/kimchi-code/install.sh +120 -0
  70. package/core/tools/ai/kimi-code/README.md +45 -0
  71. package/core/tools/ai/kimi-code/install.sh +111 -0
  72. package/core/tools/ai/kiro-cli/README.md +23 -0
  73. package/core/tools/ai/kiro-cli/install.sh +127 -0
  74. package/core/tools/ai/mimocode/README.md +43 -0
  75. package/core/tools/ai/mimocode/bin/mimo +28 -0
  76. package/core/tools/ai/mimocode/helper/mimocode_helper.c +47 -0
  77. package/core/tools/ai/mimocode/install.sh +287 -0
  78. package/core/tools/ai/minimax-cli/README.md +45 -0
  79. package/core/tools/ai/minimax-cli/install.sh +111 -0
  80. package/core/tools/ai/mistral-vibe/README.md +46 -0
  81. package/core/tools/ai/mistral-vibe/install.sh +119 -0
  82. package/core/tools/ai/odysseus/README.md +35 -0
  83. package/core/tools/ai/odysseus/install.sh +163 -0
  84. package/core/tools/ai/ollama/README.md +44 -0
  85. package/core/tools/ai/ollama/install.sh +78 -0
  86. package/core/tools/ai/openclaude/README.md +46 -0
  87. package/core/tools/ai/openclaude/install.sh +110 -0
  88. package/core/tools/ai/openclaw/README.md +47 -0
  89. package/core/tools/ai/openclaw/install.sh +112 -0
  90. package/core/tools/ai/opencode/README.md +51 -0
  91. package/core/tools/ai/opencode/bin/opencode +28 -0
  92. package/core/tools/ai/opencode/helper/opencode_helper.c +57 -0
  93. package/core/tools/ai/opencode/install.sh +290 -0
  94. package/core/tools/ai/pi/README.md +46 -0
  95. package/core/tools/ai/pi/install.sh +104 -0
  96. package/core/tools/ai/qwen-code/README.md +45 -0
  97. package/core/tools/ai/qwen-code/install.sh +111 -0
  98. package/core/tools/ai/seedance/README.md +22 -0
  99. package/core/tools/ai/seedance/install.sh +134 -0
  100. package/core/tools/ai/veo3/README.md +36 -0
  101. package/core/tools/ai/veo3/install.sh +151 -0
  102. package/core/tools/auto/all.sh +57 -0
  103. package/core/tools/auto/n8n/README.md +47 -0
  104. package/core/tools/auto/n8n/install.sh +102 -0
  105. package/core/tools/db/all.sh +60 -0
  106. package/core/tools/db/mariadb/README.md +43 -0
  107. package/core/tools/db/mariadb/install.sh +65 -0
  108. package/core/tools/db/mongodb/README.md +42 -0
  109. package/core/tools/db/mongodb/install.sh +73 -0
  110. package/core/tools/db/postgresql/README.md +45 -0
  111. package/core/tools/db/postgresql/install.sh +65 -0
  112. package/core/tools/db/sqlite/README.md +44 -0
  113. package/core/tools/db/sqlite/install.sh +65 -0
  114. package/core/tools/deploy/all.sh +39 -0
  115. package/core/tools/deploy/netlify/install.sh +41 -0
  116. package/core/tools/deploy/railway/install.sh +47 -0
  117. package/core/tools/deploy/vercel/install.sh +43 -0
  118. package/core/tools/dev/all.sh +75 -0
  119. package/core/tools/dev/bat/README.md +44 -0
  120. package/core/tools/dev/bat/install.sh +82 -0
  121. package/core/tools/dev/bc/README.md +44 -0
  122. package/core/tools/dev/bc/install.sh +82 -0
  123. package/core/tools/dev/cloudflared/README.md +43 -0
  124. package/core/tools/dev/cloudflared/install.sh +82 -0
  125. package/core/tools/dev/curl/README.md +43 -0
  126. package/core/tools/dev/curl/install.sh +82 -0
  127. package/core/tools/dev/fzf/README.md +44 -0
  128. package/core/tools/dev/fzf/install.sh +82 -0
  129. package/core/tools/dev/gh/README.md +43 -0
  130. package/core/tools/dev/gh/install.sh +82 -0
  131. package/core/tools/dev/html2text/README.md +44 -0
  132. package/core/tools/dev/html2text/install.sh +82 -0
  133. package/core/tools/dev/imagemagick/README.md +44 -0
  134. package/core/tools/dev/imagemagick/install.sh +82 -0
  135. package/core/tools/dev/jq/README.md +44 -0
  136. package/core/tools/dev/jq/install.sh +82 -0
  137. package/core/tools/dev/lsd/README.md +44 -0
  138. package/core/tools/dev/lsd/install.sh +82 -0
  139. package/core/tools/dev/make/README.md +44 -0
  140. package/core/tools/dev/make/install.sh +82 -0
  141. package/core/tools/dev/ncurses/README.md +42 -0
  142. package/core/tools/dev/ncurses/install.sh +82 -0
  143. package/core/tools/dev/proot/README.md +43 -0
  144. package/core/tools/dev/proot/install.sh +82 -0
  145. package/core/tools/dev/shfmt/README.md +44 -0
  146. package/core/tools/dev/shfmt/install.sh +82 -0
  147. package/core/tools/dev/tmate/README.md +44 -0
  148. package/core/tools/dev/tmate/install.sh +82 -0
  149. package/core/tools/dev/translate/README.md +44 -0
  150. package/core/tools/dev/translate/install.sh +82 -0
  151. package/core/tools/dev/tree/README.md +44 -0
  152. package/core/tools/dev/tree/install.sh +82 -0
  153. package/core/tools/dev/udocker/README.md +44 -0
  154. package/core/tools/dev/udocker/install.sh +82 -0
  155. package/core/tools/dev/wget/README.md +44 -0
  156. package/core/tools/dev/wget/install.sh +82 -0
  157. package/core/tools/editor/all.sh +58 -0
  158. package/core/tools/editor/neovim/README.md +43 -0
  159. package/core/tools/editor/neovim/install.sh +66 -0
  160. package/core/tools/editor/nvchad/README.md +45 -0
  161. package/core/tools/editor/nvchad/install.sh +110 -0
  162. package/core/tools/lang/all.sh +63 -0
  163. package/core/tools/lang/clang/README.md +43 -0
  164. package/core/tools/lang/clang/install.sh +79 -0
  165. package/core/tools/lang/golang/README.md +43 -0
  166. package/core/tools/lang/golang/install.sh +79 -0
  167. package/core/tools/lang/nodejs/README.md +43 -0
  168. package/core/tools/lang/nodejs/install.sh +79 -0
  169. package/core/tools/lang/perl/README.md +43 -0
  170. package/core/tools/lang/perl/install.sh +79 -0
  171. package/core/tools/lang/php/README.md +43 -0
  172. package/core/tools/lang/php/install.sh +79 -0
  173. package/core/tools/lang/python/README.md +43 -0
  174. package/core/tools/lang/python/install.sh +79 -0
  175. package/core/tools/lang/rust/README.md +43 -0
  176. package/core/tools/lang/rust/install.sh +79 -0
  177. package/core/tools/npm/all.sh +67 -0
  178. package/core/tools/npm/live-server/README.md +43 -0
  179. package/core/tools/npm/live-server/install.sh +95 -0
  180. package/core/tools/npm/localtunnel/README.md +43 -0
  181. package/core/tools/npm/localtunnel/install.sh +111 -0
  182. package/core/tools/npm/markserv/README.md +43 -0
  183. package/core/tools/npm/markserv/install.sh +94 -0
  184. package/core/tools/npm/ncu/README.md +43 -0
  185. package/core/tools/npm/ncu/install.sh +94 -0
  186. package/core/tools/npm/nestjs/README.md +43 -0
  187. package/core/tools/npm/nestjs/install.sh +94 -0
  188. package/core/tools/npm/ngrok/README.md +44 -0
  189. package/core/tools/npm/ngrok/install.sh +94 -0
  190. package/core/tools/npm/prettier/README.md +43 -0
  191. package/core/tools/npm/prettier/install.sh +94 -0
  192. package/core/tools/npm/psqlformat/README.md +43 -0
  193. package/core/tools/npm/psqlformat/install.sh +94 -0
  194. package/core/tools/npm/turbopack/README.md +8 -0
  195. package/core/tools/npm/turbopack/install.sh +41 -0
  196. package/core/tools/npm/typescript/README.md +43 -0
  197. package/core/tools/npm/typescript/install.sh +94 -0
  198. package/core/tools/npm/vercel/README.md +43 -0
  199. package/core/tools/npm/vercel/install.sh +94 -0
  200. package/core/tools/shell/all.sh +67 -0
  201. package/core/tools/shell/better-npm/README.md +43 -0
  202. package/core/tools/shell/better-npm/install.sh +85 -0
  203. package/core/tools/shell/fzf-tab/README.md +44 -0
  204. package/core/tools/shell/fzf-tab/install.sh +85 -0
  205. package/core/tools/shell/history-substring/README.md +43 -0
  206. package/core/tools/shell/history-substring/install.sh +85 -0
  207. package/core/tools/shell/powerlevel10k/README.md +43 -0
  208. package/core/tools/shell/powerlevel10k/install.sh +85 -0
  209. package/core/tools/shell/you-should-use/README.md +43 -0
  210. package/core/tools/shell/you-should-use/install.sh +85 -0
  211. package/core/tools/shell/zsh-autopair/README.md +44 -0
  212. package/core/tools/shell/zsh-autopair/install.sh +85 -0
  213. package/core/tools/shell/zsh-autosuggestions/README.md +43 -0
  214. package/core/tools/shell/zsh-autosuggestions/install.sh +85 -0
  215. package/core/tools/shell/zsh-completions/README.md +43 -0
  216. package/core/tools/shell/zsh-completions/install.sh +85 -0
  217. package/core/tools/shell/zsh-defer/README.md +43 -0
  218. package/core/tools/shell/zsh-defer/install.sh +85 -0
  219. package/core/tools/shell/zsh-syntax-highlighting/README.md +43 -0
  220. package/core/tools/shell/zsh-syntax-highlighting/install.sh +72 -0
  221. package/core/tools/ui/all.sh +61 -0
  222. package/core/tools/ui/banner/README.md +42 -0
  223. package/core/tools/ui/banner/install.sh +151 -0
  224. package/core/tools/ui/cursor/README.md +42 -0
  225. package/core/tools/ui/cursor/install.sh +58 -0
  226. package/core/tools/ui/extra-keys/README.md +43 -0
  227. package/core/tools/ui/extra-keys/install.sh +62 -0
  228. package/core/tools/ui/font/README.md +43 -0
  229. package/core/tools/ui/font/install.sh +63 -0
  230. package/core/utils/banner.sh +519 -0
  231. package/core/utils/bootstrap.sh +25 -0
  232. package/core/utils/colors.sh +31 -0
  233. package/core/utils/dialogrc +30 -0
  234. package/core/utils/env.sh +53 -0
  235. package/core/utils/log.sh +598 -0
  236. package/install.sh +272 -0
  237. package/package.json +43 -0
@@ -0,0 +1,598 @@
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 [[ "${OMNI_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
+ # ===== CENTER TEXT =====
78
+
79
+ center_text() {
80
+ local cols=$(tput cols)
81
+ local text="$1"
82
+ local padding=$(( (cols - ${#text}) / 2 ))
83
+
84
+ # Remover códigos ANSI para calcular padding correcto
85
+ local clean_text=$(echo -e "$text" | sed 's/\x1b\[[0-9;]*m//g')
86
+ local clean_len=${#clean_text}
87
+ padding=$(( (cols - clean_len) / 2 ))
88
+
89
+ printf "%${padding}s" ""
90
+ echo -e "$text"
91
+ }
92
+
93
+ # ===== BOX FUNCTIONS =====
94
+
95
+ # Draw a box around the given text
96
+ box() {
97
+ local text="$1"
98
+ local len=${#text}
99
+ local line=$(printf "%$((len + 2))s")
100
+
101
+ echo -e "${GRAY}╭${line// /─}╮${NC}"
102
+ echo -e "${GRAY}│${D_CYAN} $text ${GRAY}│${NC}"
103
+ echo -e "${GRAY}╰${line// /─}╯${NC}"
104
+ }
105
+
106
+ box_large() {
107
+ local text="$1"
108
+ local len=${#text}
109
+ local line=$(printf "%$((len + 4))s")
110
+
111
+ echo -e "${GRAY}╔${line// /═}╗${NC}"
112
+ echo -e "${GRAY}║${D_CYAN} $text ${GRAY}║${NC}"
113
+ echo -e "${GRAY}╚${line// /═}╝${NC}"
114
+ }
115
+
116
+ box_with_subtitle() {
117
+ local title="$1"
118
+ local subtitle="$2"
119
+ local max_len=$(( ${#title} > ${#subtitle} ? ${#title} : ${#subtitle} ))
120
+ local line=$(printf "%$((max_len + 2))s")
121
+
122
+ echo -e "${GRAY}╭${line// /─}╮${NC}"
123
+ echo -e "${GRAY}│${D_CYAN} $title${GRAY}$(printf "%$((max_len - ${#title}))s") │${NC}"
124
+ echo -e "${GRAY}│${D_PURPLE} $subtitle${GRAY}$(printf "%$((max_len - ${#subtitle}))s") │${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
+ while true; do
313
+ echo -e -n " ${GRAY}┌─${D_YELLOW} ${prompt} ${GRAY}[${D_GREEN}y${GRAY}/${D_RED}n${GRAY}]${D_NC}\n" >&2
314
+ echo -e -n " ${GRAY}└─${D_YELLOW}▶ ${D_NC}" >&2
315
+ read -rn1 _val
316
+ echo >&2
317
+ case "${_val,,}" in
318
+ y)
319
+ read -r "$var" <<<"y"
320
+ return 0
321
+ ;;
322
+ n)
323
+ read -r "$var" <<<"n"
324
+ return 1
325
+ ;;
326
+ *) echo -e " ${RED}✖${D_NC} Reply ${D_GREEN}y${D_NC} o ${D_RED}n${D_NC}" >&2 ;;
327
+ esac
328
+ done
329
+ }
330
+
331
+ # --- Selección de opciones ---
332
+ # Uso: read_select "Prompt" VAR_NAME "Opción1" "Opción2" ...
333
+ # VAR_NAME recibe el texto de la opción elegida
334
+ read_select() {
335
+ local prompt="$1"
336
+ local var="$2"
337
+ shift 2
338
+ local -a options=("$@")
339
+ local selected=0
340
+ local total=${#options[@]}
341
+ local cols
342
+ cols=$(tput cols)
343
+ local margin=6
344
+ local max_width=$((cols - margin))
345
+
346
+ _render_select() {
347
+ echo -e " ${GRAY}┌─${D_CYAN} ${prompt}${NC}" >&2
348
+ for ((i = 0; i < total; i++)); do
349
+ local text="${options[$i]}"
350
+ if (( ${#text} > max_width )); then
351
+ text="${text:0:$((max_width - 3))}..."
352
+ fi
353
+ if ((i == selected)); then
354
+ echo -e " ${GRAY}│ ${D_CYAN}▶ ${WHITE}${text}${D_NC}" >&2
355
+ else
356
+ echo -e " ${GRAY}│ ${GRAY}${text}${D_NC}" >&2
357
+ fi
358
+ done
359
+ echo -e -n " ${GRAY}└─${D_NC} ${GRAY}↑↓ move Enter confirm${D_NC}" >&2
360
+ }
361
+
362
+ local lines=$((total + 1))
363
+
364
+ tput civis
365
+ _render_select
366
+
367
+ while true; do
368
+ IFS= read -rsn1 key
369
+ if [[ "$key" == $'\x1b' ]]; then
370
+ read -rsn2 -t 0.1 rest
371
+ key="${key}${rest}"
372
+ fi
373
+
374
+ case "$key" in
375
+ $'\x1b[A' | k) ((selected > 0)) && ((selected--)) ;;
376
+ $'\x1b[B' | j) ((selected < total - 1)) && ((selected++)) ;;
377
+ '') break ;;
378
+ esac
379
+
380
+ echo -en "\r\033[${lines}A\033[J" >&2
381
+ _render_select
382
+ done
383
+
384
+ echo >&2
385
+ tput cnorm
386
+
387
+ read -r "$var" <<<"${options[$selected]}"
388
+ echo -e " ${GRAY}└─${D_CYAN}▶ ${D_NC}${options[$selected]}${D_NC}" >&2
389
+ }
390
+
391
+ # --- Entrada multi-línea (shell interactiva, sin editor externo) ---
392
+ # Lee contenido línea por línea hasta Ctrl+D.
393
+ # Uso: local tmp; tmp=$(read_multiline "Initial header"); content=$(cat "$tmp"); rm -f "$tmp"
394
+ read_multiline() {
395
+ local initial="$1"
396
+ local tmpfile
397
+ tmpfile=$(mktemp)
398
+
399
+ echo "$initial" >"$tmpfile"
400
+ echo >>"$tmpfile"
401
+
402
+ local cols
403
+ cols=$(tput cols 2>/dev/null || echo 80)
404
+ local w=$((cols - 6))
405
+ local bar
406
+ printf -v bar '%*s' "$w" ''
407
+
408
+ echo -e " ${GRAY}╭${bar// /─}╮${NC}" >&2
409
+ printf " ${GRAY}│${NC} ${D_CYAN}✎ Write your memory${D_NC}%*s ${GRAY}│${NC}\n" $((w - 24)) "" >&2
410
+ printf " ${GRAY}│${NC} ${D_DIM}(Ctrl+D to finish, Ctrl+C to cancel)${D_NC}%*s ${GRAY}│${NC}\n" $((w - 40)) "" >&2
411
+ echo -e " ${GRAY}├${bar// /─}┤${NC}" >&2
412
+
413
+ local line
414
+ while IFS= read -r line; do
415
+ echo "$line" >>"$tmpfile"
416
+ done
417
+
418
+ echo >&2
419
+ echo -e " ${GRAY}╰${bar// /─}╯${NC}" >&2
420
+ echo -e " ${GRAY}${D_GREEN}✔ Content captured${D_NC}" >&2
421
+
422
+ echo "$tmpfile"
423
+ }
424
+
425
+ # ===== LOADING SPINNER =====
426
+
427
+ _spinner_pids=()
428
+
429
+ loading() {
430
+ local message="$1"
431
+ shift
432
+
433
+ local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
434
+ local delay=0.08
435
+ local tmpfile
436
+ tmpfile="$(mktemp)"
437
+
438
+ printf " ${CYAN}⠋${D_CYAN} %s${NC}" "$message"
439
+
440
+ "$@" >"$tmpfile" 2>&1 &
441
+ local cmd_pid=$!
442
+
443
+ mkdir -p "$OMNI_CACHE"
444
+ echo "$cmd_pid" >> "$OMNI_CACHE/.loading_pids"
445
+
446
+ local frame_idx=0
447
+ while kill -0 "$cmd_pid" 2>/dev/null; do
448
+ printf "\r ${CYAN}%s${D_CYAN} %s${NC}" "${frames[$frame_idx]}" "$message"
449
+ frame_idx=$(( (frame_idx + 1) % ${#frames[@]} ))
450
+ sleep "$delay"
451
+ done
452
+
453
+ wait "$cmd_pid"
454
+ local exit_code=$?
455
+
456
+ if [[ $exit_code -eq 0 ]]; then
457
+ printf "\r ${GREEN}✔${D_GREEN} %s${NC}\n" "$message"
458
+ [[ -s "$tmpfile" ]] && cat "$tmpfile"
459
+ elif [[ $exit_code -eq 2 ]]; then
460
+ printf "\r ${CYAN}➜${D_CYAN} %s${NC}\n" "$message"
461
+ [[ -s "$tmpfile" ]] && cat "$tmpfile"
462
+ else
463
+ printf "\r ${RED}✖${D_RED} %s${NC}\n" "$message"
464
+ cat "$tmpfile"
465
+ fi
466
+
467
+ rm -f "$tmpfile"
468
+ return $exit_code
469
+ }
470
+
471
+ # ===== PROGRESS BAR =====
472
+
473
+ _progress_current=0
474
+ _progress_total=0
475
+ _progress_width=50
476
+
477
+ progress_bar() {
478
+ local current=$1
479
+ local total=$2
480
+ local width=${3:-50}
481
+ _progress_current=$current
482
+ _progress_total=$total
483
+ _progress_width=$width
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_start() {
496
+ local total=$1
497
+ local message="${2:-Progress}"
498
+ _progress_current=0
499
+ _progress_total=$total
500
+ _progress_width=50
501
+ printf " ${D_CYAN}%s${D_NC}" "$message"
502
+ printf "\n ${D_CYAN}[${D_NC}"
503
+ for ((i = 0; i < _progress_width; i++)); do
504
+ printf "${D_NC}░${D_CYAN}"
505
+ done
506
+ printf "${D_CYAN}]${D_NC} 0%%\n"
507
+ printf "\033[1A"
508
+ progress_bar 0 "$total"
509
+ }
510
+
511
+ progress_update() {
512
+ local current=$1
513
+ local total=$2
514
+ local width="${_progress_width:-50}"
515
+ local percentage=$((current * 100 / total))
516
+ local filled=$((current * width / total))
517
+ local empty=$((width - filled))
518
+
519
+ local bar=""
520
+ for ((i = 0; i < filled; i++)); do bar+="█"; done
521
+ for ((i = 0; i < empty; i++)); do bar+="░"; done
522
+
523
+ printf "\r ${D_CYAN}[${D_NC}${D_GREEN}%s${D_NC}${D_CYAN}]${D_NC} %3d%%" "$bar" "$percentage"
524
+ }
525
+
526
+ progress_done() {
527
+ local total=$1
528
+ progress_update "$total" "$total"
529
+ printf "\n ${GREEN}✔${D_NC} Complete\n"
530
+ }
531
+
532
+ # ===== STEP FUNCTIONS =====
533
+
534
+ step_start() {
535
+ local step="$1"
536
+ local message="$2"
537
+ echo -e " ${D_CYAN}[$step]${D_NC} $message"
538
+ }
539
+
540
+ step_success() {
541
+ local step="$1"
542
+ local message="$2"
543
+ echo -e " ${GREEN}[$step]${D_GREEN} $message ✔${NC}"
544
+ }
545
+
546
+ step_error() {
547
+ local step="$1"
548
+ local message="$2"
549
+ echo -e " ${RED}[$step]${D_RED} $message ✖${NC}" >&2
550
+ }
551
+
552
+ # ===== STATUS ICONS =====
553
+
554
+ icon_success() {
555
+ echo -e "${GREEN}✓${NC}"
556
+ }
557
+
558
+ icon_error() {
559
+ echo -e "${RED}✗${NC}"
560
+ }
561
+
562
+ icon_warning() {
563
+ echo -e "${YELLOW}⚠${NC}"
564
+ }
565
+
566
+ icon_info() {
567
+ echo -e "${CYAN}ℹ${NC}"
568
+ }
569
+
570
+ icon_arrow() {
571
+ echo -e "${D_CYAN}→${NC}"
572
+ }
573
+
574
+ # ===== BADGE FUNCTIONS =====
575
+
576
+ badge() {
577
+ local text="$1"
578
+ local color="${2:-D_CYAN}"
579
+ echo -e "${!color}[ $text ]${NC}"
580
+ }
581
+
582
+ badge_new() {
583
+ echo -e "${D_GREEN}[ NEW ]${NC}"
584
+ }
585
+
586
+ badge_beta() {
587
+ echo -e "${D_YELLOW}[ BETA ]${NC}"
588
+ }
589
+
590
+ badge_deprecated() {
591
+ echo -e "${D_RED}[ DEPRECATED ]${NC}"
592
+ }
593
+
594
+ # ===== TIP FUNCTION =====
595
+
596
+ log_tip() {
597
+ echo -e " ${D_CYAN}●${NC} $*"
598
+ }