From f5d572ee264ab19a4a5b571af288a744ef5fa555 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 11:13:54 -0300 Subject: [PATCH 01/13] fix: restore Starship cortex palette --- starship/starship.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/starship/starship.toml b/starship/starship.toml index 6bfa982..a5fb6f8 100644 --- a/starship/starship.toml +++ b/starship/starship.toml @@ -17,9 +17,9 @@ $line_break$character""" # Módulos alineados a la derecha right_format = """$cmd_duration$time""" -palette = 'innit_tech_slate' +palette = 'cortex_warm_slate' -[palettes.innit_tech_slate] +[palettes.cortex_warm_slate] color_fg0 = '#F6F8FA' color_bg1 = '#1C2128' color_bg3 = '#2D333B' @@ -159,7 +159,7 @@ disabled = false [character] disabled = false -success_symbol = '[󰼀](fg:color_fg0) ' +success_symbol = '[󰼀](fg:color_orange) ' error_symbol = '[󰼀](fg:color_red) ' vimcmd_symbol = '[󰼀](fg:color_fg0) ' vimcmd_replace_one_symbol = '[󰼀](fg:color_purple) ' From 197515f561aebf0debbdbe5ab4dd792a4692103f Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 11:14:09 -0300 Subject: [PATCH 02/13] fix: tune Herdr terminal defaults --- herdr/config.toml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/herdr/config.toml b/herdr/config.toml index 06c622c..1edd878 100644 --- a/herdr/config.toml +++ b/herdr/config.toml @@ -6,12 +6,16 @@ sidebar_width = 32 sidebar_min_width = 24 sidebar_max_width = 42 agent_panel_sort = "priority" +hide_tab_bar_when_single_tab = true show_agent_labels_on_pane_borders = true prompt_new_tab_name = true pane_borders = true pane_gaps = true accent = "#F97316" +[ui.sound] +enabled = false + [terminal] new_cwd = "follow" @@ -19,10 +23,10 @@ new_cwd = "follow" resume_agents_on_restore = true [remote] -manage_ssh_config = false +manage_ssh_config = true [theme] -name = "cortex" +name = "terminal" auto_switch = false [theme.custom] From f45297b5dd988706864a9e70da74669d74e22639 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 11:14:16 -0300 Subject: [PATCH 03/13] docs: add Herdr remote restart helpers --- README.md | 3 +++ docs/herdr-workflow.md | 4 ++++ zsh/scripts/herdr-helpers.zsh | 16 ++++++++++++++++ zsh/zshrc | 5 +++++ 4 files changed, 28 insertions(+) diff --git a/README.md b/README.md index c53f98e..1f39e51 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ Seguimiento: [cortex-dotfiles #31](https://github.com/barbatdev/cortex-dotfiles/ | `ccclip ` | Copiar código al clipboard | | `tcc`, `tdev`, `ta`, `tn`, `tl`, `tk` | Helpers tmux (`tcc` abre Claude Code en tmux) | | `wtadd`, `wtlist`, `wtremove` | Helpers de git worktrees | +| `hremote`, `hremote-stop`, `hremote-restart` | Attach/restart seguro de sesiones Herdr remotas nombradas | | `cortex.agent_state.v1`, `agent-state` | Reportar/listar estado local de agentes Cortex y, dentro de Herdr, actualizar el pane actual | | `ss [n]` | Listar últimos screenshots | | `last [-c\|-o]` | Último screenshot | @@ -156,6 +157,8 @@ Usá `hremote` desde tu terminal local en macOS. No hagas `ssh` primero y despu - Para pegar una imagen del clipboard local en la terminal remota, usá `Ctrl+V` por defecto (no `Cmd+V`). - `herdr --remote` puentea ese pegado copiando la imagen a un archivo temporal remoto y pegando el path resultante en la shell remota. +- Si Herdr dice `remote herdr server must restart before this bridge can attach`, corré `hremote-stop ` y después `hremote `. +- `hremote-stop` usa `herdr session stop ` en el host remoto: detiene solo esa sesión nombrada, no el server default. - Una sesión SSH normal no puede leer el clipboard del escritorio local de macOS, así que ese flujo depende de Herdr corriendo del lado local. - Para archivos que no sean imágenes del clipboard, puede seguir haciendo falta un fallback separado de transferencia. diff --git a/docs/herdr-workflow.md b/docs/herdr-workflow.md index 45b28af..56f5c6b 100644 --- a/docs/herdr-workflow.md +++ b/docs/herdr-workflow.md @@ -82,9 +82,13 @@ The default Herdr prefix is `Ctrl+B`. See [keymaps](keymaps.md) for the practica | Reattach role session | `hfocus [path]`, `hside [path]`, `hscratch [path]` | | Reattach explicit session | `herdr --session ` or `herdr session attach ` | | Reattach remote session | `hremote [session]` | +| Stop stale remote session | `hremote-stop [session]` | +| Stop and reattach remote session | `hremote-restart [session]` | Before detaching long-running work, name important panes and run `whereami` if the shell context is ambiguous. +If remote attach reports `remote herdr server must restart before this bridge can attach`, stop only the named remote session with `hremote-stop ` and then reattach. This maps to `herdr session stop ` on the remote host; it does not stop the remote default server. + ## Related Docs - [Keymaps](keymaps.md) diff --git a/zsh/scripts/herdr-helpers.zsh b/zsh/scripts/herdr-helpers.zsh index 9c8a6ba..e8f41f9 100644 --- a/zsh/scripts/herdr-helpers.zsh +++ b/zsh/scripts/herdr-helpers.zsh @@ -149,6 +149,22 @@ hremote() { CORTEX_MULTIPLEXER=herdr CORTEX_SSH_TARGET="$target" herdr --remote "$target" --session "$session" } +# Parar una sesión Herdr remota nombrada cuando el bridge pide restart. +# Uso: hremote-stop [session] +hremote-stop() { + local target="${1:?Uso: hremote-stop [session]}" + local session="${2:-main}" + ssh -t "$target" "PATH=\"\$HOME/.local/bin:\$HOME/.cargo/bin:/usr/local/bin:/usr/bin:/bin:\$PATH\"; herdr session stop '$session'" +} + +# Parar y re-attachar una sesión Herdr remota nombrada. +# Uso: hremote-restart [session] +hremote-restart() { + local target="${1:?Uso: hremote-restart [session]}" + local session="${2:-main}" + hremote-stop "$target" "$session" && hremote "$target" "$session" +} + # Renombrar el pane actual de Herdr con un label humano o uno derivado de repo/branch. hname() { local label="${1:-$(_herdr_workspace_name_for_path "$PWD")}" diff --git a/zsh/zshrc b/zsh/zshrc index af43219..6d0e9dc 100644 --- a/zsh/zshrc +++ b/zsh/zshrc @@ -326,6 +326,11 @@ help-profile() { echo " ${C}ccd [sub] ${R}Navegar al Claude workspace" echo " ${C}ccclip ${R}Copiar código al clipboard" + echo "\n${T}Herdr remoto${R}" + echo " ${C}hremote [s] ${R}Attach a sesión remota" + echo " ${C}hremote-stop [s] ${R}Parar una sesión remota nombrada" + echo " ${C}hremote-restart [s] ${R}Parar y re-attachar sesión remota" + echo "\n${T}Tmux — sesiones${R}" echo " ${C}tcc ${R}Abrir Claude Code + lazygit (layout automático)" echo " ${C}tdev ${R}Sesión con nombre del directorio actual" From f8aa1313b8b84d7045231d333df2c04900ef90fe Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 11:17:40 -0300 Subject: [PATCH 04/13] fix: validate remote Herdr session names --- zsh/scripts/herdr-helpers.zsh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/zsh/scripts/herdr-helpers.zsh b/zsh/scripts/herdr-helpers.zsh index e8f41f9..53a78f7 100644 --- a/zsh/scripts/herdr-helpers.zsh +++ b/zsh/scripts/herdr-helpers.zsh @@ -154,6 +154,13 @@ hremote() { hremote-stop() { local target="${1:?Uso: hremote-stop [session]}" local session="${2:-main}" + + if [[ "$session" == *[^A-Za-z0-9_.-]* ]]; then + echo "Nombre de sesión inválido: $session" + echo "Usá solo letras, números, punto, guion o underscore." + return 1 + fi + ssh -t "$target" "PATH=\"\$HOME/.local/bin:\$HOME/.cargo/bin:/usr/local/bin:/usr/bin:/bin:\$PATH\"; herdr session stop '$session'" } From befa739e1531d722bb58b5bfd3f5c343ae8a9524 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 12:22:59 -0300 Subject: [PATCH 05/13] fix: align Starship orange with Cortex palette --- starship/starship.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starship/starship.toml b/starship/starship.toml index a5fb6f8..1409a59 100644 --- a/starship/starship.toml +++ b/starship/starship.toml @@ -26,7 +26,7 @@ color_bg3 = '#2D333B' color_blue = '#0054ff' color_aqua = '#58A6FF' color_green = '#3FB950' -color_orange = '#0054ff' +color_orange = '#F97316' color_purple = '#8B5CF6' color_red = '#F85149' color_yellow = '#D29922' From 98042307bebd97d58b036d82c23bede5e5b93f06 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 12:25:54 -0300 Subject: [PATCH 06/13] fix: harden remote Herdr stop helper --- zsh/scripts/herdr-helpers.zsh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/zsh/scripts/herdr-helpers.zsh b/zsh/scripts/herdr-helpers.zsh index 53a78f7..1e55441 100644 --- a/zsh/scripts/herdr-helpers.zsh +++ b/zsh/scripts/herdr-helpers.zsh @@ -155,13 +155,19 @@ hremote-stop() { local target="${1:?Uso: hremote-stop [session]}" local session="${2:-main}" + if [[ "$target" == -* ]]; then + echo "Target SSH inválido: $target" + echo "Usá un host o alias SSH, no opciones de ssh." + return 1 + fi + if [[ "$session" == *[^A-Za-z0-9_.-]* ]]; then echo "Nombre de sesión inválido: $session" echo "Usá solo letras, números, punto, guion o underscore." return 1 fi - ssh -t "$target" "PATH=\"\$HOME/.local/bin:\$HOME/.cargo/bin:/usr/local/bin:/usr/bin:/bin:\$PATH\"; herdr session stop '$session'" + ssh -t "$target" "PATH=\"\$HOME/.local/bin:\$HOME/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:\$PATH\"; herdr session stop '$session'" } # Parar y re-attachar una sesión Herdr remota nombrada. From 08daaa2e6c03cc9b96d68c2d613e865c078f05aa Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 12:29:10 -0300 Subject: [PATCH 07/13] fix: address final Herdr review findings --- README.md | 2 +- zsh/scripts/herdr-helpers.zsh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1f39e51..2ed590f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ GitHub Actions ejecuta un smoke check mínimo en pull requests y pushes a `main` - **Terminal**: [Ghostty](https://ghostty.org/) y Alacritty - **Shell**: Zsh nativo de macOS -- **Prompt**: [Starship](https://starship.rs/) — tema Gruvbox Dark +- **Prompt**: [Starship](https://starship.rs/) — paleta Cortex warm slate - **Multiplexor**: tmux + helpers de sesión - **Barra macOS**: [SketchyBar](https://github.com/FelixKratz/SketchyBar) con tema Gruvbox - **Window manager macOS**: [yabai](https://github.com/koekeishiya/yabai) + [skhd](https://github.com/koekeishiya/skhd) opcional y gradual diff --git a/zsh/scripts/herdr-helpers.zsh b/zsh/scripts/herdr-helpers.zsh index 1e55441..848d1f8 100644 --- a/zsh/scripts/herdr-helpers.zsh +++ b/zsh/scripts/herdr-helpers.zsh @@ -161,7 +161,7 @@ hremote-stop() { return 1 fi - if [[ "$session" == *[^A-Za-z0-9_.-]* ]]; then + if [[ "$session" == -* || "$session" == *[^A-Za-z0-9_.-]* ]]; then echo "Nombre de sesión inválido: $session" echo "Usá solo letras, números, punto, guion o underscore." return 1 From ca3a39388b62db27073f2032ea94abf5e3210f80 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 12:32:01 -0300 Subject: [PATCH 08/13] fix: remove duplicate Herdr install entries --- install.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/install.sh b/install.sh index 4b57896..9552879 100755 --- a/install.sh +++ b/install.sh @@ -161,7 +161,6 @@ PY check_command herdr warn check_command mosh warn check_command tmux warn - check_command herdr warn check_command lazygit warn check_command sketchybar warn check_command yabai warn @@ -215,7 +214,6 @@ PY check_symlink_target "$DOTFILES/herdr/config.toml" "$HOME/.config/herdr/config.toml" check_symlink_target "$DOTFILES/ghostty/config" "$HOME/.config/ghostty/config" check_symlink_target "$DOTFILES/ghostty/shaders" "$HOME/.config/ghostty/shaders" - check_symlink_target "$DOTFILES/herdr/config.toml" "$HOME/.config/herdr/config.toml" check_symlink_target "$DOTFILES/opencode/tui.json" "$HOME/.config/opencode/tui.json" check_symlink_target "$DOTFILES/opencode/themes" "$HOME/.config/opencode/themes" check_symlink_target "$DOTFILES/tmux/tmux.conf" "$HOME/.tmux.conf" @@ -448,7 +446,6 @@ backup_if_exists "$HOME/.config/uv/uv.toml" backup_if_exists "$HOME/.config/starship.toml" backup_if_exists "$HOME/.config/herdr/config.toml" backup_if_exists "$HOME/.config/ghostty/config" -backup_if_exists "$HOME/.config/herdr/config.toml" backup_if_exists "$HOME/.config/opencode/tui.json" backup_if_exists "$HOME/.config/opencode/themes" backup_if_exists "$HOME/.tmux.conf" @@ -491,7 +488,6 @@ create_symlink "$DOTFILES/starship/starship.toml" "$HOME/.config/starship.toml" create_symlink "$DOTFILES/herdr/config.toml" "$HOME/.config/herdr/config.toml" create_symlink "$DOTFILES/ghostty/config" "$HOME/.config/ghostty/config" create_symlink "$DOTFILES/ghostty/shaders" "$HOME/.config/ghostty/shaders" -create_symlink "$DOTFILES/herdr/config.toml" "$HOME/.config/herdr/config.toml" create_symlink "$DOTFILES/opencode/tui.json" "$HOME/.config/opencode/tui.json" create_symlink "$DOTFILES/opencode/themes" "$HOME/.config/opencode/themes" create_symlink "$DOTFILES/tmux/tmux.conf" "$HOME/.tmux.conf" From 2c607d5cfcf5e6e0fb37ac599e40b55ed1052209 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 13:03:24 -0300 Subject: [PATCH 09/13] fix: activate mise before Starship init --- zsh/zshrc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zsh/zshrc b/zsh/zshrc index 6d0e9dc..7abae9c 100644 --- a/zsh/zshrc +++ b/zsh/zshrc @@ -18,6 +18,12 @@ fi export PATH="$HOME/.local/bin:$PATH" #endregion +#region Mise +if command -v mise &>/dev/null; then + eval "$(mise activate zsh)" +fi +#endregion + #region Zsh Options # Historia HISTFILE="$HOME/.zsh_history" From 799dd66a5c5a385e7ea313b97badbc70048f3361 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 13:06:51 -0300 Subject: [PATCH 10/13] fix: harden shell helper startup paths --- CLAUDE.md | 2 +- zsh/scripts/ssh-helpers.zsh | 6 +----- zsh/zshrc | 8 ++++++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 8958c95..b2b2d87 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,7 +41,7 @@ dotfiles/ └── install.sh # Instalador ``` -**Flujo de carga del zshrc:** Las secciones están separadas por `#region`/`#endregion`. El orden importa: Brew → PATH → Zsh options → Editor → Env vars → Aliases → Source scripts → Local overrides → Starship → Welcome. +**Flujo de carga del zshrc:** Las secciones están separadas por `#region`/`#endregion`. El orden importa: Brew → PATH → Mise → Zsh options → Editor → Env vars → Aliases → Source scripts → Local overrides → Starship → Welcome. **`local/env.zsh`** está gitignored y contiene paths personales, tokens y overrides de variables de entorno (`SCREENSHOTS_DIR`, `WORKSPACE_DIR`, `WORK_PROJECTS_DIR`). Se genera desde `env.zsh.example` en la primera instalación. diff --git a/zsh/scripts/ssh-helpers.zsh b/zsh/scripts/ssh-helpers.zsh index c7d2dd7..fa13662 100644 --- a/zsh/scripts/ssh-helpers.zsh +++ b/zsh/scripts/ssh-helpers.zsh @@ -4,11 +4,7 @@ _remote_herdr_command_for_path() { local remote_path="$1" local shell_path - if [[ "$remote_path" == "$HOME/"* ]]; then - shell_path="~/${remote_path#$HOME/}" - else - shell_path="${(q)remote_path}" - fi + shell_path="${(q)remote_path}" printf 'cd %s && exec ${SHELL:-zsh}' "$shell_path" } diff --git a/zsh/zshrc b/zsh/zshrc index 7abae9c..0f17baf 100644 --- a/zsh/zshrc +++ b/zsh/zshrc @@ -19,8 +19,12 @@ export PATH="$HOME/.local/bin:$PATH" #endregion #region Mise -if command -v mise &>/dev/null; then - eval "$(mise activate zsh)" +if [[ -x "$HOME/.local/bin/mise" ]]; then + eval "$("$HOME/.local/bin/mise" activate zsh)" +elif [[ -x "/opt/homebrew/bin/mise" ]]; then + eval "$(/opt/homebrew/bin/mise activate zsh)" +elif [[ -x "/usr/local/bin/mise" ]]; then + eval "$(/usr/local/bin/mise activate zsh)" fi #endregion From 9d19e0eb940c20f70218f3bc59601cbd7d3ad8b4 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 13:09:39 -0300 Subject: [PATCH 11/13] fix: move backups before symlink install --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 9552879..5acc258 100755 --- a/install.sh +++ b/install.sh @@ -416,7 +416,7 @@ backup_if_exists() { if [[ "$DRY_RUN" == true ]]; then echo " → Would backup $src to $backup" else - cp -R "$src" "$backup" + mv "$src" "$backup" echo " → Backup: $backup" fi fi From 98f8e3cd89616e51edd266af30faf8e4516522c8 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 13:12:59 -0300 Subject: [PATCH 12/13] fix: align Herdr helper cwd and validation --- zsh/scripts/herdr-helpers.zsh | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/zsh/scripts/herdr-helpers.zsh b/zsh/scripts/herdr-helpers.zsh index 848d1f8..408cb43 100644 --- a/zsh/scripts/herdr-helpers.zsh +++ b/zsh/scripts/herdr-helpers.zsh @@ -64,7 +64,24 @@ _herdr_open_session_for_path() { fi session="$(_herdr_session_name_with_suffix "$resolved" "$suffix")" - CORTEX_MULTIPLEXER=herdr herdr --session "$session" + (cd "$resolved" && CORTEX_MULTIPLEXER=herdr herdr --session "$session") +} + +_herdr_validate_remote_args() { + local target="$1" + local session="$2" + + if [[ "$target" == -* ]]; then + echo "Target SSH inválido: $target" + echo "Usá un host o alias SSH, no opciones de ssh." + return 1 + fi + + if [[ "$session" == -* || "$session" == *[^A-Za-z0-9_.-]* ]]; then + echo "Nombre de sesión inválido: $session" + echo "Usá solo letras, números, punto, guion o underscore." + return 1 + fi } _herdr_workspace_id_by_label() { @@ -146,6 +163,7 @@ hscratch() { hremote() { local target="${1:?Uso: hremote [session]}" local session="${2:-main}" + _herdr_validate_remote_args "$target" "$session" || return CORTEX_MULTIPLEXER=herdr CORTEX_SSH_TARGET="$target" herdr --remote "$target" --session "$session" } @@ -154,18 +172,7 @@ hremote() { hremote-stop() { local target="${1:?Uso: hremote-stop [session]}" local session="${2:-main}" - - if [[ "$target" == -* ]]; then - echo "Target SSH inválido: $target" - echo "Usá un host o alias SSH, no opciones de ssh." - return 1 - fi - - if [[ "$session" == -* || "$session" == *[^A-Za-z0-9_.-]* ]]; then - echo "Nombre de sesión inválido: $session" - echo "Usá solo letras, números, punto, guion o underscore." - return 1 - fi + _herdr_validate_remote_args "$target" "$session" || return ssh -t "$target" "PATH=\"\$HOME/.local/bin:\$HOME/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:\$PATH\"; herdr session stop '$session'" } From f3bbbbb0f7b344b35b42010a85fef5882dd76957 Mon Sep 17 00:00:00 2001 From: Juan Barbat Date: Wed, 8 Jul 2026 14:59:00 -0300 Subject: [PATCH 13/13] fix: back up existing symlinks before install --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 5acc258..47ce5df 100755 --- a/install.sh +++ b/install.sh @@ -411,7 +411,7 @@ echo "💾 Haciendo backup de configs existentes..." backup_if_exists() { local src="$1" - if [[ -e "$src" && ! -L "$src" ]]; then + if [[ -e "$src" || -L "$src" ]]; then local backup="${src}.bak_${TIMESTAMP}" if [[ "$DRY_RUN" == true ]]; then echo " → Would backup $src to $backup"