batipanel 0.3.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/lib/themes.sh ADDED
@@ -0,0 +1,354 @@
1
+ #!/usr/bin/env bash
2
+ # batipanel themes - color theme system
3
+
4
+ # available themes
5
+ BATIPANEL_THEMES="default dracula nord gruvbox tokyo-night catppuccin rose-pine kanagawa"
6
+
7
+ # get all theme colors as space-separated values
8
+ # usage: _get_theme_colors <theme>
9
+ # returns: STATUS_BG STATUS_FG ACCENT ACCENT_FG WINDOW_BG WINDOW_FG
10
+ # WINDOW_ACTIVE_BG WINDOW_ACTIVE_FG BORDER MESSAGE_BG MESSAGE_FG
11
+ # PROMPT_USER_BG PROMPT_DIR_BG PROMPT_GIT_BG PROMPT_ERR_BG
12
+ _get_theme_colors() {
13
+ local theme="$1"
14
+ case "$theme" in
15
+ default)
16
+ echo "colour234 colour137 colour2 colour232 colour238 colour249 colour33 colour255 colour240 colour33 colour255 44 240 42 41"
17
+ ;;
18
+ dracula)
19
+ echo "colour236 colour253 colour141 colour232 colour238 colour253 colour212 colour255 colour61 colour141 colour232 105 238 212 203"
20
+ ;;
21
+ nord)
22
+ echo "colour236 colour253 colour110 colour232 colour238 colour253 colour67 colour255 colour240 colour67 colour255 67 238 110 131"
23
+ ;;
24
+ gruvbox)
25
+ echo "colour235 colour223 colour208 colour232 colour237 colour223 colour214 colour235 colour239 colour208 colour235 172 239 142 167"
26
+ ;;
27
+ tokyo-night)
28
+ echo "colour234 colour253 colour111 colour232 colour238 colour253 colour141 colour255 colour240 colour111 colour232 111 238 141 203"
29
+ ;;
30
+ catppuccin)
31
+ echo "colour234 colour189 colour183 colour233 colour237 colour146 colour183 colour233 colour239 colour237 colour189 183 237 151 211"
32
+ ;;
33
+ rose-pine)
34
+ echo "colour234 colour189 colour181 colour234 colour236 colour103 colour181 colour234 colour238 colour235 colour189 182 238 152 168"
35
+ ;;
36
+ kanagawa)
37
+ echo "colour235 colour187 colour110 colour234 colour236 colour242 colour110 colour234 colour59 colour236 colour187 103 236 107 203"
38
+ ;;
39
+ *)
40
+ return 1
41
+ ;;
42
+ esac
43
+ }
44
+
45
+ # theme description for display
46
+ _get_theme_desc() {
47
+ case "$1" in
48
+ default) echo "Green/blue (original)" ;;
49
+ dracula) echo "Purple/pink dark theme" ;;
50
+ nord) echo "Arctic blue palette" ;;
51
+ gruvbox) echo "Retro warm colors" ;;
52
+ tokyo-night) echo "Blue/purple night theme" ;;
53
+ catppuccin) echo "Pastel warm dark (Mocha)" ;;
54
+ rose-pine) echo "Soho vibes, warm rose" ;;
55
+ kanagawa) echo "Japanese ink painting" ;;
56
+ esac
57
+ }
58
+
59
+ # list available themes
60
+ _list_themes() {
61
+ local current="${BATIPANEL_THEME:-default}"
62
+ echo ""
63
+ echo -e " ${BLUE}Available themes:${NC}"
64
+ echo ""
65
+ local name desc marker
66
+ for name in $BATIPANEL_THEMES; do
67
+ desc=$(_get_theme_desc "$name")
68
+ # pad name to 14 chars for alignment
69
+ local padded
70
+ padded=$(printf '%-14s' "$name")
71
+ if [ "$name" = "$current" ]; then
72
+ marker="${GREEN}*${NC}"
73
+ echo -e " ${marker} ${GREEN}${padded}${NC}${desc}"
74
+ else
75
+ echo -e " ${padded}${desc}"
76
+ fi
77
+ done
78
+ echo ""
79
+ }
80
+
81
+ # generate tmux theme overlay file
82
+ # shellcheck disable=SC2153 # BATIPANEL_HOME is set by core.sh
83
+ _generate_theme_conf() {
84
+ local theme="$1"
85
+ local conf_file="$BATIPANEL_HOME/config/theme.conf"
86
+
87
+ local colors
88
+ colors=$(_get_theme_colors "$theme") || return 1
89
+
90
+ # parse color values
91
+ local status_bg status_fg accent accent_fg win_bg win_fg
92
+ local win_active_bg win_active_fg border msg_bg msg_fg
93
+ # shellcheck disable=SC2086
94
+ read -r status_bg status_fg accent accent_fg win_bg win_fg \
95
+ win_active_bg win_active_fg border msg_bg msg_fg \
96
+ _prompt_user _prompt_dir _prompt_git _prompt_err <<< $colors
97
+
98
+ mkdir -p "$BATIPANEL_HOME/config"
99
+ cat > "$conf_file" << CONF
100
+ # batipanel theme: ${theme} (auto-generated — do not edit)
101
+
102
+ # status bar
103
+ set -g status-style "bg=${status_bg},fg=${status_fg}"
104
+ set -g status-left '#[fg=${accent_fg},bg=${accent},bold] #S #[fg=${accent},bg=${status_bg},nobold] '
105
+ set -g status-right '#[fg=${border},bg=${status_bg}]#[fg=${win_fg},bg=${border}] #{session_windows}W #{window_panes}P #[fg=${accent},bg=${border}]#[fg=${accent_fg},bg=${accent},bold] %H:%M %m-%d '
106
+
107
+ # window tabs
108
+ setw -g window-status-format '#[fg=${status_bg},bg=${win_bg}]#[fg=${win_fg},bg=${win_bg}] #I #W #[fg=${win_bg},bg=${status_bg}]'
109
+ setw -g window-status-current-format '#[fg=${status_bg},bg=${win_active_bg}]#[fg=${win_active_fg},bg=${win_active_bg},bold] #I #W #[fg=${win_active_bg},bg=${status_bg}]'
110
+
111
+ # pane borders
112
+ set -g pane-border-style "fg=${border}"
113
+ set -g pane-active-border-style "fg=${accent},bold"
114
+ set -g pane-border-format "#[fg=${border}] #{pane_index}:#{pane_title} "
115
+
116
+ # messages
117
+ set -g message-style "bg=${msg_bg},fg=${msg_fg},bold"
118
+ set -g message-command-style "bg=${msg_bg},fg=${msg_fg}"
119
+ CONF
120
+ }
121
+
122
+ # generate bash prompt with theme colors
123
+ _generate_themed_prompt() {
124
+ local theme="$1"
125
+ local prompt_file="$BATIPANEL_HOME/config/bash-prompt.sh"
126
+
127
+ local colors
128
+ colors=$(_get_theme_colors "$theme") || return 1
129
+
130
+ local prompt_user prompt_dir prompt_git prompt_err
131
+ # shellcheck disable=SC2086
132
+ read -r _ _ _ _ _ _ _ _ _ _ _ \
133
+ prompt_user prompt_dir prompt_git prompt_err <<< $colors
134
+
135
+ # map ANSI code numbers to fg transition codes
136
+ # user bg → dir transition
137
+ local t_user_fg
138
+ case "$prompt_user" in
139
+ 44) t_user_fg="34" ;; # blue
140
+ 105) t_user_fg="105" ;; # purple (256-color)
141
+ 67) t_user_fg="67" ;; # nord blue (256-color)
142
+ 172) t_user_fg="172" ;; # gruvbox orange (256-color)
143
+ 111) t_user_fg="111" ;; # tokyo blue (256-color)
144
+ 183) t_user_fg="183" ;; # catppuccin mauve (256-color)
145
+ 182) t_user_fg="182" ;; # rose-pine iris (256-color)
146
+ 103) t_user_fg="103" ;; # kanagawa violet (256-color)
147
+ *) t_user_fg="34" ;; # fallback blue
148
+ esac
149
+
150
+ # git bg → end transition
151
+ local t_git_fg
152
+ case "$prompt_git" in
153
+ 42) t_git_fg="32" ;; # green
154
+ 212) t_git_fg="212" ;; # pink (256-color)
155
+ 110) t_git_fg="110" ;; # frost (256-color)
156
+ 142) t_git_fg="142" ;; # gruvbox green (256-color)
157
+ 141) t_git_fg="141" ;; # purple (256-color)
158
+ 151) t_git_fg="151" ;; # catppuccin green (256-color)
159
+ 152) t_git_fg="152" ;; # rose-pine foam (256-color)
160
+ 107) t_git_fg="107" ;; # kanagawa spring green (256-color)
161
+ *) t_git_fg="32" ;; # fallback green
162
+ esac
163
+
164
+ # error bg → dir transition
165
+ local t_err_fg
166
+ case "$prompt_err" in
167
+ 41) t_err_fg="31" ;; # red
168
+ 203) t_err_fg="203" ;; # salmon (256-color)
169
+ 131) t_err_fg="131" ;; # nord red (256-color)
170
+ 167) t_err_fg="167" ;; # gruvbox red (256-color)
171
+ 211) t_err_fg="211" ;; # catppuccin red (256-color)
172
+ 168) t_err_fg="168" ;; # rose-pine/kanagawa red (256-color)
173
+ *) t_err_fg="31" ;; # fallback red
174
+ esac
175
+
176
+ # determine if we need 256-color or basic ANSI for bg/fg
177
+ local bg_user bg_dir bg_git fg_git bg_err t_user_dir t_dir_git t_dir_end t_git_end t_err_dir
178
+
179
+ # user segment bg
180
+ if [ "$prompt_user" -le 47 ] 2>/dev/null; then
181
+ bg_user="\\[\\e[${prompt_user}m\\]"
182
+ else
183
+ bg_user="\\[\\e[48;5;${prompt_user}m\\]"
184
+ fi
185
+
186
+ # dir segment bg (always 256-color)
187
+ bg_dir="\\[\\e[48;5;${prompt_dir}m\\]"
188
+
189
+ # git segment bg
190
+ if [ "$prompt_git" -le 47 ] 2>/dev/null; then
191
+ bg_git="\\[\\e[${prompt_git}m\\]"
192
+ else
193
+ bg_git="\\[\\e[48;5;${prompt_git}m\\]"
194
+ fi
195
+
196
+ # error segment bg
197
+ if [ "$prompt_err" -le 47 ] 2>/dev/null; then
198
+ bg_err="\\[\\e[${prompt_err}m\\]"
199
+ else
200
+ bg_err="\\[\\e[48;5;${prompt_err}m\\]"
201
+ fi
202
+
203
+ # git fg (text on git bg) — use black for light bg, white for dark
204
+ case "$prompt_git" in
205
+ 42|142|151|152|107|214) fg_git="\\[\\e[30m\\]" ;; # black text
206
+ *) fg_git="\\[\\e[97m\\]" ;; # white text
207
+ esac
208
+
209
+ # transition: user → dir
210
+ if [ "$t_user_fg" -le 37 ] 2>/dev/null; then
211
+ t_user_dir="\\[\\e[${t_user_fg};48;5;${prompt_dir}m\\]"
212
+ else
213
+ t_user_dir="\\[\\e[38;5;${t_user_fg};48;5;${prompt_dir}m\\]"
214
+ fi
215
+
216
+ # transition: dir → git
217
+ t_dir_git="\\[\\e[38;5;${prompt_dir};48;5;${prompt_git}m\\]"
218
+ if [ "$prompt_git" -le 47 ] 2>/dev/null; then
219
+ t_dir_git="\\[\\e[38;5;${prompt_dir};${prompt_git}m\\]"
220
+ fi
221
+
222
+ # transition: dir → end
223
+ t_dir_end="\\[\\e[38;5;${prompt_dir}m\\]"
224
+
225
+ # transition: git → end
226
+ if [ "$t_git_fg" -le 37 ] 2>/dev/null; then
227
+ t_git_end="\\[\\e[${t_git_fg}m\\]"
228
+ else
229
+ t_git_end="\\[\\e[38;5;${t_git_fg}m\\]"
230
+ fi
231
+
232
+ # transition: err → dir
233
+ if [ "$t_err_fg" -le 37 ] 2>/dev/null; then
234
+ t_err_dir="\\[\\e[${t_err_fg};48;5;${prompt_dir}m\\]"
235
+ else
236
+ t_err_dir="\\[\\e[38;5;${t_err_fg};48;5;${prompt_dir}m\\]"
237
+ fi
238
+
239
+ mkdir -p "$BATIPANEL_HOME/config"
240
+ cat > "$prompt_file" << PROMPT_EOF
241
+ #!/usr/bin/env bash
242
+ # batipanel bash prompt - theme: ${theme} (auto-generated)
243
+
244
+ __batipanel_prompt() {
245
+ local exit_code=\$?
246
+
247
+ # powerline arrow symbols (U+E0B0, U+E0B1)
248
+ local sep=\$'\\uE0B0'
249
+
250
+ # colors (generated from theme: ${theme})
251
+ local bg_user="${bg_user}"
252
+ local fg_user="\\[\\e[97m\\]"
253
+ local bg_dir="${bg_dir}"
254
+ local fg_dir="\\[\\e[97m\\]"
255
+ local bg_git="${bg_git}"
256
+ local fg_git="${fg_git}"
257
+ local bg_err="${bg_err}"
258
+ local fg_err="\\[\\e[97m\\]"
259
+ local reset="\\[\\e[0m\\]"
260
+
261
+ # transition colors
262
+ local t_user_dir="${t_user_dir}"
263
+ local t_dir_git="${t_dir_git}"
264
+ local t_dir_end="${t_dir_end}"
265
+ local t_git_end="${t_git_end}"
266
+ local t_err_dir="${t_err_dir}"
267
+
268
+ # segment 1: username (no hostname)
269
+ local ps=""
270
+ if [ "\$exit_code" -ne 0 ]; then
271
+ ps+="\${bg_err}\${fg_err} ✘ \${exit_code} "
272
+ ps+="\${t_err_dir}\${sep}"
273
+ fi
274
+ ps+="\${bg_user}\${fg_user} \\\\u "
275
+
276
+ # segment 2: working directory
277
+ ps+="\${t_user_dir}\${sep}"
278
+ ps+="\${bg_dir}\${fg_dir} \\\\w "
279
+
280
+ # segment 3: git branch (if in a repo)
281
+ local git_branch=""
282
+ if command -v git &>/dev/null; then
283
+ git_branch="\$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null)"
284
+ fi
285
+
286
+ if [ -n "\$git_branch" ]; then
287
+ ps+="\${t_dir_git}\${sep}"
288
+ local git_icon=\$'\\uE0A0'
289
+ ps+="\${bg_git}\${fg_git} \${git_icon} \${git_branch} "
290
+ ps+="\${reset}\${t_git_end}\${sep}\${reset} "
291
+ else
292
+ ps+="\${reset}\${t_dir_end}\${sep}\${reset} "
293
+ fi
294
+
295
+ PS1="\$ps"
296
+ }
297
+
298
+ PROMPT_COMMAND="__batipanel_prompt"
299
+ PROMPT_EOF
300
+ }
301
+
302
+ # apply theme: generate files, persist config, live reload
303
+ _apply_theme() {
304
+ local theme="$1"
305
+
306
+ # validate theme exists
307
+ if ! _get_theme_colors "$theme" >/dev/null 2>&1; then
308
+ echo -e "${RED}Unknown theme: ${theme}${NC}"
309
+ _list_themes
310
+ return 1
311
+ fi
312
+
313
+ # generate tmux theme overlay
314
+ _generate_theme_conf "$theme"
315
+
316
+ # generate themed bash prompt
317
+ _generate_themed_prompt "$theme"
318
+
319
+ # persist to config.sh
320
+ if [ -f "$TMUX_CONFIG" ]; then
321
+ if grep -qF "BATIPANEL_THEME=" "$TMUX_CONFIG"; then
322
+ _sed_i "s|BATIPANEL_THEME=.*|BATIPANEL_THEME=\"$theme\"|" "$TMUX_CONFIG"
323
+ else
324
+ echo "BATIPANEL_THEME=\"$theme\"" >> "$TMUX_CONFIG"
325
+ fi
326
+ else
327
+ echo "BATIPANEL_THEME=\"$theme\"" > "$TMUX_CONFIG"
328
+ fi
329
+
330
+ # live reload tmux if running
331
+ if command -v tmux &>/dev/null && tmux list-sessions &>/dev/null 2>&1; then
332
+ tmux source-file "$BATIPANEL_HOME/config/tmux.conf" 2>/dev/null || true
333
+ tmux source-file "$BATIPANEL_HOME/config/theme.conf" 2>/dev/null || true
334
+ fi
335
+
336
+ BATIPANEL_THEME="$theme"
337
+ echo -e "${GREEN}Theme applied: ${theme}${NC}"
338
+ }
339
+
340
+ # CLI entry point: b theme [name]
341
+ tmux_theme() {
342
+ local name="${1:-}"
343
+
344
+ case "$name" in
345
+ ""|list)
346
+ echo -e " Current theme: ${GREEN}${BATIPANEL_THEME:-default}${NC}"
347
+ _list_themes
348
+ echo " Change: b theme <name>"
349
+ ;;
350
+ *)
351
+ _apply_theme "$name"
352
+ ;;
353
+ esac
354
+ }
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env bash
2
+ # batipanel validation - tmux version, terminal size, input validation
3
+
4
+ # tmux version check (2.6+ required)
5
+ check_tmux_version() {
6
+ if ! command -v tmux &>/dev/null; then
7
+ echo -e "${RED}tmux is not installed${NC}"
8
+ case "$(uname -s)" in
9
+ Darwin) echo " Install: brew install tmux" ;;
10
+ Linux)
11
+ if command -v apt-get &>/dev/null; then
12
+ echo " Install: sudo apt-get install tmux"
13
+ elif command -v dnf &>/dev/null; then
14
+ echo " Install: sudo dnf install tmux"
15
+ elif command -v pacman &>/dev/null; then
16
+ echo " Install: sudo pacman -S tmux"
17
+ else
18
+ echo " Install tmux using your package manager"
19
+ fi
20
+ ;;
21
+ *) echo " Install tmux for your OS" ;;
22
+ esac
23
+ return 1
24
+ fi
25
+
26
+ local ver
27
+ ver=$(tmux -V | grep -oE '[0-9]+\.[0-9]+' | head -1)
28
+ if [[ -z "$ver" ]]; then
29
+ debug_log "Could not parse tmux version, continuing anyway"
30
+ return 0
31
+ fi
32
+
33
+ local major minor
34
+ major="${ver%%.*}"
35
+ minor="${ver#*.}"
36
+ if (( major < 2 || (major == 2 && minor < 6) )); then
37
+ echo -e "${RED}tmux $ver is too old (2.6+ required)${NC}"
38
+ case "$(uname -s)" in
39
+ Darwin) echo " Upgrade: brew install tmux" ;;
40
+ *)
41
+ if command -v apt-get &>/dev/null; then
42
+ echo " Upgrade: sudo apt-get install --only-upgrade tmux"
43
+ elif command -v dnf &>/dev/null; then
44
+ echo " Upgrade: sudo dnf upgrade tmux"
45
+ else
46
+ echo " Upgrade tmux using your package manager"
47
+ fi
48
+ ;;
49
+ esac
50
+ return 1
51
+ fi
52
+ debug_log "tmux version $ver OK"
53
+ }
54
+
55
+ # session name validation
56
+ validate_session_name() {
57
+ local name="$1"
58
+ if [[ -z "$name" ]]; then
59
+ echo -e "${RED}Session name is required${NC}"
60
+ return 1
61
+ fi
62
+ if ! [[ "$name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
63
+ echo -e "${RED}Session name may only contain letters, numbers, _ and -: $name${NC}"
64
+ return 1
65
+ fi
66
+ }
package/lib/wizard.sh ADDED
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env bash
2
+ # batipanel setup - first-run detection and interactive wizard
3
+
4
+ is_first_run() {
5
+ # First run if no config.sh AND no registered projects
6
+ [[ ! -f "$TMUX_CONFIG" ]] || return 1
7
+ local found=0
8
+ for f in "$BATIPANEL_HOME"/projects/*.sh; do
9
+ [ -f "$f" ] && found=1 && break
10
+ done
11
+ (( found == 0 ))
12
+ }
13
+
14
+ run_wizard() {
15
+ echo ""
16
+ echo -e "${BLUE}=== Welcome to batipanel! ===${NC}"
17
+ echo ""
18
+ echo "Let's set up your workspace in 2 quick steps."
19
+ echo ""
20
+
21
+ local screen_choice screen workflow_choice workflow layout
22
+
23
+ # Step 1: Screen size
24
+ echo -e "${GREEN}Step 1/2: What is your screen size?${NC}"
25
+ echo " 1) Small (laptop 13-14\")"
26
+ echo " 2) Large (external monitor) [default]"
27
+ echo " 3) Ultrawide"
28
+ echo ""
29
+ printf "Choose [1-3]: "
30
+ read -r screen_choice
31
+ screen_choice="${screen_choice:-2}"
32
+ case "$screen_choice" in
33
+ 1) screen="small" ;;
34
+ 3) screen="ultrawide" ;;
35
+ *) screen="large" ;;
36
+ esac
37
+ echo ""
38
+
39
+ # Step 2: Workflow
40
+ echo -e "${GREEN}Step 2/2: What is your primary workflow?${NC}"
41
+ echo " 1) AI coding (Claude Code) [default]"
42
+ echo " 2) General development"
43
+ echo " 3) DevOps / infrastructure"
44
+ echo ""
45
+ printf "Choose [1-3]: "
46
+ read -r workflow_choice
47
+ workflow_choice="${workflow_choice:-1}"
48
+ case "$workflow_choice" in
49
+ 2) workflow="general" ;;
50
+ 3) workflow="devops" ;;
51
+ *) workflow="ai" ;;
52
+ esac
53
+
54
+ # Layout mapping
55
+ case "${screen}:${workflow}" in
56
+ small:ai) layout="4panel" ;;
57
+ small:general) layout="4panel" ;;
58
+ small:devops) layout="devops" ;;
59
+ large:ai) layout="7panel" ;;
60
+ large:general) layout="6panel" ;;
61
+ large:devops) layout="devops" ;;
62
+ ultrawide:ai) layout="dual-claude" ;;
63
+ ultrawide:general) layout="7panel_log" ;;
64
+ ultrawide:devops) layout="devops" ;;
65
+ *) layout="7panel" ;;
66
+ esac
67
+
68
+ echo ""
69
+ echo -e "Selected layout: ${GREEN}${layout}${NC}"
70
+ echo ""
71
+
72
+ # Save config
73
+ mkdir -p "$BATIPANEL_HOME"
74
+ echo "DEFAULT_LAYOUT=\"$layout\"" > "$TMUX_CONFIG"
75
+ # shellcheck disable=SC2034
76
+ DEFAULT_LAYOUT="$layout"
77
+ echo -e "${GREEN}Configuration saved.${NC}"
78
+ echo ""
79
+
80
+ # Offer to register current directory as project
81
+ local cwd proj_name reg_answer
82
+ cwd=$(pwd)
83
+ proj_name=$(basename "$cwd" | tr -c 'a-zA-Z0-9_-' '-' | sed 's/-*$//')
84
+
85
+ echo -e "Register ${BLUE}${cwd}${NC} as project '${GREEN}${proj_name}${NC}'?"
86
+ printf "[Y/n] "
87
+ read -r reg_answer
88
+ if [[ "$reg_answer" != [nN] ]]; then
89
+ tmux_new "$proj_name" "$cwd"
90
+ echo ""
91
+ echo -e "${GREEN}Starting ${proj_name}...${NC}"
92
+ tmux_start "$proj_name" ""
93
+ else
94
+ echo ""
95
+ echo "No problem! Here's how to get started:"
96
+ echo " b new <name> <path> Register a project"
97
+ echo " b <project> Start a session"
98
+ echo " b help Show full help"
99
+ fi
100
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "batipanel",
3
+ "version": "0.3.0",
4
+ "description": "AI-powered terminal workspace manager — multi-panel tmux layouts with Claude Code, git, monitoring, and more",
5
+ "bin": {
6
+ "batipanel": "./bin/cli.sh"
7
+ },
8
+ "scripts": {
9
+ "postinstall": "bash install.sh"
10
+ },
11
+ "keywords": [
12
+ "tmux",
13
+ "claude",
14
+ "ai",
15
+ "terminal",
16
+ "workspace",
17
+ "multi-panel",
18
+ "developer-tools",
19
+ "cli"
20
+ ],
21
+ "author": "bati.ai (https://bati.ai)",
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/batiai/batipanel.git"
26
+ },
27
+ "homepage": "https://github.com/batiai/batipanel",
28
+ "bugs": {
29
+ "url": "https://github.com/batiai/batipanel/issues"
30
+ },
31
+ "os": ["darwin", "linux"],
32
+ "engines": {
33
+ "node": ">=16"
34
+ },
35
+ "files": [
36
+ "bin/",
37
+ "lib/",
38
+ "layouts/",
39
+ "config/",
40
+ "completions/",
41
+ "examples/",
42
+ "install.sh",
43
+ "uninstall.sh",
44
+ "VERSION",
45
+ "LICENSE",
46
+ "README.md"
47
+ ]
48
+ }
package/uninstall.sh ADDED
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env bash
2
+ # uninstall.sh - remove batipanel configuration and aliases
3
+
4
+ set -euo pipefail
5
+
6
+ BATIPANEL_HOME="${BATIPANEL_HOME:-$HOME/.batipanel}"
7
+
8
+ if [ -t 1 ]; then
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ NC='\033[0m'
13
+ else
14
+ RED='' GREEN='' YELLOW='' NC=''
15
+ fi
16
+
17
+ echo ""
18
+ echo -e "${RED}batipanel uninstaller${NC}"
19
+ echo ""
20
+
21
+ # portable sed -i
22
+ _sed_i() {
23
+ if [ "$(uname -s)" = "Darwin" ]; then
24
+ sed -i '' "$@"
25
+ else
26
+ sed -i "$@"
27
+ fi
28
+ }
29
+
30
+ # 1. stop active sessions
31
+ if command -v tmux &>/dev/null; then
32
+ for f in "$BATIPANEL_HOME"/projects/*.sh; do
33
+ [ -f "$f" ] || continue
34
+ name=$(basename "$f" .sh)
35
+ if tmux has-session -t "$name" 2>/dev/null; then
36
+ tmux kill-session -t "$name" 2>/dev/null || true
37
+ echo " Stopped session: $name"
38
+ fi
39
+ done
40
+ fi
41
+
42
+ # 2. remove tmux.conf source line
43
+ if [ -f "$HOME/.tmux.conf" ]; then
44
+ if grep -q "batipanel" "$HOME/.tmux.conf" 2>/dev/null; then
45
+ _sed_i '/# batipanel/d' "$HOME/.tmux.conf"
46
+ _sed_i '/batipanel/d' "$HOME/.tmux.conf"
47
+ echo " Cleaned ~/.tmux.conf"
48
+ fi
49
+ fi
50
+
51
+ # 3. remove shell aliases and completion source lines
52
+ for rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile"; do
53
+ [ -f "$rc" ] || continue
54
+ if grep -q "batipanel" "$rc" 2>/dev/null; then
55
+ _sed_i '/# batipanel/d' "$rc"
56
+ _sed_i '/alias batipanel=/d' "$rc"
57
+ _sed_i '/alias b=.*batipanel/d' "$rc"
58
+ _sed_i '/completions\/batipanel/d' "$rc"
59
+ echo " Cleaned aliases and completions from $(basename "$rc")"
60
+ fi
61
+ done
62
+
63
+ # remove zsh completion from fpath
64
+ local_zsh_comp="${ZDOTDIR:-$HOME}/.zfunc"
65
+ if [ -f "$local_zsh_comp/_batipanel" ]; then
66
+ rm -f "$local_zsh_comp/_batipanel"
67
+ echo " Removed zsh completion"
68
+ fi
69
+
70
+ # 4. stop server containers (if running)
71
+ if [ -f "$BATIPANEL_HOME/server/docker-compose.yml" ]; then
72
+ if command -v docker &>/dev/null && docker info &>/dev/null 2>&1; then
73
+ echo " Stopping server containers..."
74
+ if docker compose version &>/dev/null 2>&1; then
75
+ docker compose -f "$BATIPANEL_HOME/server/docker-compose.yml" down 2>/dev/null || true
76
+ elif command -v docker-compose &>/dev/null; then
77
+ docker-compose -f "$BATIPANEL_HOME/server/docker-compose.yml" down 2>/dev/null || true
78
+ fi
79
+ echo " Server containers stopped"
80
+ fi
81
+ fi
82
+
83
+ # 5. remove ~/.batipanel/ (preserve projects if user wants)
84
+ if [ -d "$BATIPANEL_HOME" ]; then
85
+ project_count=0
86
+ for f in "$BATIPANEL_HOME"/projects/*.sh; do
87
+ [ -f "$f" ] && project_count=$((project_count + 1))
88
+ done
89
+
90
+ if (( project_count > 0 )) && [ -t 0 ]; then
91
+ echo ""
92
+ echo -e "${YELLOW}You have $project_count registered project(s).${NC}"
93
+ printf "Keep project configs in %s/projects/? [Y/n] " "$BATIPANEL_HOME"
94
+ read -r keep_projects
95
+ if [[ "$keep_projects" == [nN] ]]; then
96
+ rm -rf "$BATIPANEL_HOME"
97
+ echo " Removed $BATIPANEL_HOME (including projects)"
98
+ else
99
+ # remove everything except projects/
100
+ find "$BATIPANEL_HOME" -mindepth 1 -maxdepth 1 ! -name projects -exec rm -rf {} +
101
+ echo " Removed $BATIPANEL_HOME (kept projects/)"
102
+ fi
103
+ else
104
+ rm -rf "$BATIPANEL_HOME"
105
+ echo " Removed $BATIPANEL_HOME"
106
+ fi
107
+ fi
108
+
109
+ echo ""
110
+ echo -e "${GREEN}batipanel uninstalled.${NC}"
111
+ echo " Open a new terminal to apply changes."
112
+ echo ""