Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,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 con overlay RefactorIA
- **Ls**: [eza](https://github.com/eza-community/eza)
- **AI CLI UX**: Claude Code statusline, OpenCode helpers y Herdr remoto
- **Workflow docs**: [Herdr workflow](docs/herdr-workflow.md) y [keymaps prácticos](docs/keymaps.md)
- **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)
- **Supply-chain guardrails**: defaults globales para `uv`, `npm`, `pnpm` y `bun`
- **Fuente**: FiraCode Nerd Font + variante custom RefactorIA

Expand Down Expand Up @@ -46,7 +46,7 @@ bash install.sh --dry-run
```

El instalador macOS:
1. Instala dependencias via Homebrew (starship, tmux, lazygit, neovim, eza, sketchybar, yabai, skhd, Karabiner-Elements, FiraCode Nerd Font)
1. Instala dependencias via Homebrew (cmux, starship, tmux, lazygit, neovim, eza, sketchybar, yabai, skhd, 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. Intenta seleccionar el profile `cortex` de Karabiner si `karabiner_cli` está disponible
Expand All @@ -69,6 +69,8 @@ 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
│ ├── git-helpers.zsh # Identidades Git y clone helpers
│ ├── tmux-helpers.zsh # Helpers tmux
│ ├── worktree-helpers.zsh # Helpers git worktree
Expand Down Expand Up @@ -127,6 +129,7 @@ Seguimiento: [cortex-dotfiles #31](https://github.com/barbatdev/cortex-dotfiles/
| `ccclip <files>` | 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 |
| `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 |
Expand Down
15 changes: 15 additions & 0 deletions claude/statusline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,21 @@ 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")

Expand Down
49 changes: 49 additions & 0 deletions docs/cmux-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 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 <host>` | Open a persistent cmux SSH workspace |
| `sshc <host>` | Open a conventional SSH connection |
| `sshx-doctor <host>` | Validate cmux, SSH, and host alias resolution |
| `wtadd <name> [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.
4 changes: 2 additions & 2 deletions docs/herdr-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ This workflow keeps terminal state persistent across local and remote work while
|------|-----|---------|
| Local Herdr | Normal work on the current machine | `hhere [path]`, `hfocus [path]` |
| Remote Herdr bridge | Persistent remote session rendered through the local client | `hremote <host> [session]` |
| Plain SSH/Mosh first | You need a normal remote shell before deciding what to run there | `sshx <host>`, `moshx <host> [path]` |
| Plain SSH first | You need a normal remote shell before deciding what to run there | `sshc <host>` |

`hremote` is not the same thing as `ssh` followed by `herdr`. `hremote` uses `herdr --remote` and attaches to a named Herdr session on the host through Herdr's remote bridge. `sshx` or `moshx` gives you a regular remote shell; from there, `hhere` starts or attaches Herdr as a local process on that remote host.
`hremote` is not the same thing as `ssh` followed by `herdr`. `hremote` uses `herdr --remote` and attaches to a named Herdr session on the host through Herdr's remote bridge. `sshc` gives you a regular remote shell; from there, `hhere` starts or attaches Herdr as a local process on that remote host.

In `hremote`, `Ctrl+V` is reserved by Herdr for remote image paste when supported by the terminal. Use normal shell paste bindings outside remote attach.

Expand Down
42 changes: 33 additions & 9 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,8 @@ PY
check_command starship warn
check_command nvim warn
check_command eza warn
check_command herdr warn
check_command mosh warn
check_command cmux warn
check_command tmux warn
check_command herdr warn
check_command lazygit warn
check_command sketchybar warn
check_command yabai warn
Expand All @@ -179,8 +177,6 @@ PY
check_command python3 warn
check_command starship warn
check_command nvim warn
check_command herdr warn
check_command mosh warn
check_command tmux warn
check_command lazygit warn
;;
Expand Down Expand Up @@ -245,6 +241,9 @@ PY
for path in "$DOTFILES"/zsh/scripts/*.zsh; do
check_shell "$path" zsh
done
for path in "$DOTFILES"/zsh/scripts/*.sh; do
check_shell "$path" bash
done
check_json "$DOTFILES/karabiner/karabiner.json"
for path in "$DOTFILES"/opencode/*.json "$DOTFILES"/opencode/**/*.json "$DOTFILES"/claude/themes/*.json; do
check_json "$path"
Expand Down Expand Up @@ -312,6 +311,21 @@ install_formula_if_missing() {
fi
}

install_cask_if_missing() {
local app_path="$1"
local cask="$2"
local tap="$3"

if [[ -d "$app_path" ]]; then
echo " ✓ $cask ya instalado"
elif [[ "$DRY_RUN" == true ]]; then
echo " → Would install $cask via Homebrew cask"
else
brew tap "$tap"
brew install --cask "$cask"
fi
}

# --- Verificar dependencias base ---
echo "📦 Verificando herramientas ($PLATFORM)..."

Expand All @@ -327,7 +341,7 @@ if [[ "$PLATFORM" == "Darwin" ]]; then

install_formula_if_missing starship starship "prompt"
elif [[ "$PLATFORM" == "Linux" ]]; then
for tool in zsh starship nvim herdr mosh tmux lazygit; do
for tool in zsh starship nvim tmux lazygit; do
if command -v "$tool" &>/dev/null; then
echo " ✓ $tool ya instalado"
else
Expand Down Expand Up @@ -358,8 +372,7 @@ karabiner_cli_path() {
if [[ "$PLATFORM" == "Darwin" ]]; then
install_formula_if_missing nvim neovim "editor terminal"
install_formula_if_missing eza eza "ls mejorado"
install_formula_if_missing herdr herdr "multiplexor remoto persistente"
install_formula_if_missing mosh mosh "SSH resiliente para workstations remotas"
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"
Expand Down Expand Up @@ -496,6 +509,7 @@ create_symlink "$DOTFILES/opencode/tui.json" "$HOME/.config/opencode/tui.j
create_symlink "$DOTFILES/opencode/themes" "$HOME/.config/opencode/themes"
create_symlink "$DOTFILES/tmux/tmux.conf" "$HOME/.tmux.conf"
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"
Expand Down Expand Up @@ -554,6 +568,16 @@ 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

if [[ "$PLATFORM" != "Darwin" ]]; then
:
elif [[ "$DRY_RUN" == true ]]; then
Expand Down Expand Up @@ -623,7 +647,7 @@ if [[ "$PLATFORM" == "Darwin" ]]; then
echo " 4. Si macOS bloqueó servicios, habilitá Accessibility y corré los fallbacks impresos arriba"
echo " 5. Abrí Karabiner-Elements y habilitá Input Monitoring/Accessibility si macOS lo pide"
else
echo " 3. Instalá zsh/starship/neovim/herdr/mosh/tmux/lazygit con el package manager del sistema si faltan"
echo " 3. Instalá zsh/starship/neovim/tmux/lazygit con el package manager del sistema si faltan"
fi
echo ""
echo " Para medir el load time:"
Expand Down
2 changes: 1 addition & 1 deletion local/env.zsh.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
# export OPENCODE_DEFAULT_FLAGS=""

# Multiplexor preferido para cc/oc y sesiones remotas.
# export CORTEX_MULTIPLEXER="herdr"
# export CORTEX_MULTIPLEXER="cmux"

# Navegación rápida para proyectos de una organización/equipo
# export INNIT_DIR="$BARBATDEV_DIR/innit"
Expand Down
Loading
Loading