diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..0beac25 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,67 @@ +# AGENTS.md + +This file provides guidance to Codex (claude.ai/code) when working with code in this repository. + +## Repositorio + +Dotfiles para macOS: configuración de Ghostty + Zsh + Starship. El instalador crea symlinks desde el directorio del repo hacia las ubicaciones estándar del sistema. + +## Instalación y testing + +```bash +# Instalar dotfiles (crea symlinks + instala dependencias via Homebrew) +./install.sh + +# Medir load time del profile zsh +time zsh -i -c exit + +# Verificar que los symlinks están correctos +ls -la ~/.zshrc ~/.config/starship.toml ~/.config/ghostty/config +``` + +No hay tests automatizados. La validación es manual: recargar la shell con `source ~/.zshrc` o `reload` y verificar que los comandos funcionen. + +## Estructura y arquitectura + +``` +dotfiles/ +├── zsh/ +│ ├── zshrc # Profile principal → symlink a ~/.zshrc +│ └── scripts/ # Scripts sourced desde zshrc +│ ├── claude-helpers.zsh # cc, ccx, ccd, ccclip +│ ├── git-helpers.zsh # git-workdev, git-personaldev, git-whoami, clone-* +│ ├── pcsoft-helpers.zsh # is-pcsoft-forbidden, is-pcsoft-editable +│ ├── screenshots.zsh # ss, last, ssd, imgclip +│ └── tmux-helpers.zsh # ta, tn, tk, tl, tdev +├── starship/starship.toml # Prompt Gruvbox Dark → symlink a ~/.config/starship.toml +├── ghostty/config # Terminal → symlink a ~/.config/ghostty/config +├── tmux/tmux.conf # Multiplexor → symlink a ~/.tmux.conf +├── local/ +│ └── env.zsh.example # Template para local/env.zsh (gitignored) +└── 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. + +**`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. + +## Múltiples identidades GitHub + +El repositorio maneja dos cuentas de GitHub con SSH host aliases: +- `github-workdev` → cuenta de trabajo/empresa (configurar con tu email de empresa) +- `github-personaldev` → cuenta personal (configurar con tu email personal) + +Los helpers en `git-helpers.zsh` configuran la identidad local del repo Y actualizan el remote URL para usar el alias SSH correcto. Cuando se agregan nuevas funciones relacionadas con identidades, seguir el mismo patrón. + +## Convenciones al editar + +- Los scripts `.zsh` usan `#region`/`#endregion` para agrupar secciones lógicas. +- Cada función pública en los scripts debe tener un comentario explicando su uso. +- Variables de entorno con defaults se definen como `${VAR:-default}` para permitir override desde `local/env.zsh`. +- `install.sh` usa `set -e` y hace backup de configs existentes antes de crear symlinks — mantener este comportamiento al agregar nuevas configs. + +## Agregar una nueva configuración + +1. Crear el archivo de config en su directorio (`nombre-herramienta/config`) +2. Agregar backup + symlink en `install.sh` siguiendo el patrón existente +3. Actualizar el README.md con la nueva entrada en la tabla de estructura diff --git a/README.md b/README.md index b5d3f81..24f0b8f 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ GitHub Actions ejecuta un smoke check mínimo en pull requests y pushes a `main` - **Keyboard remaps macOS**: [Karabiner-Elements](https://karabiner-elements.pqrs.org/) con profile `cortex` - **Editor terminal**: Neovim basado en LazyVim/Gentleman.Dots; la config host selecciona `gentleman-kanagawa-blur` y no se encontró un overlay RefactorIA en la auditoría - **Ls**: [eza](https://github.com/eza-community/eza) -- **AI CLI UX**: Claude Code statusline, OpenCode helpers y cmux local/remoto -- **Workflow docs**: [cmux workflow](docs/cmux-workflow.md), [Herdr workflow](docs/herdr-workflow.md) y [keymaps prácticos](docs/keymaps.md) +- **AI CLI UX**: Claude Code statusline, OpenCode helpers y herdr local/remoto +- **Workflow docs**: [Herdr workflow](docs/herdr-workflow.md) y [keymaps prácticos](docs/keymaps.md) - **Supply-chain guardrails**: defaults globales para `uv`, `npm`, `pnpm` y `bun` - **Fuente**: FiraCode Nerd Font + variante custom RefactorIA @@ -46,7 +46,7 @@ bash install.sh --dry-run El instalador macOS: -1. Instala dependencias via Homebrew (cmux, starship, tmux, lazygit, neovim, eza, sketchybar, Karabiner-Elements, FiraCode Nerd Font) +1. Instala dependencias via Homebrew (starship, tmux, lazygit, neovim, eza, sketchybar, Karabiner-Elements, FiraCode Nerd Font) 2. Hace backup de configs existentes con timestamp 3. Crea symlinks de los dotfiles y guardrails globales (`.npmrc`, `pnpm/rc`, `.bunfig.toml`, `uv.toml`) 4. Instala los themes y launchers Barbatdev/RefactorIA sin activarlos @@ -54,6 +54,34 @@ El instalador macOS: 6. Intenta arrancar/recargar `sketchybar` sin cortar la instalación si macOS requiere permisos 7. Crea `local/env.zsh` desde el template +### Backups y restore + +Cada destino de symlink existente que no apunte ya al repo se respalda antes de +reescribirlo como `.bak_`: + +- Un symlink existente se respalda con `cp -P` (el link, sin seguir su destino). +- Un archivo o directorio real se respalda con `cp -R`. + +Restore manual: + +```bash +# 1. Quitá el symlink administrado +rm ~/.zshrc +# 2. Restaurá el backup más reciente (lista con ls -la ~/.zshrc.bak_*) +cp -R ~/.zshrc.bak_20260213_101500 ~/.zshrc +``` + +Para directorios completos (por ejemplo `~/.config/opencode/themes`), borrá el +symlink y usá `cp -R backup directorio`. Los backups no se limpian +automáticamente; revisalos periódicamente con: + +```bash +find ~ -maxdepth 4 -name '*.bak_[0-9]*' -print +``` + +Si un destino es un directorio real (no symlink), el instalador aborta antes de +tocar nada: movelo o borralo y volvé a correr `install.sh`. + ## Perfiles visuales opt-in `./install.sh` instala estos assets mediante symlinks individuales. No cambia el theme activo de Pi, Herdr, Fish o Ghostty; tampoco modifica Starship ni las variables universales de Fish. @@ -211,8 +239,7 @@ dotfiles/ │ ├── zshrc # Profile principal (~/.zshrc) │ └── scripts/ │ ├── claude-helpers.zsh # Integración Claude Code -│ ├── cmux-sidebar-refresh.sh # Metadata Cortex para cmux -│ ├── ssh-helpers.zsh # cmux SSH y SSH convencional +│ ├── ssh-helpers.zsh # SSH con contexto de host │ ├── git-helpers.zsh # Identidades Git y clone helpers │ ├── tmux-helpers.zsh # Helpers tmux │ ├── worktree-helpers.zsh # Helpers git worktree @@ -230,8 +257,6 @@ dotfiles/ └── install.sh ``` -> Nota migración cmux: el path legacy `~/Library/Application Support/com.cmuxterm.app/config.ghostty` ya no está gestionado por estos dotfiles. Si todavía existe en tu máquina, podés borrarlo manualmente sin afectar la configuración actual. - ## Boundary con Cortex Este repo sigue siendo standalone: `install.sh` no requiere tener el repo `cortex` disponible y estos dotfiles deben poder instalarse por sí solos. @@ -269,7 +294,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 | -| `sshx`, `sshc`, `sshx-doctor` | cmux SSH persistente, SSH convencional y diagnóstico | +| `sshc` | SSH con contexto de host en el prompt | | `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 | @@ -297,7 +322,7 @@ Editá `local/env.zsh` (gitignored) para configurar: Referencia completa: [Herdr workflow](docs/herdr-workflow.md). Atajos prácticos: [keymaps](docs/keymaps.md). -El profile Fish también expone `h`, `hs`, `hl`, `hhere`, `hmain`, `hrole`, `hnew`, `hfocus`, `hside`, `hscratch`, `hname`, `whereami`, `sshc`, `sshx` y `sshx-doctor`; Home Manager mapea cada función de forma explícita. +El profile Fish también expone `h`, `hs`, `hl`, `hhere`, `hmain`, `hrole`, `hnew`, `hfocus`, `hside`, `hscratch`, `hname`, `whereami` y `sshc`; Home Manager mapea cada función de forma explícita. Usá `hremote` desde tu terminal local en macOS. No hagas `ssh` primero y después intentes levantar `herdr` dentro de esa sesión remota. @@ -428,7 +453,6 @@ No usarlo como banner automático del shell por defecto. En sesiones de trabajo El setup instala estas protecciones globales para reducir riesgo de supply-chain: - `~/.npmrc` - - `min-release-age=7` - `ignore-scripts=true` - `~/Library/Preferences/pnpm/rc` - `minimum-release-age=10080` (7 días en minutos) diff --git a/aerospace/aerospace.toml b/aerospace/aerospace.toml new file mode 100644 index 0000000..8a52958 --- /dev/null +++ b/aerospace/aerospace.toml @@ -0,0 +1,108 @@ +# AeroSpace — migración 1:1 desde yabai (ver ~/.local/backups/yabai-migration-*/). +# Sin SIP, sin scripting addition: los updates de macOS 27 no rompen el tiling. +# Los Spaces de macOS siguen existiendo: el indicador space.1..10 de SketchyBar +# y los atajos ctrl+N de Herdr siguen funcionando sin cambios. + +# --- Global --- +start-at-login = true +after-startup-command = [] + +# Sin gaps: las ventanas usan todo el monitor disponible (igual que yabai). +[gaps] +inner.horizontal = 0 +inner.vertical = 0 +outer.left = 0 +outer.bottom = 0 +outer.top = 0 +outer.right = 0 + +[mode.main.binding] + +# --- Focus (flechas + vim, igual que skhd alt+cmd) --- +alt-cmd-left = 'focus left' +alt-cmd-down = 'focus down' +alt-cmd-up = 'focus up' +alt-cmd-right = 'focus right' +alt-cmd-h = 'focus left' +alt-cmd-j = 'focus down' +alt-cmd-k = 'focus up' +alt-cmd-l = 'focus right' + +# --- Mover ventanas en el layout (swap) --- +alt-cmd-shift-left = 'move left' +alt-cmd-shift-down = 'move down' +alt-cmd-shift-up = 'move up' +alt-cmd-shift-right = 'move right' +alt-cmd-shift-h = 'move left' +alt-cmd-shift-j = 'move down' +alt-cmd-shift-k = 'move up' +alt-cmd-shift-l = 'move right' + +# --- Workspaces 1..9 (mismos atajos que yabai) --- +alt-cmd-1 = 'workspace 1' +alt-cmd-2 = 'workspace 2' +alt-cmd-3 = 'workspace 3' +alt-cmd-4 = 'workspace 4' +alt-cmd-5 = 'workspace 5' +alt-cmd-6 = 'workspace 6' +alt-cmd-7 = 'workspace 7' +alt-cmd-8 = 'workspace 8' +alt-cmd-9 = 'workspace 9' + +# Mover ventana al workspace y seguirla +alt-cmd-shift-1 = 'move-node-to-workspace 1' +alt-cmd-shift-2 = 'move-node-to-workspace 2' +alt-cmd-shift-3 = 'move-node-to-workspace 3' +alt-cmd-shift-4 = 'move-node-to-workspace 4' +alt-cmd-shift-5 = 'move-node-to-workspace 5' +alt-cmd-shift-6 = 'move-node-to-workspace 6' +alt-cmd-shift-7 = 'move-node-to-workspace 7' +alt-cmd-shift-8 = 'move-node-to-workspace 8' +alt-cmd-shift-9 = 'move-node-to-workspace 9' + +# --- Layout --- +alt-cmd-f = ['layout floating tiling'] # era: toggle float +alt-cmd-b = 'balance-sizes' # era: space --balance +alt-cmd-o = ['join-with down'] # era: rotate 90 (aprox. i3: fusionar hacia abajo) +alt-cmd-x = 'resize smart +50' # era: mirror x (no existe; redimensionar) +alt-cmd-y = 'resize smart -50' # era: mirror y (no existe; redimensionar) +alt-cmd-e = 'layout tiles accordion' # era: toggle split (split no juega con normalización) +alt-cmd-shift-f = 'fullscreen' # era: toggle zoom-fullscreen +alt-cmd-tab = 'workspace-back-and-forth' # era: space --focus recent + +# Ayuda de atajos de la barra (era 0x2C = coma) +alt-cmd-comma = 'exec-and-forget ~/.config/sketchybar/plugins/shortcuts_help.sh' + +# Recargar config (era: restart yabai service) +alt-cmd-shift-r = 'reload-config' + +[mode.resize.binding] +h = 'resize width -50' +j = 'resize height +50' +k = 'resize height -50' +l = 'resize width +50' +left = 'resize width -50' +down = 'resize height +50' +up = 'resize height -50' +right = 'resize width +50' +enter = 'mode main' +esc = 'mode main' + +# --- Reglas float (equivalente de yabai manage=off) --- +[[on-window-detected]] +if.app-id = 'com.apple.systempreferences' +run = ['layout floating'] + +[[on-window-detected]] +if.app-id = 'com.apple.calculator' +run = ['layout floating'] + +[[on-window-detected]] +if.app-id = 'com.apple.ActivityMonitor' +run = ['layout floating'] + +[[on-window-detected]] +if.app-id = 'com.apple.finder' +if.window-title-regex-substring = '^(Copy|Move|Info|Preferences)' +check-further-callbacks = true +run = ['layout floating'] diff --git a/archive/yabai-migration/skhdrc b/archive/yabai-migration/skhdrc new file mode 100644 index 0000000..528f7bd --- /dev/null +++ b/archive/yabai-migration/skhdrc @@ -0,0 +1,61 @@ +# Leader = option + command. + +# Focus ventanas +alt + cmd - left : yabai -m window --focus west || yabai -m window --focus prev || true +alt + cmd - down : yabai -m window --focus south || yabai -m window --focus next || true +alt + cmd - up : yabai -m window --focus north || yabai -m window --focus prev || true +alt + cmd - right : yabai -m window --focus east || yabai -m window --focus next || true + +# Aliases Vim adaptados desde Gentleman.Dots; se conserva el leader Option+Command. +alt + cmd - h : yabai -m window --focus west || yabai -m window --focus prev || true +alt + cmd - j : yabai -m window --focus south || yabai -m window --focus next || true +alt + cmd - k : yabai -m window --focus north || yabai -m window --focus prev || true +alt + cmd - l : yabai -m window --focus east || yabai -m window --focus next || true + +# Mover ventanas dentro del layout +alt + cmd + shift - left : yabai -m window --warp west || yabai -m window --swap west || true +alt + cmd + shift - down : yabai -m window --warp south || yabai -m window --swap south || true +alt + cmd + shift - up : yabai -m window --warp north || yabai -m window --swap north || true +alt + cmd + shift - right : yabai -m window --warp east || yabai -m window --swap east || true + +alt + cmd + shift - h : yabai -m window --warp west || yabai -m window --swap west || true +alt + cmd + shift - j : yabai -m window --warp south || yabai -m window --swap south || true +alt + cmd + shift - k : yabai -m window --warp north || yabai -m window --swap north || true +alt + cmd + shift - l : yabai -m window --warp east || yabai -m window --swap east || true + +# Spaces +alt + cmd - 1 : yabai -m space --focus 1 || true +alt + cmd - 2 : yabai -m space --focus 2 || true +alt + cmd - 3 : yabai -m space --focus 3 || true +alt + cmd - 4 : yabai -m space --focus 4 || true +alt + cmd - 5 : yabai -m space --focus 5 || true +alt + cmd - 6 : yabai -m space --focus 6 || true +alt + cmd - 7 : yabai -m space --focus 7 || true +alt + cmd - 8 : yabai -m space --focus 8 || true +alt + cmd - 9 : yabai -m space --focus 9 || true + +# Mover ventana al space y seguirla +alt + cmd + shift - 1 : yabai -m window --space 1 && yabai -m space --focus 1 || true +alt + cmd + shift - 2 : yabai -m window --space 2 && yabai -m space --focus 2 || true +alt + cmd + shift - 3 : yabai -m window --space 3 && yabai -m space --focus 3 || true +alt + cmd + shift - 4 : yabai -m window --space 4 && yabai -m space --focus 4 || true +alt + cmd + shift - 5 : yabai -m window --space 5 && yabai -m space --focus 5 || true +alt + cmd + shift - 6 : yabai -m window --space 6 && yabai -m space --focus 6 || true +alt + cmd + shift - 7 : yabai -m window --space 7 && yabai -m space --focus 7 || true +alt + cmd + shift - 8 : yabai -m window --space 8 && yabai -m space --focus 8 || true +alt + cmd + shift - 9 : yabai -m window --space 9 && yabai -m space --focus 9 || true + +# Layout +alt + cmd - f : yabai -m window --toggle float || true +alt + cmd - b : yabai -m space --balance || true +alt + cmd - r : yabai -m config --space window_gap 0; yabai -m space --balance || true; sketchybar --reload +alt + cmd - o : yabai -m space --rotate 90 || true +alt + cmd - x : yabai -m space --mirror x-axis || true +alt + cmd - y : yabai -m space --mirror y-axis || true +alt + cmd - e : yabai -m window --toggle split || true +alt + cmd + shift - f : yabai -m window --toggle zoom-fullscreen || true +alt + cmd - tab : yabai -m space --focus recent || true +alt + cmd - 0x2C : ~/.config/sketchybar/plugins/shortcuts_help.sh + +# Servicios +alt + cmd + shift - r : yabai --restart-service; skhd --reload; sketchybar --reload diff --git a/archive/yabai-migration/skhdrc-restored b/archive/yabai-migration/skhdrc-restored new file mode 100644 index 0000000..528f7bd --- /dev/null +++ b/archive/yabai-migration/skhdrc-restored @@ -0,0 +1,61 @@ +# Leader = option + command. + +# Focus ventanas +alt + cmd - left : yabai -m window --focus west || yabai -m window --focus prev || true +alt + cmd - down : yabai -m window --focus south || yabai -m window --focus next || true +alt + cmd - up : yabai -m window --focus north || yabai -m window --focus prev || true +alt + cmd - right : yabai -m window --focus east || yabai -m window --focus next || true + +# Aliases Vim adaptados desde Gentleman.Dots; se conserva el leader Option+Command. +alt + cmd - h : yabai -m window --focus west || yabai -m window --focus prev || true +alt + cmd - j : yabai -m window --focus south || yabai -m window --focus next || true +alt + cmd - k : yabai -m window --focus north || yabai -m window --focus prev || true +alt + cmd - l : yabai -m window --focus east || yabai -m window --focus next || true + +# Mover ventanas dentro del layout +alt + cmd + shift - left : yabai -m window --warp west || yabai -m window --swap west || true +alt + cmd + shift - down : yabai -m window --warp south || yabai -m window --swap south || true +alt + cmd + shift - up : yabai -m window --warp north || yabai -m window --swap north || true +alt + cmd + shift - right : yabai -m window --warp east || yabai -m window --swap east || true + +alt + cmd + shift - h : yabai -m window --warp west || yabai -m window --swap west || true +alt + cmd + shift - j : yabai -m window --warp south || yabai -m window --swap south || true +alt + cmd + shift - k : yabai -m window --warp north || yabai -m window --swap north || true +alt + cmd + shift - l : yabai -m window --warp east || yabai -m window --swap east || true + +# Spaces +alt + cmd - 1 : yabai -m space --focus 1 || true +alt + cmd - 2 : yabai -m space --focus 2 || true +alt + cmd - 3 : yabai -m space --focus 3 || true +alt + cmd - 4 : yabai -m space --focus 4 || true +alt + cmd - 5 : yabai -m space --focus 5 || true +alt + cmd - 6 : yabai -m space --focus 6 || true +alt + cmd - 7 : yabai -m space --focus 7 || true +alt + cmd - 8 : yabai -m space --focus 8 || true +alt + cmd - 9 : yabai -m space --focus 9 || true + +# Mover ventana al space y seguirla +alt + cmd + shift - 1 : yabai -m window --space 1 && yabai -m space --focus 1 || true +alt + cmd + shift - 2 : yabai -m window --space 2 && yabai -m space --focus 2 || true +alt + cmd + shift - 3 : yabai -m window --space 3 && yabai -m space --focus 3 || true +alt + cmd + shift - 4 : yabai -m window --space 4 && yabai -m space --focus 4 || true +alt + cmd + shift - 5 : yabai -m window --space 5 && yabai -m space --focus 5 || true +alt + cmd + shift - 6 : yabai -m window --space 6 && yabai -m space --focus 6 || true +alt + cmd + shift - 7 : yabai -m window --space 7 && yabai -m space --focus 7 || true +alt + cmd + shift - 8 : yabai -m window --space 8 && yabai -m space --focus 8 || true +alt + cmd + shift - 9 : yabai -m window --space 9 && yabai -m space --focus 9 || true + +# Layout +alt + cmd - f : yabai -m window --toggle float || true +alt + cmd - b : yabai -m space --balance || true +alt + cmd - r : yabai -m config --space window_gap 0; yabai -m space --balance || true; sketchybar --reload +alt + cmd - o : yabai -m space --rotate 90 || true +alt + cmd - x : yabai -m space --mirror x-axis || true +alt + cmd - y : yabai -m space --mirror y-axis || true +alt + cmd - e : yabai -m window --toggle split || true +alt + cmd + shift - f : yabai -m window --toggle zoom-fullscreen || true +alt + cmd - tab : yabai -m space --focus recent || true +alt + cmd - 0x2C : ~/.config/sketchybar/plugins/shortcuts_help.sh + +# Servicios +alt + cmd + shift - r : yabai --restart-service; skhd --reload; sketchybar --reload diff --git a/archive/yabai-migration/yabairc b/archive/yabai-migration/yabairc new file mode 100755 index 0000000..e5c71fe --- /dev/null +++ b/archive/yabai-migration/yabairc @@ -0,0 +1,34 @@ +#!/bin/bash + +# Config gradual con scripting addition: requiere la autorización parcial de SIP ya preparada. +# Carga la scripting addition solo si la autorización sudo no interactiva ya está instalada. +if sudo -n /opt/homebrew/bin/yabai --load-sa; then + yabai -m signal --add event=dock_did_restart action="sudo -n /opt/homebrew/bin/yabai --load-sa" +fi + +yabai -m config layout bsp +yabai -m config window_placement second_child +yabai -m config split_ratio 0.50 +yabai -m config auto_balance off + +yabai -m config top_padding 0 +yabai -m config bottom_padding 0 +yabai -m config left_padding 0 +yabai -m config right_padding 0 +yabai -m config window_gap 0 + +# Sin padding global: las ventanas usan todo el monitor disponible. + +yabai -m config mouse_follows_focus off +yabai -m config focus_follows_mouse off +yabai -m config mouse_modifier alt +yabai -m config mouse_action1 move +yabai -m config mouse_action2 resize + +# Apps que suelen funcionar mejor flotantes. +yabai -m rule --add app="^System Settings$" manage=off +yabai -m rule --add app="^Calculator$" manage=off +yabai -m rule --add app="^Activity Monitor$" manage=off +yabai -m rule --add app="^Finder$" title="^(Copy|Move|Info|Preferences)" manage=off + +sketchybar --trigger space_change 2>/dev/null || true diff --git a/archive/yabai-migration/yabairc-no-sa-macos27 b/archive/yabai-migration/yabairc-no-sa-macos27 new file mode 100755 index 0000000..2a3f7c5 --- /dev/null +++ b/archive/yabai-migration/yabairc-no-sa-macos27 @@ -0,0 +1,33 @@ +#!/bin/bash + +# Config sin scripting addition: macOS 27 rompe el SA (asmvik/yabai#2800). +# El binario está parcheado (alias 27->26) para window management; las +# operaciones de spaces vía yabai no existen sin SA: se usan los atajos +# nativos de Mission Control (ctrl+1..9 activables en Ajustes). + +yabai -m config layout bsp +yabai -m config window_placement second_child +yabai -m config split_ratio 0.50 +yabai -m config auto_balance off + +yabai -m config top_padding 0 +yabai -m config bottom_padding 0 +yabai -m config left_padding 0 +yabai -m config right_padding 0 +yabai -m config window_gap 0 + +# Sin padding global: las ventanas usan todo el monitor disponible. + +yabai -m config mouse_follows_focus off +yabai -m config focus_follows_mouse off +yabai -m config mouse_modifier alt +yabai -m config mouse_action1 move +yabai -m config mouse_action2 resize + +# Apps que suelen funcionar mejor flotantes. +yabai -m rule --add app="^System Settings$" manage=off +yabai -m rule --add app="^Calculator$" manage=off +yabai -m rule --add app="^Activity Monitor$" manage=off +yabai -m rule --add app="^Finder$" title="^(Copy|Move|Info|Preferences)" manage=off + +sketchybar --trigger space_change 2>/dev/null || true diff --git a/claude/statusline.sh b/claude/statusline.sh index 060dd10..93f480a 100755 --- a/claude/statusline.sh +++ b/claude/statusline.sh @@ -225,21 +225,6 @@ SDD_MODE=$(echo "$SDD_DATA" | cut -d'|' -f1) SDD_SPEC=$(echo "$SDD_DATA" | cut -d'|' -f2) SDD_TASKS=$(echo "$SDD_DATA" | cut -d'|' -f3) -# cmux handles lifecycle/feed with its official hooks; publish only Cortex metadata here. -CMUX_STATUS_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/cortex/cmux-status" -CMUX_STATUS_KEY=$(printf '%s' "${CMUX_WORKSPACE_ID:-default}" | tr -c 'A-Za-z0-9_.-' '_') -CMUX_STATUS_CACHE="$CMUX_STATUS_DIR/$CMUX_STATUS_KEY" -CMUX_STATUS_NOW=$(date +%s) -CMUX_STATUS_LAST=$(cat "$CMUX_STATUS_CACHE" 2>/dev/null || echo 0) -if command -v cmux >/dev/null 2>&1 && [ $((CMUX_STATUS_NOW - CMUX_STATUS_LAST)) -ge 2 ] && cmux ping >/dev/null 2>&1; then - cmux set-status claude_model "$MODEL" >/dev/null 2>&1 || true - cmux set-progress "$(awk -v percent="$CTX_PERCENT" 'BEGIN { printf "%.2f", percent / 100 }')" --label "Context ${CTX_PERCENT}%" >/dev/null 2>&1 || true - umask 077 - mkdir -p "$CMUX_STATUS_DIR" - chmod 700 "$CMUX_STATUS_DIR" - printf '%s\n' "$CMUX_STATUS_NOW" > "$CMUX_STATUS_CACHE.$$" && mv "$CMUX_STATUS_CACHE.$$" "$CMUX_STATUS_CACHE" -fi - # Nombre del directorio DIR_NAME=$(basename "$DIR") diff --git a/docs/cmux-workflow.md b/docs/cmux-workflow.md deleted file mode 100644 index 71d689b..0000000 --- a/docs/cmux-workflow.md +++ /dev/null @@ -1,49 +0,0 @@ -# cmux Workflow - -cmux is the default terminal surface for local and remote agent sessions. It reads the shared Ghostty configuration from `~/.config/ghostty/config`; there is no separate cmux theme file. - -## Agent Integrations - -Install the official lifecycle, Feed, and resume integrations after Claude Code and OpenCode are available: - -```bash -cmux hooks setup -``` - -The dotfiles layer does not replace those hooks. It adds Cortex metadata to the cmux sidebar: - -- project and Git branch -- configured brains -- active SDD spec -- Claude model and context progress - -## Remote Sessions - -Use `sshx` from the Mac to create a persistent cmux SSH workspace: - -```bash -sshx agent-dev -``` - -`cmux ssh` installs its relay daemon on the remote host. Commands such as `cmux notify`, `cmux set-status`, and `cmux set-progress` then update the local Mac workspace through that relay. - -Install agent hooks from inside the remote cmux session too, because the agent binaries and their user-level configuration live on the remote host: - -```bash -cmux hooks setup -``` - -Use `sshc agent-dev` only when a conventional SSH shell without cmux persistence or UI integration is intentional. - -## Commands - -| Command | Purpose | -|---------|---------| -| `cc [path]` | Run Claude Code and publish Cortex metadata | -| `oc [path]` | Run OpenCode and publish Cortex metadata | -| `sshx ` | Open a persistent cmux SSH workspace | -| `sshc ` | Open a conventional SSH connection | -| `sshx-doctor ` | Validate cmux, SSH, and host alias resolution | -| `wtadd [branch]` | Create a worktree and open its agent flow | - -cmux owns agent notifications and resume tokens. Cortex scripts should fail silently when the cmux relay is unavailable so the same shell configuration remains usable outside cmux. diff --git a/docs/refactoria-branding.md b/docs/refactoria-branding.md new file mode 100644 index 0000000..891570e --- /dev/null +++ b/docs/refactoria-branding.md @@ -0,0 +1,86 @@ +# RefactorIA branding contract + +This bounded surface makes RefactorIA the default visual language for Ghostty, Herdr, and SketchyBar without changing behavior, keybindings, services, installed fonts, or host configuration. + +## Official source evidence + +The source of truth is the published RefactorIA site, treated as data only: + +- `https://refactoria.dev` — the `pre.hero-beard` element contains exactly 36 `.hero-beard_row` spans. +- `https://refactoria.dev/_astro/Paragraph.qwlurlYD.css` — official tokens: `light100 #fff`, `light200 #ebebeb`, `light300 #f2effa`, `dark700 #2c2144`, `dark800 #17102a`, `dark900 #0b0714`, `brand500 #7127ff`, and `brand-text #fff`. +- `https://refactoria.dev/_astro/index.BwOF64gR.css` — `.hero-beard` uses the site text color, `line-height: 1.12`, and the mono family. +- The favicon and legacy external PNG are intentionally not used: neither proves equality with the site beard. + +Recorded source SHA-256 values: + +| Source | SHA-256 | +| --- | --- | +| site HTML | `39ed1d64fbe8e39b59e8068da9948dc1bf3e56c5b6679a9b64415b997b1055db` | +| Paragraph CSS | `4c34ae19aecde86b6152d40b8443160ffdfb7439e4e0ba47f747ebf8958c9638` | +| index CSS | `37ae077c398c012ad534081ea7f0f9dafcdadaacda137bd762bbb61a386c2cd4` | + +## Palette roles + +The exact site tokens are used for surfaces, text, selection, and the brand accent. Terminal and status colors are separate adapted semantic roles so errors, warnings, and successes remain distinguishable: + +| Role | Value | Classification | +| --- | --- | --- | +| background | `#0b0714` | official `dark900` | +| surface 2 | `#17102a` | official `dark800` | +| surface 3 | `#2c2144` | official `dark700` | +| text | `#ffffff` | official `light100` / `brand-text` | +| secondary text | `#ebebeb` / `#f2effa` | official `light200` / `light300` | +| brand accent | `#7127ff` | official `brand500` | +| error | `#ff6b8a` | adapted semantic color | +| success | `#58e6a8` | adapted semantic color | +| warning | `#ffc857` | adapted semantic color | +| info | `#8cc8ff` | adapted semantic color | + +Selection follows the site contract: white background with the dark900 foreground. The same palette is repeated in `ghostty/config` and `ghostty/profiles/refactoria.conf`, and in `herdr/config.toml` and `herdr/profiles/refactoria.toml`, so the default and optional RefactorIA launchers do not drift. `herdr/config-base.toml` remains behavior-only. + +## Local adaptation and exception + +This section is local-only. It does not revise official RefactorIA tokens or imply a remote rollout: + +- Adapted legible text violet: `#A477FF`. +- Local beard gold: `#FFDE70`, used by the local Starship default and SketchyBar beard. This is a local adaptation, not the official `brand500`; semantic status colors remain separate. +- In the audited host plugin configuration, Neovim selects only Kanagawa (`gentleman-kanagawa-blur`); no RefactorIA highlight overlay was found, and runtime activation was not confirmed. +- Site tokens, published source hashes, and remote behavior remain unchanged. + +## Isotipo and font + +`assets/refactoria-braille.txt` is the exact 36-row hero source. The existing custom font identity remains stable: + +- Family: `FiraCode Nerd Font Mono Beard` +- Glyph: `U+F0F00` +- Output: `fonts/FiraCodeNerdFontMonoBeard-Reg.ttf` + +`fonts/patch_beard.py` converts canonical Braille dots into a deterministic monochrome SVG (`fonts/refactoria-isotipo.svg`) and then imports that vector into FontForge. This is an offline vectorization of verified site text, not a trace of an unverified logo image. External SVG input remains supported for controlled regeneration. + +Regenerate only the repository artifact with the verified source font: + +```bash +fontforge -script fonts/patch_beard.py \ + --font ~/Library/Fonts/FiraCodeNerdFontMono-Regular.ttf \ + --braille assets/refactoria-braille.txt \ + --svg fonts/refactoria-isotipo.svg \ + --output-dir fonts +``` + +The command does not install the generated font. It preserves the source font's other glyph metrics and restores the target glyph's mono-cell advance width after outline transforms. + +## Recovery checklist + +1. Capture `git status --short --untracked-files=all` and SHA-256 values before editing. +2. Compare only the allowed paths from this change against that baseline; do not restore a whole dirty file containing unrelated work. +3. If regeneration is needed, verify the source-font hash and rerun the offline command above; never copy the result into `~/Library/Fonts` during repository work. +4. Validate configuration and shell syntax before any human-owned activation or reload. + +Recorded repository artifact hashes: + +| Artifact | SHA-256 | +| --- | --- | +| verified source font | `ad88c69cb6a497db9f2714e4b414817aabbee621484a1560bfdb3fd73abdd564` | +| canonical Braille | `785f7832c6f11951c2fc371d86a02791df753213d39dcae0ae2efa1b2c9dae9b` | +| generated SVG | `ffa74a2b5821f56c5aac0a2a6846478e1262a6d651a8fe0ef5b7caa27af6e64c` | +| generated font | `83527223cf5dcd7597e7417347e62bfdf5f7de1b457cf658c8ae615ab7fc4f7f` | diff --git a/fish/atuin/config.toml b/fish/atuin/config.toml new file mode 100644 index 0000000..447d640 --- /dev/null +++ b/fish/atuin/config.toml @@ -0,0 +1,403 @@ +## Base directory for Atuin data files (databases, keys, session, etc.) +## All data file paths default to being relative to this directory. +## linux/mac: ~/.local/share/atuin (or XDG_DATA_HOME/atuin) +## windows: %USERPROFILE%/.local/share/atuin +# data_dir = "~/.local/share/atuin" + +## where to store your database, default is your system data directory +## linux/mac: ~/.local/share/atuin/history.db +## windows: %USERPROFILE%/.local/share/atuin/history.db +# db_path = "~/.history.db" + +## where to store your encryption key, default is your system data directory +## linux/mac: ~/.local/share/atuin/key +## windows: %USERPROFILE%/.local/share/atuin/key +# key_path = "~/.key" + +## where to store your auth session token, default is your system data directory +## linux/mac: ~/.local/share/atuin/session +## windows: %USERPROFILE%/.local/share/atuin/session +# session_path = "~/.session" + +## date format used, either "us" or "uk" +# dialect = "us" + +## default timezone to use when displaying time +## either "l", "local" to use the system's current local timezone, or an offset +## from UTC in the format of "<+|->H[H][:M[M][:S[S]]]" +## for example: "+9", "-05", "+03:30", "-01:23:45", etc. +# timezone = "local" + +## enable or disable automatic sync +# auto_sync = true + +## enable or disable automatic update checks +# update_check = true + +## which release channel to follow with `atuin update` and update checks +## "stable" for stable releases only, "nightly" to also receive prereleases +# update_channel = "stable" + +## address of the sync server +# sync_address = "https://api.atuin.sh" + +## how often to sync history. note that this is only triggered when a command +## is ran, so sync intervals may well be longer +## set it to 0 to sync after every command +# sync_frequency = "5m" + +## which search mode to use for interactive search +## possible values: prefix, fulltext, fuzzy, daemon-fuzzy +# search_mode = "fuzzy" + +## which search mode to use when atuin is invoked from a shell up-key binding +## the accepted values are identical to those of "search_mode" +## leave unspecified to use same mode set in "search_mode" +# search_mode_shell_up_key_binding = "fuzzy" + +## which filter mode to use for interactive search +## possible values: "global", "host", "session", "session-preload", "directory", "workspace" +## consider using search.filters to customize the enablement and order of filter modes +# filter_mode = "global" + +## which filter mode to use when atuin is invoked from a shell up-key binding +## the accepted values are identical to those of "filter_mode" +## leave unspecified to use same mode set in "filter_mode" +# filter_mode_shell_up_key_binding = "global" + +## With workspace filtering enabled, Atuin will filter for commands executed +## in any directory within a git repository tree (default: false). +## +## To use workspace mode by default when available, set this to true and +## set filter_mode to "workspace" or leave it unspecified and +## set search.filters to include "workspace" before other filter modes. +# workspaces = false + +## which display style to use +## possible values: auto, full, compact +# style = "compact" + +## the maximum number of lines the interface should take up +## set it to 0 to always go full screen +# inline_height = 40 + +## the maximum number of lines the interface should take up +## when atuin is invoked from a shell up-key binding +## the accepted values are identical to those of "inline_height" +# inline_height_shell_up_key_binding = 0 + +## Invert the UI - put the search bar at the top , Default to `false` +# invert = false + +## enable or disable showing a preview of the selected command +## useful when the command is longer than the terminal width and is cut off +# show_preview = true + +## what to do when the escape key is pressed when searching +## possible values: return-original, return-query +# exit_mode = "return-original" + +## possible values: emacs, subl +# word_jump_mode = "emacs" + +## characters that count as a part of a word +# word_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + +## number of context lines to show when scrolling by pages +# scroll_context_lines = 1 + +## use ctrl instead of alt as the shortcut modifier key for numerical UI shortcuts +## alt-0 .. alt-9 +# ctrl_n_shortcuts = false + +## Show numeric shortcuts (1..9) beside list items in the TUI +## set to false to hide the moving numbers if you find them distracting +# show_numeric_shortcuts = true + +## default history list format - can also be specified with the --format arg +# history_format = "{time}\t{command}\t{duration}" + +## Defaults to true. If enabled, strip trailing spaces and tabs from commands +## before saving them to history. +## Escaped trailing spaces (for example `printf foo\\ `) are preserved. +# strip_trailing_whitespace = true + +## prevent commands matching any of these regexes from being written to history. +## Note that these regular expressions are unanchored, i.e. if they don't start +## with ^ or end with $, they'll match anywhere in the command. +## For details on the supported regular expression syntax, see +## https://docs.rs/regex/latest/regex/#syntax +# history_filter = [ +# "^secret-cmd", +# "^innocuous-cmd .*--secret=.+", +# ] + +## prevent commands run with cwd matching any of these regexes from being written +## to history. Note that these regular expressions are unanchored, i.e. if they don't +## start with ^ or end with $, they'll match anywhere in CWD. +## For details on the supported regular expression syntax, see +## https://docs.rs/regex/latest/regex/#syntax +# cwd_filter = [ +# "^/very/secret/area", +# ] + +## Configure the maximum height of the preview to show. +## Useful when you have long scripts in your history that you want to distinguish +## by more than the first few lines. +# max_preview_height = 4 + +## Configure whether or not to show the help row, which includes the current Atuin +## version (and whether an update is available), a keymap hint, and the total +## amount of commands in your history. +# show_help = true + +## Configure whether or not to show tabs for search and inspect +# show_tabs = true + +## Configure whether or not the tabs row may be auto-hidden, which includes the current Atuin +## tab, such as Search or Inspector, and other tabs you may wish to see. This will +## only be hidden if there are fewer than this count of lines available, and does not affect the use +## of keyboard shortcuts to switch tab. 0 to never auto-hide, default is 8 (lines). +## This is ignored except in `compact` mode. +# auto_hide_height = 8 + +## Defaults to true. This matches history against a set of default regex, and will not save it if we get a match. Defaults include +## 1. AWS key id +## 2. Github pat (old and new) +## 3. Slack oauth tokens (bot, user) +## 4. Slack webhooks +## 5. Stripe live/test keys +# secrets_filter = true + +## Defaults to true. If enabled, upon hitting enter Atuin will immediately execute the command, +## whereas tab will put the command in the prompt for editing. +## If set to false, both enter and tab will place the command in the prompt for editing. +## This applies for new installs. Old installs will keep the old behaviour unless configured otherwise. +enter_accept = true + +## Defaults to false. If enabled, when triggered after &&, || or |, Atuin will complete commands to chain rather than replace the current line. +# command_chaining = false + +## This specifies the keymap on the startup of `atuin search`. If this is set +## to "auto", the startup keymap mode in the Atuin search is automatically +## selected based on the shell's keymap where the keybinding is defined. If +## this is set to "emacs", "vim-insert", or "vim-normal", the startup keymap +## mode in the Atuin search is forced to be the specified one. +# keymap_mode = "emacs" + +## Cursor style in each keymap mode. If specified, the cursor style is changed +## in entering the cursor shape. Available values are "default" and +## "{blink,steady}-{block,underline,bar}". +# keymap_cursor = { emacs = "blink-block", vim_insert = "blink-block", vim_normal = "steady-block" } + +# network_connect_timeout = 5 +# network_timeout = 30 + +## Extra HTTP headers to send on every request to the sync server. Useful when +## a self-hosted server sits behind a proxy that requires its own auth header, +## e.g. Cloudflare Access. Headers that Atuin sets itself (e.g. Authorization) +## cannot be overridden. When set, cross-origin redirects are refused so these +## headers are never sent to a different origin. +# extra_headers = { "CF-Access-Client-Id" = "...", "CF-Access-Client-Secret" = "..." } + +## Timeout (in seconds) for acquiring a local database connection (sqlite) +# local_timeout = 5 + +## Set this to true and Atuin will minimize motion in the UI - timers will not update live, etc. +## Alternatively, set env NO_MOTION=true +# prefers_reduced_motion = false + +## Defaults to true. Configures whether to store commands that failed (those with non-zero exit status) or not. +# store_failed = true + +[stats] +## Set commands where we should consider the subcommand for statistics. Eg, kubectl get vs just kubectl +# common_subcommands = [ +# "apt", +# "cargo", +# "composer", +# "dnf", +# "docker", +# "dotnet", +# "git", +# "go", +# "ip", +# "jj", +# "kubectl", +# "nix", +# "nmcli", +# "npm", +# "pecl", +# "pnpm", +# "podman", +# "port", +# "systemctl", +# "tmux", +# "yarn", +# ] + +## Set commands that should be totally stripped and ignored from stats +# common_prefix = ["sudo"] + +## Set commands that will be completely ignored from stats +# ignored_commands = [ +# "cd", +# "ls", +# "vi" +# ] + +[keys] +# Defaults to true. If disabled, using the up/down key won't exit the TUI when scrolled past the first/last entry. +# scroll_exits = true + +# Defaults to true. The left arrow key will exit the TUI when scrolling before the first character +# exit_past_line_start = true + +# Defaults to true. The right arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified. +# accept_past_line_end = true + +# Defaults to false. The left arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified. +# accept_past_line_start = false + +# Defaults to false. The backspace key performs the same functionality as Tab and copies the selected line to the command line to be modified when at the start of the line. +# accept_with_backspace = false + +[preview] +## which preview strategy to use to calculate the preview height (respects max_preview_height). +## possible values: auto, static +## auto: length of the selected command. +## static: length of the longest command stored in the history. +## fixed: use max_preview_height as fixed height. +# strategy = "auto" + +[daemon] +## Enables using the daemon to sync. +# enabled = false + +## Automatically start and manage the daemon when needed. +## Not compatible with `systemd_socket = true`. +# autostart = false + +## How often the daemon should sync in seconds +# sync_frequency = 300 + +## The path to the unix socket used by the daemon (on unix systems) +## linux/mac: ~/.local/share/atuin/atuin.sock +## windows: Not Supported +# socket_path = "~/.local/share/atuin/atuin.sock" + +## The daemon pidfile used for lifecycle management. +## Defaults to the Atuin data directory. +# pidfile_path = "~/.local/share/atuin/atuin-daemon.pid" + +## Use systemd socket activation rather than opening the given path (the path must still be correct for the client) +## linux: false +## mac/windows: Not Supported +# systemd_socket = false + +## The port that should be used for TCP on non unix systems +# tcp_port = 8889 + +# [pty_proxy] +## If enabled, `atuin init` will first re-exec your shell inside `atuin pty-proxy`, +## so you don't need a separate `eval "$(atuin pty-proxy init)"` line in your shell +## config. Supported for bash, zsh, fish and nu on unix platforms. +## For the fastest startup, keep your `atuin init` line near the top of your shell +## config: everything sourced before it runs again inside the proxy. +## Safe to combine with an existing `atuin pty-proxy init` line — the proxy only +## starts once. +# enabled = false + +# [theme] +## Color theme to use for rendering in the terminal. +## There are some built-in themes, including the base theme ("default"), +## "autumn" and "marine". You can add your own themes to the "./themes" subdirectory of your +## Atuin config (or ATUIN_THEME_DIR, if provided) as TOML files whose keys should be one or +## more of AlertInfo, AlertWarn, AlertError, Annotation, Base, Guidance, Important, and +## the string values as lowercase entries from this list: +## https://ogeon.github.io/docs/palette/master/palette/named/index.html +## If you provide a custom theme file, it should be called "NAME.toml" and the theme below +## should be the stem, i.e. `theme = "NAME"` for your chosen NAME. +# name = "autumn" + +## Whether the theme manager should output normal or extra information to help fix themes. +## Boolean, true or false. If unset, left up to the theme manager. +# debug = true + +[search] +## The list of enabled filter modes, in order of priority. +## The "workspace" mode is skipped when not in a workspace or workspaces = false. +## Default filter mode can be overridden with the filter_mode setting. +# filters = ["global", "host", "session", "workspace", "directory", "session-preload"] + +## Filter interactive search results by the shell used to run the command: +## +## - "all": show all commands +## +## - "auto": show commands run by the current type of shell, or commands that +## have no shell recorded (for example, from before Atuin started tracking it) +## +## - array of strings: show commands run by any shell in the array; "" includes +## commands that have no recorded shell +# shells = "auto" + +[tmux] +## Enable using atuin with tmux popup (requires tmux >= 3.2) +## When enabled and running inside tmux, Atuin will use a popup window for interactive search. +## Set to false to disable the popup. +## This can also be controlled with the ATUIN_TMUX_POPUP environment variable. +## Note: The tmux popup is currently supported in zsh, bash, and fish shells. This currently doesn't work with iTerm native tmux integration. +# enabled = false + +## Width of the tmux popup window +## Can be a percentage, or integer (e.g. "100" means 100 characters wide) +# width = "80%" + +## Height of the tmux popup window +## Can be a percentage, or integer (e.g. "100" means 100 lines tall) +# height = "60%" + +[ui] +## Columns to display in the interactive search, from left to right. +## The selection indicator (" > ") is always shown first implicitly. +## +## Each column can be specified as a simple string (uses default width) +## or as an object with type, width, and expand: +## { type = "directory", width = 30, expand = true } +## +## Available column types (with default widths): +## duration (5) - Command execution duration (e.g., "123ms") +## time (8) - Relative time since execution (e.g., "59m ago") +## datetime (16) - Absolute timestamp (e.g., "2025-01-22 14:35") +## directory (20) - Working directory (truncated if too long) +## host (15) - Hostname where command was run +## user (10) - Username +## exit (3) - Exit code (colored by success/failure) +## command (*) - The command itself (expands by default) +## +## The "expand" option (default: true for command, false for others) makes a +## column fill remaining space. Only one column should have expand = true. +## +## Default: +# columns = ["duration", "time", "command"] +## +## Examples: +## +## Minimal - more space for commands: +# columns = ["duration", "command"] +## +## With wider directory column: +# columns = ["duration", { type = "directory", width = 30 }, "command"] +## +## Show host for multi-machine sync users: +# columns = ["duration", "time", "host", "command"] +## +## Show exit codes prominently: +# columns = ["exit", "duration", "command"] +## +## Make directory expand instead of command: +# columns = ["duration", "time", { type = "directory", expand = true }, { type = "command", expand = false }] + +## Syntax highlight commands in the search results, using the theme's colors. +## Not available on all platforms (e.g. Windows). +# syntax_highlight = true diff --git a/fish/conf.d/10-core.fish b/fish/conf.d/10-core.fish index c47a5bb..ec82b87 100644 --- a/fish/conf.d/10-core.fish +++ b/fish/conf.d/10-core.fish @@ -16,7 +16,7 @@ if not set -q CORTEX_DOTFILES_DIR; or test -z "$CORTEX_DOTFILES_DIR" set -gx CORTEX_DOTFILES_DIR "$BARBATDEV_DIR/cortex/cortex-dotfiles" end if not set -q CORTEX_MULTIPLEXER; or test -z "$CORTEX_MULTIPLEXER" - set -gx CORTEX_MULTIPLEXER cmux + set -gx CORTEX_MULTIPLEXER herdr end set -gx CLAUDE_CODE_EFFORT_LEVEL high if not set -q WORK_PROJECTS_DIR; or test -z "$WORK_PROJECTS_DIR" diff --git a/fish/functions/sshx-doctor.fish b/fish/functions/sshx-doctor.fish deleted file mode 100644 index 9d06fe7..0000000 --- a/fish/functions/sshx-doctor.fish +++ /dev/null @@ -1,28 +0,0 @@ -# Check cmux and SSH host resolution without connecting. Usage: sshx-doctor -function sshx-doctor --description 'Check cmux and SSH host resolution' - if test (count $argv) -lt 1 - printf 'Uso: sshx-doctor \n' >&2 - return 2 - end - set -l target $argv[1] - if string match -q -- '-*' "$target" - printf 'Target SSH inválido: %s\n' "$target" >&2 - return 1 - end - - set -l failed 0 - if not command -q cmux - printf '✗ cmux no encontrado\n' - set failed 1 - end - if not command -q ssh - printf '✗ ssh no encontrado\n' - set failed 1 - else if ssh -G "$target" >/dev/null 2>&1 - printf '✓ SSH config resuelve: %s\n' "$target" - else - printf '✗ SSH config no resuelve: %s\n' "$target" - set failed 1 - end - return $failed -end diff --git a/fish/functions/sshx.fish b/fish/functions/sshx.fish deleted file mode 100644 index 37c3fe2..0000000 --- a/fish/functions/sshx.fish +++ /dev/null @@ -1,22 +0,0 @@ -# Open a persistent cmux SSH workspace. Usage: sshx [cmux ssh args...] -function sshx --description 'Open persistent cmux SSH workspace' - if test (count $argv) -lt 1 - printf 'Uso: sshx [cmux ssh args...]\n' >&2 - return 2 - end - set -l target $argv[1] - if string match -q -- '-*' "$target" - printf 'Target SSH inválido: %s\n' "$target" >&2 - return 1 - end - if not command -q cmux - printf 'cmux no está disponible; usá sshc para una conexión SSH directa\n' >&2 - return 1 - end - if not command -q ssh - printf 'sshx: ssh is not available\n' >&2 - return 127 - end - set -e argv[1] - env CORTEX_SSH_TARGET="$target" cmux ssh "$target" $argv -end diff --git a/fish/functions/wtadd.fish b/fish/functions/wtadd.fish index 7816ffb..5756ba9 100644 --- a/fish/functions/wtadd.fish +++ b/fish/functions/wtadd.fish @@ -31,7 +31,6 @@ function wtadd end; or return 1 printf 'Worktree created: %s\n' "$worktree" - if test "$CORTEX_MULTIPLEXER" = cmux - cc "$worktree" - end + cc "$worktree" + end diff --git a/fish/tests/w2-core.fish b/fish/tests/w2-core.fish index 8f6a8b6..94f0836 100644 --- a/fish/tests/w2-core.fish +++ b/fish/tests/w2-core.fish @@ -49,10 +49,10 @@ end cp "$core" "$xdg/fish/conf.d/10-core.fish" set -l defaults (run_fish -c 'string join "|" $WORKSPACE_DIR $BARBATDEV_DIR $CORTEX_HOME $CORTEX_ROOT $CORTEX_DOTFILES_DIR $CORTEX_MULTIPLEXER $CLAUDE_CODE_EFFORT_LEVEL $WORK_PROJECTS_DIR $PERSONAL_PROJECTS_DIR $INNIT_DIR $SCREENSHOTS_DIR $EDITOR $VISUAL') -assert_equal "$defaults" "$home/dev|$home/dev/barbatdev|$home/.cortex|$home/dev/barbatdev/cortex/cortex|$home/dev/barbatdev/cortex/cortex-dotfiles|cmux|high|$home/dev/innit-sas|$home/dev/barbatdev/products|$home/dev/innit-sas|$home/Screenshots|$bin/nvim|$bin/nvim" 'defaults and editor selection' +assert_equal "$defaults" "$home/dev|$home/dev/barbatdev|$home/.cortex|$home/dev/barbatdev/cortex/cortex|$home/dev/barbatdev/cortex/cortex-dotfiles|herdr|high|$home/dev/innit-sas|$home/dev/barbatdev/products|$home/dev/innit-sas|$home/Screenshots|$bin/nvim|$bin/nvim" 'defaults and editor selection' set -l empty_defaults (env -i HOME="$home" USER=test-user LOGNAME=test-user XDG_CONFIG_HOME="$xdg" PATH="$bin:/usr/bin:/bin" TERM=xterm-256color LANG=C WORKSPACE_DIR= BARBATDEV_DIR= CORTEX_HOME= CORTEX_ROOT= CORTEX_DOTFILES_DIR= CORTEX_MULTIPLEXER= CLAUDE_CODE_EFFORT_LEVEL= WORK_PROJECTS_DIR= PERSONAL_PROJECTS_DIR= INNIT_DIR= SCREENSHOTS_DIR= "$fish_bin" -c 'string join "|" $WORKSPACE_DIR $BARBATDEV_DIR $CORTEX_HOME $CORTEX_ROOT $CORTEX_DOTFILES_DIR $CORTEX_MULTIPLEXER $CLAUDE_CODE_EFFORT_LEVEL $WORK_PROJECTS_DIR $PERSONAL_PROJECTS_DIR $INNIT_DIR $SCREENSHOTS_DIR') -assert_equal "$empty_defaults" "$home/dev|$home/dev/barbatdev|$home/.cortex|$home/dev/barbatdev/cortex/cortex|$home/dev/barbatdev/cortex/cortex-dotfiles|cmux|high|$home/dev/innit-sas|$home/dev/barbatdev/products|$home/dev/innit-sas|$home/Screenshots" 'empty environment values use defaults' +assert_equal "$empty_defaults" "$home/dev|$home/dev/barbatdev|$home/.cortex|$home/dev/barbatdev/cortex/cortex|$home/dev/barbatdev/cortex/cortex-dotfiles|herdr|high|$home/dev/innit-sas|$home/dev/barbatdev/products|$home/dev/innit-sas|$home/Screenshots" 'empty environment values use defaults' printf 'set -gx WORKSPACE_DIR "$HOME/private-dev"\nset -gx EDITOR private-editor\nset -gx VISUAL private-editor\n' >"$xdg/fish/conf.d/99-local.fish" set -l overrides (run_fish -c 'string join "|" $WORKSPACE_DIR $EDITOR $VISUAL') diff --git a/fish/tests/w5b-herdr-ssh.fish b/fish/tests/w5b-herdr-ssh.fish index f5ac69a..429e967 100644 --- a/fish/tests/w5b-herdr-ssh.fish +++ b/fish/tests/w5b-herdr-ssh.fish @@ -33,10 +33,9 @@ string match -q '*hhere: herdr is not available*' "$missing_herdr"; or fail "hhe printf '%s\n' '#!/bin/sh' 'printf "herdr|%s|%s|%s\n" "$CORTEX_MULTIPLEXER" "$CORTEX_SSH_TARGET" "$*" >> "$HERDR_TEST_LOG"' 'case "$1 $2" in' ' "workspace list") printf "{\"result\":{\"workspaces\":[]}}\n" ;;' 'esac' >"$fake_bin/herdr" printf '%s\n' '#!/bin/sh' 'if [ -n "$HERDR_TEST_WORKSPACE_ID" ]; then printf "%s\n" "$HERDR_TEST_WORKSPACE_ID"; elif [ -n "$HERDR_TEST_PANE_ID" ]; then printf "%s\n" "$HERDR_TEST_PANE_ID"; fi' >"$fake_bin/python3" printf '%s\n' '#!/bin/sh' 'printf "ssh|%s|%s\n" "$CORTEX_SSH_TARGET" "$*" >> "$HERDR_TEST_LOG"' '[ "$1" = -G ] && exit 0' 'exit 99' >"$fake_bin/ssh" -printf '%s\n' '#!/bin/sh' 'printf "cmux|%s|%s\n" "$CORTEX_SSH_TARGET" "$*" >> "$HERDR_TEST_LOG"' >"$fake_bin/cmux" printf '%s\n' '#!/bin/sh' 'printf "testhost\n"' >"$fake_bin/hostname" printf '%s\n' '#!/bin/sh' 'printf "123456\n"' >"$fake_bin/date" -chmod +x "$fake_bin/herdr" "$fake_bin/python3" "$fake_bin/ssh" "$fake_bin/cmux" "$fake_bin/hostname" "$fake_bin/date" +chmod +x "$fake_bin/herdr" "$fake_bin/python3" "$fake_bin/ssh" "$fake_bin/hostname" "$fake_bin/date" set -l local_output (run_function "$fake_bin" hhere "$workspace/project") test -z "$local_output"; or fail "hhere outer output: $local_output" set -l herdr_log (string collect <"$workspace/herdr.log") @@ -69,14 +68,6 @@ run_function "$fake_bin" sshc agent-dev -p 22 set herdr_log (string collect <"$workspace/herdr.log") assert_equal "$herdr_log" 'ssh|agent-dev|agent-dev -p 22' 'sshc routing' printf '' >"$workspace/herdr.log" -run_function "$fake_bin" sshx agent-dev -o StrictHostKeyChecking=no -set herdr_log (string collect <"$workspace/herdr.log") -assert_equal "$herdr_log" 'cmux|agent-dev|ssh agent-dev -o StrictHostKeyChecking=no' 'sshx routing' -printf '' >"$workspace/herdr.log" -run_function "$fake_bin" sshx-doctor agent-dev; or fail 'sshx-doctor success' -set herdr_log (string collect <"$workspace/herdr.log") -assert_equal "$herdr_log" 'ssh||-G agent-dev' 'sshx-doctor must only resolve config' -printf '' >"$workspace/herdr.log" set -l rename_output (env HERDR_TEST_PANE_ID=pane-1 HOME="$workspace/home" PATH="$fake_bin:/usr/bin:/bin" TMPDIR="$workspace/tmp" HERDR_TEST_LOG="$workspace/herdr.log" "$fish_bin" --no-config -c 'set -gx fish_function_path $argv[1]; hname review' "$functions_dir") assert_equal "$rename_output" 'pane: review' 'hname output' set herdr_log (string collect <"$workspace/herdr.log") @@ -85,17 +76,8 @@ if run_function "$fake_bin" sshc -bad >"$workspace/invalid.out" 2>&1 fail 'invalid ssh target must fail' end string match -q '*Target SSH inválido: -bad*' (string collect <"$workspace/invalid.out"); or fail 'invalid ssh target error' -if run_function "$empty_bin" sshx agent-dev >"$workspace/missing-cmux.out" 2>&1 - fail 'missing cmux must fail' -end -string match -q '*cmux no está disponible*' (string collect <"$workspace/missing-cmux.out"); or fail 'missing cmux error' if env HOME="$workspace/home" PATH="$empty_bin" TMPDIR="$workspace/tmp" "$fish_bin" --no-config -c 'set -gx fish_function_path $argv[1]; sshc agent-dev' "$functions_dir" >"$workspace/missing-ssh.out" 2>&1 fail 'missing ssh must fail' end string match -q '*sshc: ssh is not available*' (string collect <"$workspace/missing-ssh.out"); or fail 'missing ssh error' -if env HOME="$workspace/home" PATH="$empty_bin" TMPDIR="$workspace/tmp" "$fish_bin" --no-config -c 'set -gx fish_function_path $argv[1]; sshx-doctor agent-dev' "$functions_dir" >"$workspace/doctor-missing.out" 2>&1 - fail 'doctor without tools must fail' -end -set -l doctor_missing (string collect <"$workspace/doctor-missing.out") -string match -q '*cmux no encontrado*' "$doctor_missing"; and string match -q '*ssh no encontrado*' "$doctor_missing"; or fail 'doctor missing tools' printf 'PASS: Fish W5b Herdr and SSH parity\n' diff --git a/fonts/__pycache__/patch_beard.cpython-314.pyc b/fonts/__pycache__/patch_beard.cpython-314.pyc new file mode 100644 index 0000000..a0698f1 Binary files /dev/null and b/fonts/__pycache__/patch_beard.cpython-314.pyc differ diff --git a/fonts/refactoria-isotipo.svg b/fonts/refactoria-isotipo.svg new file mode 100644 index 0000000..565ad08 --- /dev/null +++ b/fonts/refactoria-isotipo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/fonts/test_patch_beard.py b/fonts/test_patch_beard.py new file mode 100644 index 0000000..3fdbe45 --- /dev/null +++ b/fonts/test_patch_beard.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +"""Dependency-light tests for the deterministic Braille-to-SVG conversion.""" + +from __future__ import annotations + +from pathlib import Path +import sys + + +ROOT = Path(__file__).resolve().parent.parent +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +from patch_beard import BRAILLE_BASE, braille_to_svg, parse_braille_rows # noqa: E402 + + +ASSET = ROOT / "assets" / "refactoria-braille.txt" +SVG = ROOT / "fonts" / "refactoria-isotipo.svg" + + +def assert_raises(expected: type[BaseException], callback) -> None: + try: + callback() + except expected: + return + raise AssertionError(f"expected {expected.__name__}") + + +def main() -> int: + rows = parse_braille_rows(ASSET.read_text(encoding="utf-8")) + assert len(rows) == 36 + assert {len(row) for row in rows} == {56} + assert all(BRAILLE_BASE <= ord(char) <= BRAILLE_BASE + 0xFF for row in rows for char in row) + + svg = braille_to_svg(rows) + assert svg == braille_to_svg(rows), "conversion must be deterministic" + assert ' 1000, "the canonical silhouette must retain its active dots" + + full_cell = braille_to_svg(["⣿"]) + assert full_cell.count("M ") == 8 + assert_raises(ValueError, lambda: parse_braille_rows("not braille")) + assert_raises(ValueError, lambda: braille_to_svg(["⠀"])) + + if SVG.exists(): + assert SVG.read_text(encoding="utf-8") == svg, "checked-in SVG must be reproducible from the asset" + + print("patch_beard conversion tests: PASS") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/herdr/config.toml b/herdr/config.toml index 05119ad..851346a 100644 --- a/herdr/config.toml +++ b/herdr/config.toml @@ -6,7 +6,7 @@ next_agent = "prefix+alt+j" focus_agent = "prefix+ctrl+1..9" [ui.toast] -delivery = "terminal" +delivery = "herdr" [ui] sidebar_width = 32 @@ -56,4 +56,4 @@ teal = "#66E6E6" peach = "#FFC857" [ui.sound] -enabled = true +enabled = false diff --git a/herdr/patches/v0.9.1-endpoint-menu-contrast.patch b/herdr/patches/v0.9.1-endpoint-menu-contrast.patch new file mode 100644 index 0000000..4813d2a --- /dev/null +++ b/herdr/patches/v0.9.1-endpoint-menu-contrast.patch @@ -0,0 +1,49 @@ +--- a/src/client/shell/endpoint_sidebar.rs ++++ b/src/client/shell/endpoint_sidebar.rs +@@ -522,17 +522,35 @@ + width, + 1, + ); +- put_right_text( +- buffer, +- workspace_area, +- footer_y, +- if attention { "● menu" } else { "menu" }, +- Style::default().fg(if attention { +- palette.accent +- } else { +- palette.overlay0 +- }), +- ); ++ if attention { ++ let start_x = workspace_area.right().saturating_sub(6); ++ put_text( ++ buffer, ++ start_x, ++ footer_y, ++ 2, ++ "● ", ++ Style::default() ++ .fg(palette.accent) ++ .add_modifier(Modifier::BOLD), ++ ); ++ put_text( ++ buffer, ++ start_x.saturating_add(2), ++ footer_y, ++ 4, ++ "menu", ++ Style::default().fg(palette.overlay0), ++ ); ++ } else { ++ put_right_text( ++ buffer, ++ workspace_area, ++ footer_y, ++ "menu", ++ Style::default().fg(palette.overlay0), ++ ); ++ } + } + super::endpoint_agents::render_expanded( + buffer, diff --git a/install.sh b/install.sh index 08c43b5..17b82f3 100755 --- a/install.sh +++ b/install.sh @@ -7,6 +7,60 @@ TIMESTAMP=$(date +%Y%m%d_%H%M%S) DRY_RUN=false PLATFORM="$(uname -s)" +# --- Managed symlink manifest (single source of truth) --- +# Format: "repo-relative-src|absolute-destination|platform" +# platform: "all" or "darwin". Consumed by backup, symlink creation and --check, +# so a new dotfile only needs one entry here. +MANAGED_LINKS=( + "zsh/zshrc|$HOME/.zshrc|all" + "npm/npmrc|$HOME/.npmrc|all" + "bun/bunfig.toml|$HOME/.bunfig.toml|all" + "aerospace/aerospace.toml|$HOME/.config/aerospace/aerospace.toml|all" + "uv/uv.toml|$HOME/.config/uv/uv.toml|all" + "starship/starship.toml|$HOME/.config/starship.toml|all" + "herdr/config.toml|$HOME/.config/herdr/config.toml|all" + "herdr/config-base.toml|$HOME/.config/herdr/config-base.toml|all" + "herdr/profiles/barbatdev.toml|$HOME/.config/herdr/profiles/barbatdev.toml|all" + "herdr/profiles/refactoria.toml|$HOME/.config/herdr/profiles/refactoria.toml|all" + "fish/themes/barbatdev.fish|$HOME/.config/fish/themes/barbatdev.fish|all" + "fish/themes/refactoria.fish|$HOME/.config/fish/themes/refactoria.fish|all" + "fish/functions/hbarbatdev.fish|$HOME/.config/fish/functions/hbarbatdev.fish|all" + "fish/functions/hrefactoria.fish|$HOME/.config/fish/functions/hrefactoria.fish|all" + "pi/themes/barbatdev.json|$HOME/.pi/agent/themes/barbatdev.json|all" + "pi/themes/refactoria.json|$HOME/.pi/agent/themes/refactoria.json|all" + "ghostty/config|$HOME/.config/ghostty/config|all" + "ghostty/shaders|$HOME/.config/ghostty/shaders|all" + "ghostty/profiles/barbatdev.conf|$HOME/.config/ghostty/profiles/barbatdev.conf|darwin" + "ghostty/profiles/refactoria.conf|$HOME/.config/ghostty/profiles/refactoria.conf|darwin" + "fish/functions/gbarbatdev.fish|$HOME/.config/fish/functions/gbarbatdev.fish|darwin" + "fish/functions/grefactoria.fish|$HOME/.config/fish/functions/grefactoria.fish|darwin" + "opencode/themes|$HOME/.config/opencode/themes|all" + "tmux/tmux.conf|$HOME/.tmux.conf|all" + "claude/statusline.sh|$HOME/.claude/statusline.sh|all" + "claude/themes|$HOME/.claude/themes|all" + "lazygit/config.yml|$HOME/.config/lazygit/config.yml|all" + "pnpm/rc|$HOME/Library/Preferences/pnpm/rc|darwin" + "sketchybar|$HOME/.config/sketchybar|darwin" + "karabiner/karabiner.json|$HOME/.config/karabiner/karabiner.json|darwin" +) + +# Whether a manifest entry (src|dst|platform) applies to the current platform. +link_applies() { + local platform="$3" + [[ "$platform" == "all" ]] && return 0 + [[ "$platform" == "darwin" && "$PLATFORM" == "Darwin" ]] +} + +# Emit each applicable manifest entry as "abs-src|dst|platform". +manifest_entries() { + local entry src dst platform + for entry in "${MANAGED_LINKS[@]}"; do + IFS='|' read -r src dst platform <<<"$entry" + link_applies "$src" "$dst" "$platform" || continue + printf '%s|%s|%s\n' "$DOTFILES/$src" "$dst" "$platform" + done +} + if [[ "${1:-}" == "--dry-run" ]]; then DRY_RUN=true fi @@ -158,7 +212,6 @@ PY check_command starship warn check_command nvim warn check_command eza warn - check_command cmux warn check_command tmux warn check_command lazygit warn check_command sketchybar warn @@ -201,43 +254,17 @@ PY echo "" echo "checking symlink targets" - check_symlink_target "$DOTFILES/zsh/zshrc" "$HOME/.zshrc" - check_symlink_target "$DOTFILES/npm/npmrc" "$HOME/.npmrc" - check_symlink_target "$DOTFILES/bun/bunfig.toml" "$HOME/.bunfig.toml" - check_symlink_target "$DOTFILES/uv/uv.toml" "$HOME/.config/uv/uv.toml" - check_symlink_target "$DOTFILES/starship/starship.toml" "$HOME/.config/starship.toml" - check_symlink_target "$DOTFILES/herdr/config.toml" "$HOME/.config/herdr/config.toml" - check_symlink_target "$DOTFILES/herdr/config-base.toml" "$HOME/.config/herdr/config-base.toml" - check_symlink_target "$DOTFILES/herdr/profiles/barbatdev.toml" "$HOME/.config/herdr/profiles/barbatdev.toml" - check_symlink_target "$DOTFILES/herdr/profiles/refactoria.toml" "$HOME/.config/herdr/profiles/refactoria.toml" - check_symlink_target "$DOTFILES/fish/themes/barbatdev.fish" "$HOME/.config/fish/themes/barbatdev.fish" - check_symlink_target "$DOTFILES/fish/themes/refactoria.fish" "$HOME/.config/fish/themes/refactoria.fish" - check_symlink_target "$DOTFILES/fish/functions/hbarbatdev.fish" "$HOME/.config/fish/functions/hbarbatdev.fish" - check_symlink_target "$DOTFILES/fish/functions/hrefactoria.fish" "$HOME/.config/fish/functions/hrefactoria.fish" - check_symlink_target "$DOTFILES/pi/themes/barbatdev.json" "$HOME/.pi/agent/themes/barbatdev.json" - check_symlink_target "$DOTFILES/pi/themes/refactoria.json" "$HOME/.pi/agent/themes/refactoria.json" - check_symlink_target "$DOTFILES/ghostty/config" "$HOME/.config/ghostty/config" - check_symlink_target "$DOTFILES/ghostty/shaders" "$HOME/.config/ghostty/shaders" - if [[ "$(uname -s)" == "Darwin" ]]; then - check_symlink_target "$DOTFILES/ghostty/profiles/barbatdev.conf" "$HOME/.config/ghostty/profiles/barbatdev.conf" - check_symlink_target "$DOTFILES/ghostty/profiles/refactoria.conf" "$HOME/.config/ghostty/profiles/refactoria.conf" - check_symlink_target "$DOTFILES/fish/functions/gbarbatdev.fish" "$HOME/.config/fish/functions/gbarbatdev.fish" - check_symlink_target "$DOTFILES/fish/functions/grefactoria.fish" "$HOME/.config/fish/functions/grefactoria.fish" - fi + manifest_count=0 + while IFS='|' read -r src dst _; do + check_symlink_target "$src" "$dst" + manifest_count=$((manifest_count + 1)) + done < <(manifest_entries) + pass "manifest symlinks checked: $manifest_count" check_file "$DOTFILES/opencode/tui.json" if [[ -L "$HOME/.config/opencode/tui.json" ]]; then warn "opencode tui.json is a symlink; gentle-ai sync refuses it (install.sh converts it to a copy)" fi - check_symlink_target "$DOTFILES/opencode/themes" "$HOME/.config/opencode/themes" - check_symlink_target "$DOTFILES/tmux/tmux.conf" "$HOME/.tmux.conf" - check_symlink_target "$DOTFILES/claude/statusline.sh" "$HOME/.claude/statusline.sh" - check_symlink_target "$DOTFILES/claude/themes" "$HOME/.claude/themes" - check_symlink_target "$DOTFILES/lazygit/config.yml" "$HOME/.config/lazygit/config.yml" - if [[ "$(uname -s)" == "Darwin" ]]; then - check_symlink_target "$DOTFILES/pnpm/rc" "$HOME/Library/Preferences/pnpm/rc" - check_symlink_target "$DOTFILES/sketchybar" "$HOME/.config/sketchybar" - check_symlink_target "$DOTFILES/karabiner/karabiner.json" "$HOME/.config/karabiner/karabiner.json" - else + if [[ "$(uname -s)" != "Darwin" ]]; then pass "macOS-only symlink targets skipped on non-macOS platform" fi @@ -256,9 +283,9 @@ PY check_shell "$path" bash done check_json "$DOTFILES/karabiner/karabiner.json" - for path in "$DOTFILES"/opencode/*.json "$DOTFILES"/opencode/**/*.json "$DOTFILES"/claude/themes/*.json "$DOTFILES"/pi/themes/*.json; do + while IFS= read -r -d '' path; do check_json "$path" - done + done < <(find "$DOTFILES/opencode" "$DOTFILES/claude/themes" "$DOTFILES/pi/themes" -name '*.json' -type f -print0 2>/dev/null | sort -z) for path in \ "$DOTFILES/fish/themes/barbatdev.fish" \ "$DOTFILES/fish/themes/refactoria.fish" \ @@ -271,9 +298,9 @@ PY check_toml "$DOTFILES/starship/starship.toml" check_toml "$DOTFILES/bun/bunfig.toml" check_toml "$DOTFILES/uv/uv.toml" - for path in "$DOTFILES"/herdr/*.toml "$DOTFILES"/herdr/**/*.toml; do + while IFS= read -r -d '' path; do check_toml "$path" - done + done < <(find "$DOTFILES/herdr" -name '*.toml' -type f -print0 2>/dev/null | sort -z) echo "" if [[ "$CRITICAL_FAILURES" -gt 0 ]]; then @@ -392,10 +419,10 @@ karabiner_cli_path() { if [[ "$PLATFORM" == "Darwin" ]]; then install_formula_if_missing nvim neovim "editor terminal" install_formula_if_missing eza eza "ls mejorado" - install_cask_if_missing "/Applications/cmux.app" cmux manaflow-ai/cmux install_formula_if_missing tmux tmux "multiplexor de terminal" install_formula_if_missing lazygit lazygit "git TUI" install_formula_if_missing sketchybar sketchybar "barra macOS" + install_cask_if_missing "/Applications/AeroSpace.app" aerospace nikitabobko/tap if ! karabiner_cli_available && ! karabiner_app_exists; then if [[ "$DRY_RUN" == true ]]; then @@ -442,47 +469,16 @@ fi echo "" echo "💾 Haciendo backup de configs existentes..." -backup_if_exists() { +# Unified backup: symlinks are backed up with cp -P (never following the +# operand into the repo), real files/dirs with cp -R. An already-correct +# managed symlink is skipped so re-running install creates no new backups. +backup_path() { local src="$1" - if [[ -e "$src" && ! -L "$src" ]]; then - local backup="${src}.bak_${TIMESTAMP}" - if [[ "$DRY_RUN" == true ]]; then - echo " → Would backup $src to $backup" - else - cp -R "$src" "$backup" - echo " → Backup: $backup" - fi - fi -} - -backup_karabiner_if_exists() { - local src="$HOME/.config/karabiner/karabiner.json" - if [[ -e "$src" || -L "$src" ]]; then - local backup="${src}.bak_${TIMESTAMP}" - if [[ "$DRY_RUN" == true ]]; then - echo " → Would backup $src to $backup" - else - if [[ -L "$src" ]]; then - cp -P "$src" "$backup" - else - cp "$src" "$backup" - fi - echo " → Backup: $backup" - fi - fi -} - -backup_managed_symlink() { - local expected_src="$1" local dst="$2" - - if [[ -L "$dst" && "$(readlink "$dst")" == "$expected_src" ]]; then - return - fi - if [[ ! -e "$dst" && ! -L "$dst" ]]; then - return + [[ -e "$dst" || -L "$dst" ]] || return 0 + if [[ -L "$dst" && "$(readlink "$dst")" == "$src" ]]; then + return 0 fi - local backup="${dst}.bak_${TIMESTAMP}" if [[ "$DRY_RUN" == true ]]; then echo " → Would backup $dst to $backup" @@ -495,37 +491,31 @@ backup_managed_symlink() { fi } -backup_if_exists "$HOME/.zshrc" -backup_if_exists "$HOME/.npmrc" -backup_if_exists "$HOME/.bunfig.toml" -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/themes" -backup_if_exists "$HOME/.tmux.conf" -backup_if_exists "$HOME/.claude/statusline.sh" -backup_if_exists "$HOME/.claude/themes" -backup_if_exists "$HOME/.config/lazygit/config.yml" -backup_managed_symlink "$DOTFILES/fish/themes/barbatdev.fish" "$HOME/.config/fish/themes/barbatdev.fish" -backup_managed_symlink "$DOTFILES/fish/themes/refactoria.fish" "$HOME/.config/fish/themes/refactoria.fish" -backup_managed_symlink "$DOTFILES/fish/functions/hbarbatdev.fish" "$HOME/.config/fish/functions/hbarbatdev.fish" -backup_managed_symlink "$DOTFILES/fish/functions/hrefactoria.fish" "$HOME/.config/fish/functions/hrefactoria.fish" -backup_managed_symlink "$DOTFILES/herdr/config-base.toml" "$HOME/.config/herdr/config-base.toml" -backup_managed_symlink "$DOTFILES/herdr/profiles/barbatdev.toml" "$HOME/.config/herdr/profiles/barbatdev.toml" -backup_managed_symlink "$DOTFILES/herdr/profiles/refactoria.toml" "$HOME/.config/herdr/profiles/refactoria.toml" -backup_managed_symlink "$DOTFILES/pi/themes/barbatdev.json" "$HOME/.pi/agent/themes/barbatdev.json" -backup_managed_symlink "$DOTFILES/pi/themes/refactoria.json" "$HOME/.pi/agent/themes/refactoria.json" -if [[ "$PLATFORM" == "Darwin" ]]; then - backup_managed_symlink "$DOTFILES/ghostty/profiles/barbatdev.conf" "$HOME/.config/ghostty/profiles/barbatdev.conf" - backup_managed_symlink "$DOTFILES/ghostty/profiles/refactoria.conf" "$HOME/.config/ghostty/profiles/refactoria.conf" - backup_managed_symlink "$DOTFILES/fish/functions/gbarbatdev.fish" "$HOME/.config/fish/functions/gbarbatdev.fish" - backup_managed_symlink "$DOTFILES/fish/functions/grefactoria.fish" "$HOME/.config/fish/functions/grefactoria.fish" - backup_if_exists "$HOME/Library/Preferences/pnpm/rc" - backup_if_exists "$HOME/.config/sketchybar" - backup_karabiner_if_exists -fi +# Pre-flight: a real directory at a symlink destination cannot be replaced by +# ln -sfn (it would fail mid-run with set -e). Abort cleanly before any change. +preflight_conflicts() { + local src dst conflicts=0 + while IFS='|' read -r src dst _; do + if [[ -d "$dst" && ! -L "$dst" ]]; then + if [[ "$DRY_RUN" == true ]]; then + echo " → Would abort: $dst is a real directory; remove or move it before installing" + else + echo "❌ $dst es un directorio real; movelo o borralo antes de instalar (el symlink no puede reemplazarlo)." + fi + conflicts=$((conflicts + 1)) + fi + done < <(manifest_entries) + if [[ "$conflicts" -gt 0 && "$DRY_RUN" != true ]]; then + echo "Abortando: $conflicts destino(s) son directorios reales y romperían la creación de symlinks." + exit 1 + fi +} + +preflight_conflicts + +while IFS='|' read -r src dst _; do + backup_path "$src" "$dst" +done < <(manifest_entries) # --- Crear symlinks --- echo "" @@ -545,45 +535,16 @@ create_symlink() { fi } -create_symlink "$DOTFILES/zsh/zshrc" "$HOME/.zshrc" -create_symlink "$DOTFILES/npm/npmrc" "$HOME/.npmrc" -create_symlink "$DOTFILES/bun/bunfig.toml" "$HOME/.bunfig.toml" -create_symlink "$DOTFILES/uv/uv.toml" "$HOME/.config/uv/uv.toml" -create_symlink "$DOTFILES/starship/starship.toml" "$HOME/.config/starship.toml" -create_symlink "$DOTFILES/herdr/config.toml" "$HOME/.config/herdr/config.toml" -create_symlink "$DOTFILES/herdr/config-base.toml" "$HOME/.config/herdr/config-base.toml" -create_symlink "$DOTFILES/herdr/profiles/barbatdev.toml" "$HOME/.config/herdr/profiles/barbatdev.toml" -create_symlink "$DOTFILES/herdr/profiles/refactoria.toml" "$HOME/.config/herdr/profiles/refactoria.toml" -create_symlink "$DOTFILES/fish/themes/barbatdev.fish" "$HOME/.config/fish/themes/barbatdev.fish" -create_symlink "$DOTFILES/fish/themes/refactoria.fish" "$HOME/.config/fish/themes/refactoria.fish" -create_symlink "$DOTFILES/fish/functions/hbarbatdev.fish" "$HOME/.config/fish/functions/hbarbatdev.fish" -create_symlink "$DOTFILES/fish/functions/hrefactoria.fish" "$HOME/.config/fish/functions/hrefactoria.fish" -create_symlink "$DOTFILES/pi/themes/barbatdev.json" "$HOME/.pi/agent/themes/barbatdev.json" -create_symlink "$DOTFILES/pi/themes/refactoria.json" "$HOME/.pi/agent/themes/refactoria.json" -create_symlink "$DOTFILES/ghostty/config" "$HOME/.config/ghostty/config" -create_symlink "$DOTFILES/ghostty/shaders" "$HOME/.config/ghostty/shaders" -if [[ "$PLATFORM" == "Darwin" ]]; then - create_symlink "$DOTFILES/ghostty/profiles/barbatdev.conf" "$HOME/.config/ghostty/profiles/barbatdev.conf" - create_symlink "$DOTFILES/ghostty/profiles/refactoria.conf" "$HOME/.config/ghostty/profiles/refactoria.conf" - create_symlink "$DOTFILES/fish/functions/gbarbatdev.fish" "$HOME/.config/fish/functions/gbarbatdev.fish" - create_symlink "$DOTFILES/fish/functions/grefactoria.fish" "$HOME/.config/fish/functions/grefactoria.fish" -fi +while IFS='|' read -r src dst _; do + create_symlink "$src" "$dst" +done < <(manifest_entries) # gentle-ai sync edits tui.json and refuses symlinks: seed a copy instead. # shellcheck source=scripts/seed-file.sh source "$DOTFILES/scripts/seed-file.sh" -seed_file "$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" +seed_file "$DOTFILES/opencode/tui.json" "$HOME/.config/opencode/tui.json" run_or_plan "chmod +x $DOTFILES/claude/statusline.sh" chmod +x "$DOTFILES/claude/statusline.sh" -run_or_plan "chmod +x cmux integration scripts" chmod +x "$DOTFILES/zsh/scripts/cmux-sidebar-refresh.sh" -create_symlink "$DOTFILES/claude/statusline.sh" "$HOME/.claude/statusline.sh" -create_symlink "$DOTFILES/claude/themes" "$HOME/.claude/themes" -create_symlink "$DOTFILES/lazygit/config.yml" "$HOME/.config/lazygit/config.yml" if [[ "$PLATFORM" == "Darwin" ]]; then - create_symlink "$DOTFILES/pnpm/rc" "$HOME/Library/Preferences/pnpm/rc" run_or_plan "chmod +x sketchybar scripts" chmod +x "$DOTFILES/sketchybar/sketchybarrc" "$DOTFILES/sketchybar/plugins"/*.sh - create_symlink "$DOTFILES/sketchybar" "$HOME/.config/sketchybar" - create_symlink "$DOTFILES/karabiner/karabiner.json" "$HOME/.config/karabiner/karabiner.json" KARABINER_CLI="$(karabiner_cli_path || true)" if [[ -n "$KARABINER_CLI" ]]; then @@ -629,16 +590,6 @@ else echo " - sketchybar no disponible; se omite" fi -if [[ "$PLATFORM" == "Darwin" ]]; then - if [[ "$DRY_RUN" == true ]]; then - echo " → Would install cmux hooks for detected agents" - elif command -v cmux >/dev/null 2>&1; then - cmux hooks setup || echo " ! cmux hooks setup no pudo completar todas las integraciones" - else - echo " ! Abrí cmux y asegurá su CLI en PATH; después corré: cmux hooks setup" - fi -fi - # --- Configuración local --- echo "" if [[ ! -f "$DOTFILES/local/env.zsh" ]]; then diff --git a/local/env.zsh.example b/local/env.zsh.example index 4766b42..ccaf4d8 100644 --- a/local/env.zsh.example +++ b/local/env.zsh.example @@ -8,8 +8,10 @@ # export BARBATDEV_DIR="${WORKSPACE_DIR:-$HOME/dev}/barbatdev" # Configuración propia de cortex-dotfiles. +# CORTEX_HOME es la raíz de la instalación de Cortex; ajustala a tu setup real. +# export CORTEX_HOME="$HOME/.cortex" # export CORTEX_DOTFILES_DIR="$BARBATDEV_DIR/cortex/cortex-dotfiles" -# export CORTEX_SHELL_INTEGRATION="$CORTEX_HOME/shell/cortex.zsh" +# export CORTEX_SHELL_INTEGRATION="${CORTEX_HOME:-$HOME/.cortex}/shell/cortex.zsh" # Proyectos personales # export PERSONAL_PROJECTS_DIR="${WORKSPACE_DIR:-$HOME/dev}/local" diff --git a/nix/home.nix b/nix/home.nix index 2810e44..8478869 100644 --- a/nix/home.nix +++ b/nix/home.nix @@ -51,8 +51,6 @@ let "fish/functions/herdr-orient.fish".source = ../fish/functions/herdr-orient.fish; "fish/functions/whereami.fish".source = ../fish/functions/whereami.fish; "fish/functions/sshc.fish".source = ../fish/functions/sshc.fish; - "fish/functions/sshx.fish".source = ../fish/functions/sshx.fish; - "fish/functions/sshx-doctor.fish".source = ../fish/functions/sshx-doctor.fish; "fish/functions/_cortex_resolve_target.fish".source = ../fish/functions/_cortex_resolve_target.fish; "fish/functions/_cortex_run_agent.fish".source = ../fish/functions/_cortex_run_agent.fish; "fish/functions/cc.fish".source = ../fish/functions/cc.fish; diff --git a/npm/npmrc b/npm/npmrc index a672117..97b895e 100644 --- a/npm/npmrc +++ b/npm/npmrc @@ -1,2 +1 @@ -min-release-age=7 ignore-scripts=true diff --git a/odd/tasks/aerospace-migration.md b/odd/tasks/aerospace-migration.md new file mode 100644 index 0000000..b982f3b --- /dev/null +++ b/odd/tasks/aerospace-migration.md @@ -0,0 +1,33 @@ +# Migración yabai → AeroSpace (macOS 27) + +macOS 27 rompió yabai (scripting addition roto, sin release con fix). El usuario usaba principalmente el tiling. AeroSpace cubre tiling + focus + workspaces sin SIP y sin inyección. + +## Specs + +- S1 (user): "que tanta integración? si no hacemos mucho tampoco" — integración mínima; SketchyBar sigue igual. +- S2 (user): "Lo que mas usaba era el tiling" — prioridad tiling automático. +- S3 (user): "si metelo en un loop y no pares hasta que quede hecho" — migración completa sin pausas. +- S4: mismo leader `alt+cmd`, mismos atajos 1..9 y hjkl que skhd. + +## Tasks + +- [x] T1 (S4): `aerospace/aerospace.toml` — config porteada 1:1 (commit e6156ac). +- [x] T2: install.sh symlink + cask nikitabobko/tap. +- [x] T3: baja yabai/skhd (configs archivados en `archive/yabai-migration/`, brew uninstall + untap). +- [x] T4: fix `split` → `layout tiles accordion` (incompatible con normalización). +- [ ] T5: borrado con sudo de `/Library/ScriptingAdditions/yabai.osax` y regla NOPASSWD de yabai en sudoers — requiere password del usuario. + +## Log + +- L1 (user): "ayer te pedí sacar yabai... no era eso lo que me estaba jodiendo. Desde que entro macos 27 empezó a joder mal yabai y capaz ya sacaron alguna actualización?" +- L2: verificado — yabai 7.1.25 no soporta macOS 27; fixes en master sin release; mantenedor poco activo (#2684). Decisión: migrar a AeroSpace 0.21.3-Beta. +- L3: AeroSpace requiere Accesibilidad (gate del usuario); otorgado. Server arriba, 3 ventanas gestionadas, workspaces 1..9. +## Log + +- L5 (cierre revert): AeroSpace era inestable en el combo real (macOS 27 + 4 monitores: crashes + desync workspace↔space). Revert a yabai 7.1.25 parcheado (#2800, alias 27→26, binario compilado y reemplazado en Cellar) + skhd como LaunchAgents de usuario. Tiling y atajos verificados. Sin SA: space ops no-op — el usuario confirmó que no usa espacios de yabai. osax /Library/ScriptingAdditions/yabai.osax borrado con sudo (confirmado ausente). Pendiente menor: ninguno bloqueante. + +## Notas + +- Rotate/mirror/balance de yabai no existen en i3-tree: mapeados a join-with/resize. +- Mouse move/resize con modificador (alt+drag) no existe en AeroSpace. +- Config-version 1 con warning de migración a 2 — funciona, migración diferida. diff --git a/odd/tasks/installer-portability.md b/odd/tasks/installer-portability.md new file mode 100644 index 0000000..14689b2 --- /dev/null +++ b/odd/tasks/installer-portability.md @@ -0,0 +1,26 @@ +# installer-portability + +Portability and symlink hardening of `install.sh` per issue #25 (barbatdev/cortex-dotfiles). + +## Specs + +- S1: Symlink destinations are declared once in a single manifest consumed by backup, symlink creation, and `--check`; no destination missing from any of the three. +- S2: Backup of a symlink destination uses `cp -P`; repo content is never duplicated into `.bak_*`. +- S3: A real (non-symlink) directory at any destination produces a clean pre-flight abort (or explicit dry-run notice), never a mid-run `set -e` abort. +- S4: No duplicate backup calls; `backup_if_exists`/`backup_managed_symlink`/`backup_karabiner_if_exists` collapse into one unified backup path. +- S5: `--check` JSON/TOML globs no longer rely on `**` without `globstar`; each file validated exactly once. +- S6: `local/env.zsh.example` defines `CORTEX_HOME`; every referenced variable is defined or documented. +- S7: README documents `.bak_*` restore steps and backup retention behavior. +- S8: `./install.sh --dry-run` and `./install.sh --check` exit 0 on Linux-style runs (macOS-only branches skipped); re-running install twice creates zero new `.bak_*` files. + +## Tasks + +- T1 (S1-S5, S8): manifest + unified backup + preflight + manifest-driven --check + find globs in install.sh — commit: 91754ae +- T3 (S6): env.zsh.example CORTEX_HOME — commit: see T4 commit +- T4 (S6-S7): env.zsh.example CORTEX_HOME + README restore/retention docs — commit: (this commit) +- T5 (S8): sandbox verification — commit: pending + +## Log + +- L1 (user): "si ya" — approval to implement issue #25 (TARS fleet review: needs work → define concrete defects + acceptance criteria; done via issue body update). +- L2: Repo has no automated test runner (AGENTS.md); verification via `bash -n`, `shellcheck` if available, sandbox `$HOME` dry-run/check/real-run/idempotency, per manual-validation convention. diff --git a/odd/tasks/mise-removal-linux-agents.md b/odd/tasks/mise-removal-linux-agents.md new file mode 100644 index 0000000..3858506 --- /dev/null +++ b/odd/tasks/mise-removal-linux-agents.md @@ -0,0 +1,38 @@ +# Mise removal on Linux agents + +Migrate agent-dev and agent-gentle from mise-managed toolchains to native installs, then remove mise completely. agent-refactoria is unreachable (SSH timeout) and stays out of scope. + +## Specs + +- S1: All tools currently managed by mise must work natively after migration, at the same or compatible versions (user choice: same versions mise pins today; pacman-current acceptable on Arch for versioned system packages). +- S2: `claude`, `codex`, `opencode`, `pi` must keep working on agent-gentle through the whole migration (they run via mise shims today). +- S3: `gs sync` must pass on each migrated machine afterwards. +- S4: mise binary, `~/.local/share/mise`, `~/.config/mise` and shell references removed after verification. +- S5: agent-refactoria: report blocked, do not attempt. +- S6: Method: system package manager (apt on Ubuntu / pacman on Arch) + official installers/tarballs + npm -g for npm-distributed AI CLIs. + +## Tasks + +- T1 (S1,S6): agent-dev — native installs (go 1.27.1 tarball, node 24 LTS NodeSource, python3 system, starship, bun), rewrite ~/.bashrc PATH refs. +- T2 (S1,S3): agent-dev — verify go/node/pnpm/gs sync; then remove mise (S4). +- T3 (S1,S2,S6): agent-gentle — native installs (pacman go/gh/node, npm -g claude/codex/opencode/pi/pnpm, bun/uv official), fix fish configs. +- T4 (S2,S3): agent-gentle — verify all AI clients + gs sync; then remove mise (S4). +- T5 (S5): agent-refactoria — report blocked, pending SSH access. + +## Log + +- L3 (2026-10-08): agent-dev migrado y mise en cuarentena (T1,T2 ✓). agent-gentle migrado, gs sync OK; falta `sudo pacman -Rns mise-bin` (sin sudo sin contraseña allá). agent-refactoria migrado completo (T5 ✓), mise-bin desinstalado, gs sync solo falla por engram upstream. +- L4: Bug upstream confirmado en dos máquinas consumer: engram main sin go.mod en revision 8e525e7 rompe `go install .../cmd/engram@main`. Workshop (agent-gentle) no afectado (compila del clone). +- L5 (2026-10-08): engram sync failure root-caused — NOT upstream: engram go.mod is module v3, gs consumer branch installed v2 path. Fixed bin/gs v2→v3 in all four live deploys; repo fix committed (a3b689d) on fix/gs-engram-v3, PR #67. agent-dev pnpm was a broken symlink to mise; reinstalled real pnpm 11.21.0 and added to .profile PATH. Full gs sync verified OK on agent-dev. +- L1 (user): "Podemos sacar mise y dejar todo nativo como debe ser?" Machines: mac (local, no mise), agent-dev, agent-gentle, agent-refactoria. Choices: apt/tarballs+official, remove mise completely, keep same versions. +- L2: agent-gentle is Omarchy (Arch) → pacman, not apt. agent-refactoria unreachable (timeout) — volvió después. +- L6 (2026-10-13): adopción del canal oficial main en consumer hosts. bin/gs: a57402d (pi update → gentle-shell upgrade --channel main → pi update --extensions → engram go install casero → compat), 194e6fa (fallback pi gestionado), eb29103 (skip tolerante en launchers <4.1.0 por min-release-age). mac migrada (gentle-pi@4.2.0 npm-owned, canal main fijado: Shell c41ebd591/AI f0b6e477, sync no-op + compat OK). agent-dev/refactoria verificados en modo tolerante (4.0.0; 4.1.0 madura el 19/10). Políticas: min-release-age intacta por decisión del usuario; build scripts permitidos solo para paquetes org. Issue upstream gentle-shell#2183 (403 rate limit, propuesta git ls-remote) cargado vía skill issue-creation. Deuda: engram core sigue sin canal oficial (go install casero en gs sync); workshop sin cambios. +- L7 (2026-10-13, agent-dev): `gs` rompía al cargar la extensión gentle-pi (`Cannot find module @heyhuynhgiabuu/pi-pretty`). Causa: pi instala extensiones con pnpm y su linker aislado no resuelve deps para el loader de extensiones de pi; agravado por lockfile corrupto de intentos fallidos previos. Fix: `~/.pi/agent/npm/pnpm-workspace.yaml` con `nodeLinker: hoisted` + `onlyBuiltDependencies` (org packages, comillas por el @ inicial) y reinstalación limpia. El sync posterior verificó EXIT=0 (extensión 4.1.0, hoisted persistente, engram 3.4.1, compat OK). Nota: pnpm 11 no lee node-linker de .npmrc ni pnpm.* de package.json — va en pnpm-workspace.yaml. +- L8 (2026-10-13, cierre de flota): chequeo integral en las 4 máquinas tras las migraciones (runtime, wrappers sin mise, pi gestionado 1.2.0, extensiones resolviendo, arranque real de pi, gs sync + compat). Resiliencia añadida a gs sync (4d2a9b6): fallo transitorio del canal main → WARN y continuar. agent-refactoria migrada al canal oficial (Shell a3a268ec3c7d + AI f0b6e477, gentle-shell 4.2.0-main; wrapper subcommand-aware, npm -g gentle-pi, settings npm:gentle-pi, postinstall aprobado). agent-dev espera madurez de 4.1.0 (19/10). Veredicto final de flota: las 4 máquinas sanas. +- L9 (2026-10-14): el wrapper ~/.local/bin/gs de la MAC también tenía default GENTLE_SHELL_PI al cli.js npm viejo (todos los wrappers gs/gentle-shell nacieron el 2/10 con esa ruta). Corregido a ~/.pi/agent/bin/pi y verificado con arranque real de TUI. Barrido final: los defaults restantes en agent-dev/gentle apuntan al launcher gestionado ✓ y el de refactoria al cli.js npm ✓ (su esquema sigue siendo npm — correcto). Lección: cualquier wrapper creado pre-migración es sospechoso hasta verificar su default. +- L10 (2026-10-14, nan): nan es workspace de la plataforma nan.builders con diseño propio — launcher /opt/gentle-shell/bin/gentle-shell (script shell propio) que corre gentle-pi desde node_modules con node anclado, home aislado ~/.gentle-shell/agent, pi y ENGRAM_BIN anclados, y proveedor nan vía NAN_API_KEY inyectada por nan-vmd en /etc/hermes/env. Forzar gs sync casero recrearía el problema de dos fuentes de verdad → gs en nan delega al launcher de la plataforma (wrapper en /usr/local/bin/gs). hermes: crash preexistente por deps python ausentes (dotenv, httpx) → apt python3-dotenv/python3-httpx + launcher. pi actualizado 1.0.2→1.2.0 (standalone release con SHA verificado; no puede auto-actualizarse por estar en /opt root-owned). Go 1.27.1 instalado. Pendiente usuario: API key del pi del member home (fleet-check lo marca honestamente). +- L11 (2026-10-14, nan): el wrapper delegante hacía que `gs sync` abriera pi con "sync" como prompt (el launcher de la plataforma no tiene subcomandos gs). Fix: el wrapper de nan ahora guarda los subcomandos de gs (sync/pr/issue/new/review/base/ls/done) con un mensaje claro ("las actualizaciones las maneja la imagen base") y delega solo el launch. Verificado: gs sync → mensaje + exit 1; gs --version → mismo camino de ejecución que el launch (wrapper → launcher → node → mjs → pi 1.2.0). El TUI completo se valida en la terminal interactiva del usuario (necesita PTY). +- L11 (2026-10-14, nan dev): a pedido del usuario nan pasa a máquina de desarrollo. gs estándar restaurado (el wrapper delegante había pisado el deploy por tee a través del symlink /usr/local/bin/gs → deploy dir — gotcha: tee sigue symlinks), extensiones git:gentle-pi@main + git:engram@main en settings.json (preservando defaultProvider nan/defaultModel glm5.3), launcher /usr/local/bin/gentle-shell → node checkout main (4.2.0), pnpm 12.11.2 vía npm prefix ~/.local. Verificado: gs sync completo (gentle-ai 4.1.2 compilado con Go local, engram 3.4.1, compat OK) y fleet-check full TODO OK. La API key de pi no hizo falta configurarla: NAN_API_KEY del login + defaultProvider nan. El launcher aislado de la plataforma (~/.gentle-shell/agent) sigue coexistiendo. +- L12 (2026-10-14, nan cierre): causa raíz del "no funciona nada" en la sesión del usuario — el PATH del member shell no incluía ~/.local/bin (pnpm/gentle-ai/engram) ni /opt/node/bin (node). Fix: /etc/profile.d/gentle-fleet.sh. Verificado en login shell limpio: gs sync completo (compat OK) y gs -p responde "Ok" (único warning: codemode duplicado builtin vs checkout — esperado con extensión git:main, no bloquea). Flota final: 5/6 máquinas TODO OK; tars pendiente de acceso; agent-dev canal main el 19-20/10. +- L13 (2026-10-20, agent-gentle residuo): la sesión de gentle-shell en agent-gentle no conectaba Engram (buscaba el binario bajo `~/.local/share/mise/...`) ni corría el hook de codegraph. Diagnóstico: mise ya está removido (dir inexistente, fish/systemd limpios, env.d nativo); solo quedaban (a) `/etc/environment` con PATH que incluye `~/.local/share/mise/shims` muerto — requiere sudo con contraseña, bloqueado para el agente; (b) `codegraph` ausente → instalado `@colbymchenry/codegraph@1.6.2` npm -g, hook resuelto; (c) `cortex`/`herdr` en `~/.local/bin` son ELF funcionales que solo embeben strings legacy de mise (herdr menciona `/mise/shims/herdr` en help) — no requieren acción. Engram binario activo: symlink a `~/.local/share/gentle-ai/main/engram` v3.4.1. Pendiente usuario: `sudo` en agent-gentle para limpiar la línea PATH de `/etc/environment`. +- L14 (2026-10-20, agent-gentle cc): `cc` en fish caía a `/usr/bin/cc` (gcc) — los helpers de Claude (`cc`/`oc` de zsh/scripts/claude-helpers.zsh) nunca se portaron a fish en los Linux agents. Fix: `~/.config/fish/functions/cc.fish` y `oc.fish` (resolve dir + launch, sin cmux porque no existe allá). Verificado: error de dir inexistente exit=1, funciones autoloaden OK. Paridad pendiente si se quiere en agent-dev/refactoria (bash/zsh allá: port directo de claude-helpers.zsh). diff --git a/odd/tasks/refactoria-agent-dev-cli-parity.md b/odd/tasks/refactoria-agent-dev-cli-parity.md new file mode 100644 index 0000000..aeec2b2 --- /dev/null +++ b/odd/tasks/refactoria-agent-dev-cli-parity.md @@ -0,0 +1,45 @@ +# RefactorIA CLI parity on agent-dev + +## Goal and authority +Replicate the locally approved *visual presentation* on `agent-dev-01` (`ssh agent-dev`) for Herdr, Pi, Claude Code, OpenCode, Starship, Fish and Zsh. The user selected the full applicable CLI scope after a read-only four-tool inventory. Preserve remote-specific behavior and unrelated dirty work. Exclude SketchyBar (absent), Neovim (host-owned Kanagawa exception), Ghostty, the unapplied Herdr endpoint-menu binary patch, installer, and service/session restarts. Do not push, publish or commit; earlier no-commit constraint remains. Visual completion requires a later user-observed remote session; static checks cannot substitute for it. + +## Baseline and constraints +- Remote repo `/home/jbarbat/dev/barbatdev/cortex/cortex-dotfiles` is on dirty `main`; Herdr/Starship/Zsh sources are modified, Claude/OpenCode themes and Fish theme are untracked. Host symlinks point to this repo for Herdr default, Starship and Zsh. Do not overwrite unrelated work or change symlink targets. +- Remote Herdr profile and Pi theme exist as regular host files, with no repository source paths yet. Remote Herdr profile has extra roles missing locally: preserve remote-only keys. Herdr default and profile toast delivery deliberately differ (`terminal` locally in base, `herdr` in profile); retain intended per-file delivery. +- Pi/Claude/OpenCode selectors already select RefactorIA. Their remote theme contents predate the approved local role hierarchy. Remote Claude minimal statusline has the same five data segments as local; only its gray and high-context alert colors need alignment. Do not switch to the richer repository script or alter settings. +- Remote Fish RefactorIA theme is automatically sourced from its repository source by an existing `conf.d` file, unlike the Mac's opt-in theme. Keep that remote activation unchanged. A regular host theme copy is stale/inactive. Remote Fish greeting/help functions are absent; the user selected these welcome surfaces. The remote Fish command `ccclip` is unavailable: omit it from the newly added help rather than advertise it. Do not touch Nix-owned Fish links or universal variables. +- Remote Starship config, Zsh bootstrap and Zsh fragment are active symlink targets and dirty. Change presentation only; preserve custom module commands/detection, Zsh text/function order, remote PATH/workspace defaults, and shell startup. No macOS-only paths or commands may be copied. +- Before any remote source/host write, capture exact path types, hashes, missing-path markers and private backups under `~/.local/state/refactoria-backups/` on agent-dev. Recheck pre-write hashes, use atomic same-directory replacement where applicable and preserve file modes. Do not print settings secrets. Prepare bounded rollback by exact backed-up paths only. + +## Tasks +- [x] **T1 — Read-only remote mapping and scope.** Confirm SSH target, current Git/host ownership, selectors, activation, relevant semantic deltas and missing helpers; select full applicable CLI scope with the user. Evidence: target is `agent-dev-01`, repo `main`; four selectors present, shells use active symlinks and remote Fish auto-overlay. No writes. +- [x] **T2 — Snapshot and execution boundary.** Reconciled dirty `main` with a feature branch without losing remote work; recorded hashes, modes, symlinks and absent files, and verified private rollback snapshots. No source files changed. +- [x] **T3 — Four-tool presentation.** Remote Herdr default/profile roles, Pi/Claude/OpenCode themes, and only two Claude statusline colors aligned. Kept remote-only Herdr profile fields and toast behavior, preserved source/host ownership and selectors. Independent parser/semantic/synthetic checks passed; live visual review remains T6. +- [x] **T4 — Starship and Fish.** Remote Starship and Fish theme presentation now match approved local sources; Fish greeting/help were added as repo sources and regular host functions, omitting unavailable `ccclip`. Automatic theme source and existing shell startup were preserved. Independent static and isolated render checks passed; actual interactive visual review remains T6. +- [x] **T5 — Zsh Welcome.** Only five ANSI/color-comment lines in the remote active fragment changed. Independent verifier confirmed untouched bytes outside Welcome, preserved stripped text/function order/bootstrap/host symlink, `zsh -n` and scoped diff check. +- [x] **T6a — Repair confirmed Linux Claude bar encoding.** Scoped three-line glyph-generation fix backed up, independently verified across seven byte-level fixtures and visually approved by the user after reopening Claude; five segments, colors and threshold preserved. +- [x] **T6 — Independent readback and handoff.** Per-unit independent checks and parent final bounded readback passed; user visually approved new remote Fish, Zsh/Starship, Pi, Herdr default, OpenCode, Claude theme and corrected context bar. The additional aggregate independent verifier did not execute. Fish `help-profile` and the optional Herdr profile were initially not singled out in the stepwise reports; the user subsequently confirmed those worked too. No commit/push or agent-forced session reload. + +## Checkpoint: T2 +The initial `ssh` branch command failed at Fish parsing before any Git command ran; independent incident diagnosis and parent read-only branch probe confirmed remote `main` and no target branch. Used explicit `bash -s` on SSH stdin to create `refactoria/agent-dev-cli-parity`, preserving dirty contents and making no commit. Remote backup root: `/home/jbarbat/.local/state/refactoria-backups/agent-dev-cli-20260924T224828Z-2381977/`. Its private `manifest.json` records 24 exact paths: 14 regular private content copies, 4 symlink identities and 6 absence markers. Re-read independently verified each current path and backup SHA, mode, symlink target and branch. No source/host theme, prompt or function has changed yet. Rollback boundary is the manifest's exact paths only; keep the new branch until the user decides otherwise. + +## Checkpoint: T3 +Five remote source theme files were updated on the feature branch, with exact prewrite backup/hash gates. Herdr default retains non-theme keys and `herdr` toast; newly created repo profile preserves all nine extra host theme roles and `herdr` toast. New repo Pi theme and existing Claude/OpenCode JSONs match current local source SHA-256 exactly. Independent source verifier passed TOML/JSON and scoped diff checks. An apparent eight-path postwrite mismatch was investigated read-only: five intended repo source changes plus Herdr host file symlink and Claude/OpenCode parent **directory** symlinks to the same source paths; no concurrent host edits. Parent atomically mirrored the existing regular Herdr profile and Pi host theme after baseline checks; no redundant Claude/OpenCode mirroring. Parent changed only two ANSI constants in active host `~/.claude/statusline-command.sh`, preserving mode `0664` and its five segments. Independent host verifier passed selectors, resolved host aliases, theme parsing, exact two-line statusline diff, Bash syntax, synthetic 25/79/80/95% threshold and scoped diff checks. No UI was launched/reloaded. Separate byte-level baseline comparison showed the remote statusline's `tr` bar already emitted invalid UTF-8 on Linux both before and after this color-only update; output normalized for the two ANSI colors is otherwise byte-identical. Do not silently change bar logic in this rollout; disclose as an existing visual limitation for later decision. + +## Checkpoint: T4 +Delegated writer updated remote repo `starship/starship.toml` and `fish/themes/refactoria.fish` to approved local source bytes and created `fish/functions/{fish_greeting,help-profile}.fish`; the remote help intentionally omits the `ccclip` command/description pair because `fish -c` found it unavailable. Independent source verifier passed exact hashes, TOML nonpresentation invariants (commands, conditions, detection, thresholds, module order and right format), defined palette references, gold `#FFDE70` beard, all 21 Fish color roles, Fish syntax and unchanged `conf.d` activation SHA. Parent rechecked host baseline/absence and atomically mirrored the theme regular copy and installed two new regular 0644 Fish functions. Starship's host config remains a symlink to the updated source. Independent host verifier passed file ownership/equality/activation checks, all six isolated Fish greeting/help width renders, and normal/error Starship color render; write-suppressed Starship reported a cache-directory warning, but renders passed. No existing interactive shell was reloaded, no actual user visual review yet. + +## Checkpoint: T5 +Parent guarded the exact original SHA from the manifest, modified only five remote `zsh/cortex-dotfiles.zsh` Welcome-region lines, and preserved 0664 mode and the active host fragment symlink. Independent verifier passed exact five-line change, byte-identical content outside Welcome versus backup, unchanged ANSI-stripped visible text (apart from two color comments), function ordering, untouched `zsh/zshrc` bootstrap, `zsh -n` and scoped `git diff --check`. No current shell was reloaded; actual visual approval remains T6. + +## Checkpoint: T6 static readback and visual progression +Parent's bounded final remote readback reconciled all 24 manifest records: 21 changed paths are in the intended source/host or symlink-alias set, zero unexpected changes among those records. The feature branch still points at the exact same commit as remote `main`, and there are no rollout-prefixed temporary files left in touched directories. Scoped Git status lists only the ten intended repository source files (three modified tracked, seven untracked); backup root and manifest remain 0700/0600. An additional independent *aggregate* verifier did not run because its exact-command gate was not resolved; do not present this final aggregate check as independent. Prior independent T3, T4 and T5 phase verifiers did run and pass. The user opened a fresh remote Fish session with `ssh -t agent-dev fish` and reported that the displayed appearance looks good; this approves the observed Fish welcome/theme startup only. `help-profile` output was optional and not explicitly confirmed. The user then opened a fresh `ssh -t agent-dev zsh -i` session and reported that the Zsh Welcome and Starship prompt look good. The user next launched Pi remotely and reported that the theme looks perfect; then launched Herdr and reported its visible panel/focus as perfect. This does not prove optional Herdr profile activation or binary patch installation. The user then launched OpenCode and reported its theme looks perfect. The user then launched Claude Code and said its appearance looks really good, approving the displayed full theme. The user then inspected the bottom statusline and reported replacement characters (`��������`) in its context bar. The byte-level Linux `tr` invalid-UTF-8 issue identified in both prechange backup and current script is therefore confirmed live; the statusline is **not visually approved**. The user explicitly authorized a bounded fix only to the bar glyph generation, preserving segments/colors/thresholds. At that checkpoint T6a became active; the corrected visual check is recorded below. No existing sessions were reloaded. + +## Checkpoint: T6a code, tests and live approval +The first exact-pattern guard found that the fallback bar uses `$bar_width`, not `$empty`, and aborted before backup or script writes. A read-only three-line inspection corrected the guard. With explicit user authorization, parent verified seven prewrite synthetic inputs against the current script (invalid UTF-8) and in-memory candidate (valid UTF-8, identical bytes outside the bar, correct eight glyphs and 80% alert), then saved a fresh 0600 snapshot at `/home/jbarbat/.local/state/refactoria-backups/agent-dev-cli-20260924T224828Z-2381977/statusline-before-utf8-fix-20260924T235909Z-2517239.sh` plus adjacent `statusline-utf8-fix-20260924T235909Z-2517239.json` metadata. Replaced exactly three GNU `tr` glyph lines with six Bash parameter-expansion lines in `~/.claude/statusline-command.sh`; preserved mode 0664. New SHA-256 is `8b3524b8f1c9279f19986dbef7be0e3230d9044868d6f21b44b5ad85c40e454c`. Five postwrite fixtures passed. Independent verifier passed exact three-to-six-line change, backup/metadata hashes and modes, unchanged `statusLine.command`, `bash -n`, and seven missing/0/25/79/80/95/100 fixtures: old invalid/new valid UTF-8, bar width/count, identical output outside bar, five segments, threshold, zero stderr. Initial verifier invocation failed because the metadata filename stem was ambiguous; the corrected exact path was provided and rerun passed. The user reopened Claude normally and confirmed the bar now displays correctly, closing the live visual blocker. No app was restarted by the agent. + +## Work-unit boundaries +Use one serialized writer per non-trivial multi-file unit and independent bounded verification. No parallel remote writes. A correction remains confined to the unit that introduced it. Keep checkpoint evidence in this document and the Engram mirror after each transition. Source-to-host identity is required only where semantics and platform ownership allow it; preserve intentional remote-specific roles and activation. + +## Closeout +All requested remote visual surfaces that the user opened are approved: Fish welcome/theme, Zsh Welcome/Starship, Pi, Herdr default, OpenCode and Claude Code theme plus corrected context bar. Fish `help-profile` passed isolated width renders, and the user subsequently confirmed it and the optional Herdr profile worked too. The Herdr binary endpoint-menu patch remains deliberately unapplied. The aggregate independent final verifier did not execute due to its command gate; per-unit independent verifiers passed, and parent bounded final readback found zero unexpected paths among the 24 manifest records before the separately backed-up host statusline correction. No commit, push, installer or agent-forced session restart. The remote feature branch remains `refactoria/agent-dev-cli-parity` with uncommitted source files; delivery/versioning is a separate user decision. diff --git a/odd/tasks/refactoria-agent-refactoria-cli-parity.md b/odd/tasks/refactoria-agent-refactoria-cli-parity.md new file mode 100644 index 0000000..e395a16 --- /dev/null +++ b/odd/tasks/refactoria-agent-refactoria-cli-parity.md @@ -0,0 +1,25 @@ +# Reproduce RefactorIA CLI visuals on agent-refactoria + +## Goal and authority +Repeat the **manual, supervised, per-tool** Linux/Fish rollout approved on agent-gentle, using the committed portable visual inputs from this feature branch. Preserve host-owned nonvisual settings, other dirty work and running sessions. Work in this order: Herdr, Pi, Claude, OpenCode, Starship, Fish. For each: fresh exact-path inventory, source hash, isolated rehearsal, private backup, drift-guarded apply, static check, **human visual gate** before the next tool. No `install.sh`, Zsh, Ghostty, Neovim, SketchyBar, Herdr binary patch, package install, commit, push, merge or existing-session restart is authorized by this request. New host baselines are never copied from agent-gentle. + +## Read-only preflight +- `agent-refactoria` resolves to `192.168.200.124`, `/home/jbarbat`, Linux Omarchy, uid/gid 1000/1000, login Fish; no Zsh binary. Existing ED25519 pin under `HostKeyAlias=agent-refactoria` fingerprint `SHA256:Ys0EkEO/EzgRbG/goUyzL8//pfjpCzR5+v7fYvptfCE`; strict `BatchMode=yes`, `StrictHostKeyChecking=yes`, `UpdateHostKeys=no` probe passed after the user fixed SSH. Always pass those exact options; no key enrollment by the assistant. +- Herdr 0.9.1 config is regular0644 SHA `d618349e3a17b84a530e5c4b41429aae2e98d6fd06601cd59f0386965bc95ca4`; profile absent. The committed profile SHA `db5fb9e9c2cfa2b2c71ec389eaf7dff35596cfeee655740e237013c0d7816e33` and `scripts/refactoria_herdr.py:plan_visual_merge` generate candidate SHA `cc60b9668a7f162516a94bbee3b23c3e3aa8bcfaebc9e90b6eea5e3e2403b945`, idempotent with parsed nonvisual subtrees equal. `.config/herdr` exists regular owned0755; `profiles/` absent. +- Pi settings regular0644 SHA `69cf2f79870c5d4dbceb8de6b09b9bb5e67a2ff6dbca1e055722258fd857d932`, with only `theme=omarchy-system`; theme file absent. `pi --version` timed out at four seconds during read-only tool inventory; do not infer version or retry in a running session. Whether to make RefactorIA the saved Pi default on this different host must be resolved at its own gate. +- Claude settings, theme and statusline absent. OpenCode `opencode.json` regular0644 SHA `fb067af039252d48ef5b5c573a5e12c17357af4324b218aca5efa36f882846dd` with keys `$schema`, `autoupdate`, `theme=system`; `tui.json` and theme absent. Starship config regular0644 SHA `b17c9b5f096fc125e97050e359171c6011d6b3c7d7e9ac28f630e75b4d4bb9db` (different from gentle). Fish `config.fish` regular0644 SHA `03024507fed9ca35fc93006ca345b692b57ef8909edf4319842fa7a148da6cca`, old `conf.d/zz-refactoria-theme.fish` regular0644 SHA `8ebfb078e66c0c0109dbc1708a4060a7f4a93f13fa2494d41164218c89fdedfb`; theme/greeting/help absent. Private `~/.local/state/refactoria-{staging,backups}/` roots do not exist yet. Only exact paths may be created with owned 0700 staging/backup and 0600 saved files. +- Source precedent: `docs/refactoria-agent-gentle-rollout.md` lists nine committed Linux replay inputs and describes app-specific merges; its **gentle target baselines and backup IDs do not apply here**. The Git index was empty during preflight. Previous delegated SSH inspections proved unreliable, so direct parent strict-SSH readback is required after any delegated check. + +## Tasks +- [x] **T1 — Inventory and bind SSH/source.** Strict SSH pin and target-specific read-only inventory completed. No target config changes. +- [x] **T2 — Herdr.** Staged portable profile, merge helper, bounded one-host transaction helper and generated candidate in private `/home/jbarbat/.local/state/refactoria-staging/herdr.s19mf4kk/` (0700). Full fixture `fixture1.zoUTLhhm` and partial fixture `fixture2.PDIz5m5h` rehearsals passed backup/apply/rollback with private homes under this stage; isolated `herdr config check` returned `config: ok`. Real backup `/home/jbarbat/.local/state/refactoria-backups/herdr-k9rw5l1y/` (0700, original config and absence marker0600) passed prewrite readback. Applied only `~/.config/herdr/config.toml` regular0644 SHA `cc60b9668a7f162516a94bbee3b23c3e3aa8bcfaebc9e90b6eea5e3e2403b945` and new `~/.config/herdr/profiles/refactoria.toml` regular0644 SHA `db5fb9e9c2cfa2b2c71ec389eaf7dff35596cfeee655740e237013c0d7816e33`. Direct strict-SSH hashes/modes/uid, nonvisual TOML preservation, live `herdr config check` and rollback **preview only** passed. The user opened a fresh Herdr session and selected “Sí, se ve bien”; visual gate closed. Pi may be planned next. Binary patch left unapplied. +- [x] **T3 — Pi.** User explicitly chose RefactorIA as saved default on this host. Fresh bounded Pi 0.87.1 probe passed after earlier four-second timeout; settings baseline regular0644 SHA `69cf2f79870c5d4dbceb8de6b09b9bb5e67a2ff6dbca1e055722258fd857d932` had sole `theme=omarchy-system`, theme absent. Stage `/home/jbarbat/.local/state/refactoria-staging/pi.2yb1givu/` private0700 contains candidate settings SHA `d68449f4a04eafdfaa7de9f8d5b24006a50b6983a4062137dd427acd4d830565`, theme SHA `add53fd1744a052af7630508257b0cd6cfc7e53739088370207408f5918347ee`, and bounded one-host helper SHA `0a11845cfe85a1ac3985f34a2db3df7d8b7dbc40c6b8a3c621c34b0b9fdcdf7e`. Independent static review's directory-fsync blocker was repaired before full/partial private fixture rehearsal, both passed. Real backup `/home/jbarbat/.local/state/refactoria-backups/pi-o297mqo2/` mode0700 (original, absent marker and apply intent0600) passed exact prewrite readback. Applied only settings regular0644 SHA `d68449f4...0565` and new theme regular0644 SHA `add53fd17...47ee`; strict-SSH postwrite hashes/uid/modes, JSON semantic preservation and rollback **preview only** passed. The user opened a fresh Pi session without `--use-theme` and selected “Sí, se ve bien”; saved-default visual gate closed. Claude may be planned next. +- [ ] **T4a — Repair Claude installation (separately authorized).** The user explicitly chose repair rather than skip/pause. Diagnose `mise` install semantics and exact current state without re-running `~/.local/bin/claude`; scope any repair to version `2.1.284` and back up any existing bytes/manifest before mutation. Do not silently change `~/.config/mise/config.toml` or remove the empty version directory. Official mise docs confirm `mise install` does not add a config selector, unlike `mise use -g`; however `mise install --dry-run claude@2.1.284` queried GitHub and received unauthenticated API 403 rate limit (0/60), reset at 2026-09-28 20:47:03 -03 (epoch 1790639223), roughly 18 minutes after readback. Dry-run exited0 'would install': the 403 warning **does not prove** a pinned install would fail. No repair install ran. The user initially chose to pause, then challenged the necessity of waiting; correct the overstatement and seek a fresh resume decision before proceeding. Then verify a direct executable and bounded runtime command before resuming visual-only Claude. +- [ ] **T4 — Claude (PAUSED — wrapper incident).** Settings, settings.local, theme dir/theme and statusline are absent; ~/.claude exists owned0755. Bounded `claude --version` probes timed out at 4s and 8s. Read-only diagnosis then revealed `/home/jbarbat/.local/bin/claude` is a 123-byte Bash wrapper running `mise use -g --quiet "claude"` before `mise x`, so those probes might have changed global mise state or installed Claude outside the visual-only scope. Post-probe `~/.local/share/mise/installs/claude/2.1.284/` is an **empty** owned0755 directory with mtime 2026-09-28 19:58:13-0300, consistent with interrupted installation but there is no pre-probe snapshot to prove causality; `~/.config/mise/config.toml` mtime was earlier (19:08:21-0300), SHA `94ebb63a631d81f55a015d3e649ee7a267dafeaab6a2efb2cc022297c1d4e0d6`, and has no `tools.claude` selector. No Claude visual target files changed, no related process remains. **Stop: do not run the wrapper, install/clean anything or advance to OpenCode until user decides how to handle the possible package side effect.** If continuation is authorized, treat absent settings as a distinct baseline; rehearse minimal settings/theme/statusline creation and full/partial rollback under private stage before live writes and fresh visual check. +- [ ] **T5 — OpenCode.** Preserve `$schema`/`autoupdate` values, merge only theme in main config, decide/create missing `tui.json` with backup of absence, copy theme; rehearse and visually confirm. +- [ ] **T6 — Starship.** This host's baseline differs from gentle. Compare nonvisual features and confirm acceptable visual-only candidate before any replacement; rehearse backup/rollback, then apply and request fresh-shell check. +- [ ] **T7 — Fish.** Preserve host-owned `config.fish`; stage theme/greeting/help and wrapper, isolated full/partial rollback rehearsal; guard old activation's exact 64-character SHA, apply, check Fish syntax/runtime and request fresh-shell visual check. +- [ ] **T8 — Document outcomes and delivery.** Record exact backups, hashes, failures/skips, approvals and host-specific recovery caveats. Do not commit/push without a separate explicit decision; leave unrelated work untouched. + +## Boundaries and recovery +Stop after each tool until the user confirms its rendered result. A stopped/failed tool remains open and no later tool starts. For any rollback, recheck current bytes/type/owner against this host's recorded candidate, restore only backed-up exact existing files, remove only exact newly created file bytes, and refuse drift. Retain private backups/staging until the user separately authorizes cleanup. Do not re-use agent-gentle scripts or backup identities as if they bound this host. diff --git a/odd/tasks/refactoria-cross-tool-surface-parity.md b/odd/tasks/refactoria-cross-tool-surface-parity.md new file mode 100644 index 0000000..fab628f --- /dev/null +++ b/odd/tasks/refactoria-cross-tool-surface-parity.md @@ -0,0 +1,40 @@ +# RefactorIA cross-tool surface parity (local) + +## Objective and rationale +Extend the visually approved Pi/Herdr restrained TUI palette to local Claude and OpenCode, and repair stale optional Ghostty/Herdr profile activation without washing out approved brand accents. RefactorIA should be recognizable by official dark surfaces, light text, restrained violet, and semantic color, not large blocks of purple. + +## Scope and constraints +- Local Mac only. No agent-dev rollout, full installer, service interruption, font update, or delivery/commit authorized by this task. +- Official surface tokens: background `#0B0714`, panel `#17102A`, raised `#2C2144`, text `#FFFFFF`, brand fill `#7127FF`. Adapted readable text accent `#A477FF`. +- Preserve approved Herdr gold `#FFC857` focus, Pi palette and guarded prompt, existing Ghostty ANSI/selection and opacity. For SketchyBar, user authorized revising uniform lavender icons and the previously white beard; preserve warning/error semantics. +- Preserve all pre-existing dirty repository and host changes. Back up each live copy before activation; do not replace settings files or host-only plugin content. +- Effective strict TDD: not configured (repository documents manual validation). Runner: ordinary JSON/TOML parsers, Ghostty validator, Herdr config check, bash syntax and focused assertions. +- Route: delegated direct writer for coordinated multi-file source changes (mapping and writer triggers), parent for narrow host activation and reconciliation. Initial ~40 authored changed lines plus a bounded SketchyBar pilot estimated under 120 authored lines; generated files excluded; delivery strategy ask-on-risk. No commit planned. + +## Tasks +- [x] **T1 — Normalize agent surfaces.** In `claude/themes/refactoria.json`, reduce large user-message fill to `#2C2144`, keep readable accent `#A477FF`, align hover/selection to brand fill and primary/inverse text to official light/dark. In `opencode/themes/refactoria.json`, align only background/text to official `#0B0714`/`#FFFFFF`. Validate exact scoped JSON deltas, selectors, legibility, and backups. Rollback boundary: these two theme files and their host mirrors only. +- [x] **T2 — Bring optional overlays into parity.** In `herdr/profiles/refactoria.toml`, align official sidebar/active/selection and approved gold focus with default while preserving profile-specific behavior. For Ghostty, leave working base and opacity unchanged; reconcile stale live RefactorIA profile to repository content with backup and validate both base/profile. Do not alter host-only settings. Rollback boundary: these two optional profile files/links only. +- [x] **T3 — Verify and report.** Independently verify exact colors, contrast and host mirror paths; validate Ghostty, Herdr, JSON and SketchyBar scripts without changes; perform one parent spot check. Report visual/runtime limitations and obtain user feedback before any remote rollout. Rollback boundary: local theme mirrors and optional profile activations only. +- [x] **T4 — SketchyBar visual hierarchy pilot.** Preserve raised selected space with readable outline and neutral/info right-side roles; use `#FFDE70` gold beard on transparent bar background at Regular 24 on all four brand items. Backups, shell syntax, scoped diff, live queries, independent verification and user visual approval completed. Rollback boundary: `sketchybar/sketchybarrc`, changed status plugins, and the running bar config only. + +## Acceptance criteria +- Local Claude/OpenCode active RefactorIA themes use official neutral surfaces with text legible; only authorized roles changed. +- Herdr default and optional RefactorIA profile agree on color roles; profile-specific toast behavior preserved. +- Ghostty default and optional RefactorIA profile share official palette without changing bindings/opacity. +- SketchyBar becomes legibly RefactorIA at a glance: golden isotipo without a surrounding tile, selected workspace distinct without saturated fill, right-side normal icons not uniformly lavender, white labels, and warning/error colors retained. +- Backups and source-to-active parity are verified, no current sessions force-closed. + +## Progress and evidence +- Mapping completed: Ghostty base, Herdr default, SketchyBar already use approved palette. Claude user fill `#6647B2` is the main remaining purple block; OpenCode background `#030304`/text `#F8F8F8` are slightly off; optional live Ghostty/Herdr profiles are stale. +- Delegated writer changed only Claude/OpenCode theme source and the Herdr RefactorIA profile; exact scoped JSON/TOML delta assertions, isolated Herdr composition/config check, Ghostty base/profile validators, SketchyBar syntax and whitespace checks passed. Writer: gpt-5.6-luna/max. No source change was justified for Ghostty or SketchyBar. +- Native assessment was unavailable because unrelated untracked files require declaration; independent verification remains required. +- Parent confirmed four live copies were regular files and their differences were limited to allowed palette roles/profile theme; backed up all at `~/.local/state/refactoria-backups/cross-tool-surfaces-20260923T233523Z/` (0700/0600) and activated matching source copies with current modes 0644. No settings, default Ghostty/Herdr, SketchyBar, remote host, or sessions were touched. +- Independent verification passed for T1–T3: four source/host byte mirrors, exact Claude/OpenCode/Herdr/Ghostty allowed roles, both Herdr config checks, both Ghostty validators, eight SketchyBar shell syntax checks, scoped whitespace checks, and contrast >=4.5:1 on specified text pairs. Parent spot-check confirmed four live theme values. Original host permissions and historical SketchyBar immutability cannot be independently proven from missing baseline. +- T4 pre-edit backup at `~/.local/state/refactoria-backups/sketchybar-hierarchy-20260924T125139Z/` contains seven scoped files (0700/0600). Writer implemented white U+F0F00 at 20px on violet brand tile, raised selected space with readable border, neutral vs info icons and preserved semantic branches. Bash syntax/mock checks and independent live verification passed; user approved all except the white-on-bright-violet beard tile. +- A second single-file brand-only variant was backed up at `~/.local/state/refactoria-backups/sketchybar-gold-beard-20260924T130812Z/sketchybarrc` and changed only `BRAND` to gold `#FFC857` and `BRAND_TILE` to dark violet `#2C2144`; syntax/diff/live checks passed. User found the dark-violet tile still muted the gold. +- A third single-file variant was backed up at `~/.local/state/refactoria-backups/sketchybar-transparent-beard-20260924T131423Z/sketchybarrc`; only `BRAND_TILE` changed to transparent `0x00000000`. Exact delta, bash syntax, diff check, and `sketchybar --reload` succeeded. An immediate query raced the config's remove/recreate window; read-only incident diagnosis confirmed the active symlink/process and both brand and space items. Follow-up queries of all four brand variants passed: gold `0xffffc857`, transparent `0x0`, drawing on. +- The brighter-gold variant was backed up at `~/.local/state/refactoria-backups/sketchybar-brighter-beard-20260924T132511Z/sketchybarrc`; only `BRAND` changed from `#FFC857` to `#FFDE70`. Exact one-line delta, bash syntax, scoped diff check, reload and bounded live queries of all four brands passed: `0xffffde70` foreground, `0x0` tile. User screenshot still showed muted brown-looking glyph despite live requested gold. Screenshot crop histogram was near half-intensity on beard strokes; installed font has monochrome outlines, no embedded color tables. +- Backed up the next variant at `~/.local/state/refactoria-backups/sketchybar-beard-size-20260924T134706Z/sketchybarrc`; changed only four brand font sizes Regular 20→24, preserving gold and transparent tile. Parent reloaded; independent read-only verifier confirmed exact four-size delta, shell syntax, diff check and live queries of all four variants. Main brand reports on-screen bounds; three external brand variants have off-screen placeholder bounds. User explicitly approved the final size/color and asked to leave it as is. No Orca per explicit user preference. + +## Next step +Keep this local approved state. No commit, remote rollout or agent-dev propagation was requested; decide those separately if needed. diff --git a/odd/tasks/refactoria-remaining-cli-surfaces.md b/odd/tasks/refactoria-remaining-cli-surfaces.md new file mode 100644 index 0000000..8e86db7 --- /dev/null +++ b/odd/tasks/refactoria-remaining-cli-surfaces.md @@ -0,0 +1,44 @@ +# RefactorIA remaining CLI surfaces (local) + +## Goal and boundaries +Align the remaining visible CLI surfaces to the user-approved restrained RefactorIA hierarchy without homogenizing every application. Work locally on this Mac; do not touch `agent-dev`, SketchyBar (already visually approved), tmux (replaced in practice by Herdr), or unrelated dirty files. No full installer or forced session closure. Neovim's active configuration is host-owned and outside this repository: audit first and request a separate scope decision before any host write. + +Use official surfaces `#0B0714`, `#17102A`, `#2C2144`, light text and limited brand `#7127FF`; adapted legible violet `#A477FF` and semantic success/info/warning/error roles. Preserve module behavior, status thresholds, keybindings, profile activation choices and existing user-visible information. Make backups before host-facing edits or activation. Validate source syntax/semantics, actual activation, contrast and a user-visible preview before claiming visual completion. + +No strict TDD runner is configured for this dotfiles repository. Use focused parsers, tool validation/render commands, scoped diff, and manual visual approval. Work units are independent and reviewable; no commit/push/remote rollout is authorized in this session. Document a rollback boundary per unit. + +## Tasks +- [x] **T1 — Starship prompt.** Update only `starship/starship.toml` palette and presentation styles. Preserve module order, repo/SDD commands, Git and language detection, prompt symbols and right-side modules. Use the user-selected balanced hierarchy: one official-violet repo tile with white text, raised dark directory, blue Git tile with dark text, and restrained remaining roles; try the approved SketchyBar beard gold `#FFDE70` on the default/success beard glyph while keeping the error glyph semantic; both white and violet trials were too subtle in the terminal. Keep all normal text/background pairs readable. Back up the linked source, validate TOML, render normal/error/right prompt plus representative modules, check exact scope and contrast, then ask for visual judgment. Rollback: only `starship/starship.toml` and its live symlinked effect. +- [x] **T2 — Fish theme.** Inspect opt-in activation; align `fish/themes/refactoria.fish` syntax/pager roles to the approved dark surfaces while maintaining legible selections, errors and suggestions. Validate Fish syntax, color roles and an isolated no-config preview; back up and reconcile the matching regular host theme copy without changing startup, universal variables or login shell. User sources the opt-in theme for visual approval. Rollback: repository theme and backed-up host theme copy; session-only colors expire with that session. +- [x] **T3 — Claude statusline.** Inspect actual host registration first. It currently runs a deliberately minimal host-owned `~/.claude/statusline-command.sh`, not the richer unused repository `claude/statusline.sh`. User selected aligning only the active minimal colors: in `~/.claude/statusline-command.sh`, change secondary gray to `#EBEBEB` and high-context alert to `#FF6B8A`, preserving its five data segments, order, conditions, rate-limit field and output contract. Back up the exact host file; do not edit settings or the richer unused repository script. Verify synthetic normal/high-context/fallback inputs and ask for visual judgment. Rollback: restore that one host file from backup. +- [x] **T4 — Zsh welcome.** Resolve worktree ownership before writing: active `~/.zshrc` is a bootstrap in the linked `dotfiles-live` worktree and sources `zsh/cortex-dotfiles.zsh`, where the visible welcome/help block lives; current feature worktree has a separate legacy `zsh/zshrc`. User selected color-only alignment in both `zsh/zshrc` on this feature branch and `zsh/cortex-dotfiles.zsh` in the linked `dotfiles-live` worktree. Preserve the live bootstrap, load order and branch-specific help text. Map load success to #58E6A8, clock/command names to #8CC8FF, help title/action to legible violet #A477FF and supporting hint to secondary #EBEBEB. Back up each exact file; validate `zsh -n`, bounded output with unchanged text and visible colors without replacing a running shell. Rollback: those two files independently. +- [x] **T6 — Fish welcome and help.** User explicitly selected an automatic Fish greeting plus `help-profile`, despite the host's current empty `fish_greeting`. Implement Fish-native autoload functions in `fish/functions/{fish_greeting,help-profile}.fish`, adapt the approved Zsh visual hierarchy without claiming an unmeasured load time, and list only real Fish helpers (no Tmux). Keep RefactorIA syntax theme opt-in and preserve unrelated host config; verify custom greeting runs after host `clear` before any host activation. Back up host-facing state and activate only the two new function files as regular copies under `~/.config/fish/functions`, avoiding the full installer and Nix-managed links. Validate Fish syntax, isolated rendering, actual new-shell activation, command availability and rollback of only those two host files. User judges the final visual result; no commit. +- [x] **T5 — Neovim scope and documentation.** Audit the host-owned `~/.config/nvim` palette read-only; do not overwrite it or link a new configuration without a separate user decision. Reconcile only repository documentation that describes completed visual work (including stale Gruvbox/InnIT names and the approved local SketchyBar exception) after evidence is available. Rollback: documentation-only paths if authorized later. + +## Initial evidence +- Repo mapping: `starship/starship.toml` uses `innit_tech_slate`, with white text on yellow/aqua/green backgrounds below ordinary 4.5:1 text contrast; `fish/themes/refactoria.fish` is opt-in with older dark/violet values; `claude/statusline.sh` and `zsh/zshrc` contain independent ANSI colors; `nvim/README.md` describes a host-owned InnIT overlay. +- Live `~/.config/starship.toml` is a symlink to this repo's `starship/starship.toml`; Starship 1.26.0 can render via `STARSHIP_CONFIG` without sourcing either shell. Baseline render shows colored repo/path/Git blocks and the beard glyph. Preserve this symlink and current sessions. +- Repository was already dirty across unrelated files before this feature. Preserve unrelated changes. +- T1 source backup: `~/.local/state/refactoria-backups/starship-palette-20260924T143141Z/starship.toml` (private 0700/0600). Delegated writer changed only `starship/starship.toml`: semantic RefactorIA palette and dark segment styles, preserving module behavior. TOML, normal/error/right renders and scoped diff check passed. Independent verifier confirmed all ten palette references, preserved conditions/commands/detection/format structure and eight explicit text-on-surface pairs with minimum 5.823:1 contrast. Brand separators are decorative foreground on inherited dark background: 3.258:1, above 3:1 non-text target but below 4.5:1 text target. SDD/Node/Python fixture and battery runtime style were not exercised; no shell reload or remote operation occurred. +- User rejected the first pilot's composition: dark panel/surface fills were nearly indistinguishable from the base. They selected a balanced second pilot: visible brand-violet repo tile, blue Git tile with dark text, raised dark directory, restrained remaining segments. Do not rebrand other tools or loosen contrast rules. +- First pilot backup: `~/.local/state/refactoria-backups/starship-balanced-20260924T152059Z/starship.toml`. Writer corrected only five fields: repo foreground/background and Git branch/status style/format. Independent verifier confirmed exact scope, TOML parse, Starship 1.26 normal/error/right render, scoped diff check and WCAG contrast: white/brand 6.11:1, dark/info 11.21:1, white/raised 14.91:1; decorative brand separators on base 3.26:1. No shell reload or remote change. +- User noticed the default beard was green because the first pilot assigned `color_success` to `success_symbol`; they chose white as the normal glyph, preserving semantic error color. Backed up the balanced pilot at `~/.local/state/refactoria-backups/starship-white-beard-20260924T154553Z/starship.toml`, then changed only that one line. Independent verifier confirmed exact delta, TOML assertions, status-0 white ANSI and status-1 pink ANSI, and scoped diff check. +- User then found the white ASCII beard too subtle and requested a violet trial. Backed up the white variant at `~/.local/state/refactoria-backups/starship-violet-beard-20260924T155329Z/starship.toml` and changed only the normal glyph to the legible `#A477FF` text accent, not the lower-contrast `#7127FF` fill. Independent verifier confirmed exact one-line delta, status-0 ANSI `#A477FF`, status-1 error ANSI `#FF6B8A`, TOML assertions and scoped diff check. User still found the violet glyph nearly invisible. +- User proposed gold. Backed up violet variant at `~/.local/state/refactoria-backups/starship-gold-beard-20260924T155807Z/starship.toml`; added `color_beard = '#FFDE70'` and applied it only to normal/success glyph. Independent verifier confirmed exact two-change delta, TOML, status-0 gold ANSI, status-1 pink ANSI and scoped diff check. User explicitly approved the live appearance. SDD/Node/Python fixture and battery runtime style remain unexercised; no commit was authorized. + +- T2 mapping: `fish/themes/refactoria.fish` defines only session-global syntax/pager colors; its installed `~/.config/fish/themes/refactoria.fish` was a matching regular 0644 copy, not a symlink. Host `config.fish` and generated `fish_frozen_theme.fish` set a separate default palette and do not source RefactorIA. Preserve startup/universal variables and opt-in behavior. +- T2 backup `~/.local/state/refactoria-backups/fish-theme-20260924T162445Z/{source,host}/refactoria.fish` captures both identical pre-edit copies. Delegated writer changed only 13 local palette values in repo source; all 21 global syntax/pager role assignments were preserved. Independent verifier passed Fish syntax, isolated no-config source, scoped diff and contrast (normal 19.91:1; selected 6.11:1; search 14.91:1; suggestion 9.41:1). Parent atomically mirrored verified source to the regular host copy after checking it still matched backup. Independent post-activation check passed byte mirror, 0644 host mode, syntax, selected/error values. No default activation or universal variables changed. User manually previewed and explicitly approved the visual result; no commit was requested. + +- T3 mapping: `~/.claude/settings.json` registers `bash ~/.claude/statusline-command.sh`; `~/.claude/statusline.sh` is absent. The active host-owned script intentionally emits a minimal five-part statusline (context, model/effort, cwd, Git dirty cue, 5h rate limit) with gray ANSI-256 and red only for high context. The repository `claude/statusline.sh` instead includes MCP/SDD/cmux/cache. Editing repo colors alone would not change the UI; switching registration would change behavior. User selected a visual-only update to the active minimal script, not migration. +- T3 private backup at `~/.local/state/refactoria-backups/claude-minimal-statusline-20260924T173418Z/statusline-command.sh` captures the original executable host file. Parent changed only two constants in `~/.claude/statusline-command.sh`: gray ANSI-250 to RGB `#EBEBEB`, bold high-context red to RGB `#FF6B8A`. Independent read-only verification passed bash syntax, exact two-line diff, active settings registration, unchanged executable mode, and five synthetic inputs (normal/high/empty/zero/80 boundary) with identical plain text and correct alert threshold. No settings, repo script, data logic or sessions changed. User explicitly approved the appearance in Claude; no commit was requested. + +- T4 incident diagnosis: active `~/.zshrc` points to linked `cortex-dotfiles-main/zsh/zshrc` on branch `dotfiles-live`; that bootstrap sources `~/.config/cortex-dotfiles/shell/cortex-dotfiles.zsh`, itself a symlink to `cortex-dotfiles-main/zsh/cortex-dotfiles.zsh`. The latter contains the active `_welcome` and `help-profile` colors. This feature worktree's `zsh/zshrc` has a comparable but branch-distinct block. Both tracked relevant paths are clean; no user work is being overwritten. Editing current `zsh/zshrc` alone would not change the live welcome. User explicitly selected both the current and live fragment worktrees for color-only updates; target was registered in the session. Both clean sources were backed up privately at `~/.local/state/refactoria-backups/zsh-welcome-20260924T180337Z/{feature/zshrc,live/cortex-dotfiles.zsh}`. Two sequential bounded writers replaced only five Welcome-region ANSI/color-comment lines in each source, using the same success/info/violet/secondary roles while leaving branch-specific help text and live bootstrap untouched. Writers report `zsh -n`, `git diff --check`, scoped backup comparison passing; feature writer isolated Welcome render also passed. Initial independent verifier runs could only inspect files: their command authorizations timed out, so they **did not** establish syntax or byte-equivalence independently. Exact-command independent verification of feature `zsh/zshrc` passed: `zsh -n`, diff check, exact five-line Welcome-only ANSI mapping, byte-identical outside the region and preserved stripped text. Exact-command independent verification of the live `dotfiles-live` fragment also passed: `zsh -n`, diff check, expected five ANSI/comment lines, byte-identical remainder, matching stripped content, and active symlink targets. An isolated runtime render of the live fragment was not run. User rendered the real active Zsh welcome/help from a Fish session via `zsh -i -c 'help-profile'` and explicitly approved the appearance. No commit or forced shell reload. + +## T6 evidence +T6 Fish mapping: the host's regular `~/.config/fish/config.fish` sets `fish_greeting` empty and ends in `clear`; no Fish `help-profile` exists. Most existing host Fish functions are Nix-managed symlinks, while earlier RefactorIA helpers are regular copies; do not overwrite them. User chose an automatic greeting plus Fish-native help. Bounded writer created the two new repo functions; initial independent verifier found two presentation failures: framed content rows are three columns shorter than borders (`fish_greeting.fish`), and a command signature overflows at 20 columns (`help-profile.fish`). Syntax and helper inventory passed, but `fish -i -c` did not prove automatic greeting. Both width issues were corrected and independently rechecked at 80/40/30/28/20/16 columns; syntax, palette, text and command inventory passed. The isolated pseudo-TTY startup harness did not show a greeting even with a nonempty variable, so it is inconclusive. User was told directly; after confirming both host function names were absent, parent atomically installed only new 0644 regular copies under `~/.config/fish/functions` from exact private snapshots at `~/.local/state/refactoria-backups/fish-welcome-20260924T195710Z/`. Host `config.fish`, Nix symlinks and opt-in Fish theme remain untouched. Independent host-copy verification passed syntax, byte equality and regular 0644 file mode. User ran a real new Fish session, confirmed the automatic greeting and explicitly approved the appearance. No config, theme, Nix symlink or unrelated changes; no commit. + +## T5 evidence +T5 runtime blocker was repaired by explicit user authorization: old `nvim` 0.12.4 linked to missing Tree-sitter 0.26 while opt pointed at 0.27. `HOMEBREW_NO_AUTO_UPDATE=1 brew reinstall neovim` installed Neovim 0.12.5_1 and also upgraded its LuaJIT dependency (disclosed to user); no Neovim configuration files or tap trust changed. Independent read-only verification passed `brew linkage --test neovim`, `nvim --version`, clean headless startup, and otool now points at libtree-sitter.0.27.dylib. Read-only host audit found `~/.config/nvim` is a regular user-owned directory and its `lua/plugins/colorscheme.lua` selects `gentleman-kanagawa-blur` (not RefactorIA); Lualine in `lua/plugins/ui.lua` uses the same theme. Installed default palette is transparent dark with `#F3F6F9` foreground, `#191E28/#232A40/#313342/#27345C` surfaces, and gold/green/blue/magenta accents rather than official RefactorIA violet/surfaces. Repo `nvim/README.md` describes a nonexistent RefactorIA overlay and stale InnIT colors. User supplied a screenshot of the Fish source in Neovim: dark background and readable restrained syntax, no obvious contrast failure in that buffer, but diagnostics/floats/statusline were not shown. User explicitly chose to keep Gentleman Kanagawa Blur and correct repo documentation instead of adding a RefactorIA overlay. Host config/plugins/theme remain unchanged; exact final highlight values/opacity outside the screenshot remain unverified. Documentation-only writer updated `nvim/README.md`, relevant root `README.md` visual claims and a local-exception note in the existing untracked `docs/refactoria-branding.md`, preserving official source hashes/tokens and unrelated dirty README hunks. Parent structural readback found the first pass still mislabeled Starship/SketchyBar as Gruvbox/InnIT and used the historical Neovim date; a bounded correction fixed those claims. Independent verifier initially flagged absolute runtime claims; final docs now scope Neovim to configured selection/audited files and separate approved local pilots from opt-in launchers. Root README also replaced its obsolete external-PNG font regeneration/host-copy recipe with the canonical Braille-source link and fixed a Python `~` path. Independent final documentation verification passed exact claims, relative link anchor and scoped `git diff --check`. No commit. + +## Closeout +All requested local surfaces are visually approved or, for Neovim, explicitly kept as an audited exception. Diagnostics, floating windows, statusline states and plugin-specific Neovim highlights were not fully exercised; do not infer coverage from one screenshot. Local changes remain uncommitted and no remote rollout was performed. diff --git a/scripts/__pycache__/refactoria_herdr.cpython-314.pyc b/scripts/__pycache__/refactoria_herdr.cpython-314.pyc new file mode 100644 index 0000000..f0fed85 Binary files /dev/null and b/scripts/__pycache__/refactoria_herdr.cpython-314.pyc differ diff --git a/scripts/__pycache__/refactoria_herdr_rollout.cpython-314.pyc b/scripts/__pycache__/refactoria_herdr_rollout.cpython-314.pyc new file mode 100644 index 0000000..5ddcd3e Binary files /dev/null and b/scripts/__pycache__/refactoria_herdr_rollout.cpython-314.pyc differ diff --git a/scripts/__pycache__/test_refactoria_herdr.cpython-314.pyc b/scripts/__pycache__/test_refactoria_herdr.cpython-314.pyc new file mode 100644 index 0000000..c546ac6 Binary files /dev/null and b/scripts/__pycache__/test_refactoria_herdr.cpython-314.pyc differ diff --git a/scripts/__pycache__/test_refactoria_herdr_rollout.cpython-314.pyc b/scripts/__pycache__/test_refactoria_herdr_rollout.cpython-314.pyc new file mode 100644 index 0000000..ee9a57e Binary files /dev/null and b/scripts/__pycache__/test_refactoria_herdr_rollout.cpython-314.pyc differ diff --git a/zsh/cortex-dotfiles.zsh b/zsh/cortex-dotfiles.zsh index c29910e..623aa18 100644 --- a/zsh/cortex-dotfiles.zsh +++ b/zsh/cortex-dotfiles.zsh @@ -20,7 +20,6 @@ _cortex_dotfiles_path_prepend() { } _cortex_dotfiles_path_prepend "$HOME/.local/bin" -[[ -d "/Applications/cmux.app/Contents/Resources/bin" ]] && _cortex_dotfiles_path_prepend "/Applications/cmux.app/Contents/Resources/bin" #endregion #region Zsh Options diff --git a/zsh/scripts/claude-helpers.zsh b/zsh/scripts/claude-helpers.zsh index 5c6d183..ed9865c 100644 --- a/zsh/scripts/claude-helpers.zsh +++ b/zsh/scripts/claude-helpers.zsh @@ -1,13 +1,5 @@ #region Claude Code Helpers -_cmux_sidebar_refresh() { - local target="${1:-$PWD}" - local workspace="${2:-}" - local script="${_DOTFILES_DIR:-$HOME/.cortex/cortex-dotfiles}/zsh/scripts/cmux-sidebar-refresh.sh" - - [[ -x "$script" ]] && "$script" "$target" "$workspace" >/dev/null 2>&1 || true -} - _cortex_resolve_target() { local target="${1:-.}" local resolved @@ -22,22 +14,8 @@ _cortex_resolve_target() { _cortex_run_agent() { local target="$1" shift - local -a agent_command=("$@") - local command_string="" - local arg created workspace - - if [[ "${CORTEX_MULTIPLEXER:-${CORTEX_DOTFILES_MULTIPLEXER:-cmux}}" == "cmux" && -n "${CMUX_WORKSPACE_ID:-}" && "$target" != "$PWD" ]]; then - for arg in "${agent_command[@]}"; do - command_string+="${(q)arg} " - done - created=$(cmux workspace create --cwd "$target" --command "$command_string" --json) || return 1 - workspace=$(jq -er '.workspace_ref // .workspace_id' <<<"$created") || return 1 - _cmux_sidebar_refresh "$target" "$workspace" - return - fi - _cmux_sidebar_refresh "$target" - (cd -q "$target" && command "${agent_command[@]}") + (cd -q "$target" && command "$@") } # Abre Claude Code en el path indicado. diff --git a/zsh/scripts/cmux-sidebar-refresh.sh b/zsh/scripts/cmux-sidebar-refresh.sh deleted file mode 100755 index 5700895..0000000 --- a/zsh/scripts/cmux-sidebar-refresh.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -set -u - -target="${1:-$PWD}" -workspace="${2:-}" - -command -v cmux >/dev/null 2>&1 || exit 0 -cmux ping >/dev/null 2>&1 || exit 0 - -set_status() { - local key="$1" - local value="$2" - - if [[ -n "$value" && -n "$workspace" ]]; then - cmux set-status "$key" "$value" --workspace "$workspace" >/dev/null 2>&1 || true - elif [[ -n "$value" ]]; then - cmux set-status "$key" "$value" >/dev/null 2>&1 || true - elif [[ -n "$workspace" ]]; then - cmux clear-status "$key" --workspace "$workspace" >/dev/null 2>&1 || true - else - cmux clear-status "$key" >/dev/null 2>&1 || true - fi -} - -git_root=$(git -C "$target" rev-parse --show-toplevel 2>/dev/null || true) -if [[ -n "$git_root" ]]; then - project=$(basename "$git_root") - branch=$(git -C "$git_root" branch --show-current 2>/dev/null || true) - [[ -n "$(git -C "$git_root" status --porcelain 2>/dev/null)" ]] && branch="${branch}*" -else - project=$(basename "$target") - branch="" -fi - -set_status project "$project" -set_status git_branch "$branch" - -brains="" -for brain in work-brain life-brain second-brain; do - if [[ -f "$HOME/.claude.json" ]] && jq -e --arg name "$brain" '.mcpServers[$name] // .projects[].mcpServers[$name]' "$HOME/.claude.json" >/dev/null 2>&1; then - short=${brain%-brain} - [[ "$brain" == "second-brain" ]] && short="notes" - brains="${brains:+$brains,}$short" - fi -done -set_status brains "$brains" - -if [[ -d "$target/.ai" ]]; then - spec=$(find "$target/.ai/specs" -maxdepth 1 -type f 2>/dev/null | sort | tail -n 1) - set_status sdd_spec "${spec##*/}" -else - set_status sdd_spec "" -fi diff --git a/zsh/scripts/ssh-helpers.zsh b/zsh/scripts/ssh-helpers.zsh index a8b9887..e2d6331 100644 --- a/zsh/scripts/ssh-helpers.zsh +++ b/zsh/scripts/ssh-helpers.zsh @@ -7,35 +7,3 @@ sshc() { [[ "$target" == -* ]] && { echo "Target SSH inválido: $target"; return 1; } CORTEX_SSH_TARGET="$target" ssh "$target" "$@" } - -# Abre un workspace remoto persistente en cmux usando aliases y opciones de ~/.ssh/config. -sshx() { - local target="${1:?Uso: sshx [cmux ssh args...]}" - shift - [[ "$target" == -* ]] && { echo "Target SSH inválido: $target"; return 1; } - - if ! command -v cmux >/dev/null 2>&1; then - echo "cmux no está disponible; usá sshc para una conexión SSH directa" - return 1 - fi - - CORTEX_SSH_TARGET="$target" cmux ssh "$target" "$@" -} - -# Diagnostica el cliente cmux y la resolución SSH del host sin iniciar una sesión. -sshx-doctor() { - local target="${1:?Uso: sshx-doctor }" - local failed=0 - [[ "$target" == -* ]] && { echo "Target SSH inválido: $target"; return 1; } - - command -v cmux >/dev/null 2>&1 || { echo "✗ cmux no encontrado"; failed=1; } - command -v ssh >/dev/null 2>&1 || { echo "✗ ssh no encontrado"; failed=1; } - if command -v ssh >/dev/null 2>&1 && ssh -G "$target" >/dev/null 2>&1; then - echo "✓ SSH config resuelve: $target" - else - echo "✗ SSH config no resuelve: $target" - failed=1 - fi - - return "$failed" -} diff --git a/zsh/scripts/worktree-helpers.zsh b/zsh/scripts/worktree-helpers.zsh index d95eec6..379e4c6 100644 --- a/zsh/scripts/worktree-helpers.zsh +++ b/zsh/scripts/worktree-helpers.zsh @@ -1,5 +1,5 @@ #region Worktree Helpers -# Funciones para gestión de git worktrees con integración cmux. +# Funciones para gestión de git worktrees. # Detecta repos PCSoft automáticamente y bloquea la creación de worktrees en ellos. # Verifica si el repo actual contiene archivos PCSoft (Categoría B — prohibido worktree) @@ -32,7 +32,7 @@ _wt_path_for() { printf '%s/%s/%s' "$(_wt_base_dir)" "$repo_name" "$name" } -# Crea un worktree en ~/dev/worktrees// y abre el agente desde cmux. +# Crea un worktree en ~/dev/worktrees// y abre el agente. # Uso: wtadd [branch] # — nombre del worktree (crea ~/dev/worktrees//) # [branch] — branch existente o nueva (default: crea branch nueva con el mismo nombre) @@ -82,10 +82,10 @@ wtadd() { echo "✓ Worktree creado: $wt_path" - if [[ "${CORTEX_MULTIPLEXER:-${CORTEX_DOTFILES_MULTIPLEXER:-cmux}}" == "cmux" ]]; then - echo "→ Abriendo agente para el worktree..." - cc "$wt_path" - fi + echo "✓ Worktree creado: $wt_path" + + echo "→ Abriendo agente para el worktree..." + cc "$wt_path" } # Lista los worktrees activos del repo actual.