Skip to content

feat(zsh): reach parity with the fish profile - #91

Merged
barbatdev merged 2 commits into
mainfrom
feat/zsh-parity
Oct 30, 2026
Merged

barbatdev merged 2 commits into
mainfrom
feat/zsh-parity

Conversation

@barbatdev

Copy link
Copy Markdown
Owner

Summary

First step of moving every machine (Mac, agent-dev, agent-gentle) from fish to zsh. Fish keeps working unchanged; removing it comes in a later PR.

  • zsh/scripts/profile-helpers.zsh (new): ports hbarbatdev, hrefactoria, gbarbatdev, grefactoria and herdr-screens with the same checks and messages.
  • zsh/cortex-dotfiles.zsh mirrors fish/conf.d/10-core.fish:
    • per-OS PATH list in the same order (Pi, Nix, bun, volta, cargo; Go/pnpm on Linux) plus ~/.gentle-ai/bin
    • Herdr clipboard guard from fix(fish): copy through OSC 52 from Herdr terminals on hosts with a desktop #86 (drop DISPLAY/WAYLAND_DISPLAY in Herdr terminals outside SSH)
    • CORTEX_HOME, CORTEX_ROOT, CORTEX_MULTIPLEXER, GENTLE_AI_CHANNEL=beta
    • PERSONAL_PROJECTS_DIR / TOOLS_DIR defaults now match fish (barbatdev/products, barbatdev/tools)
    • o alias only on macOS
  • Removes gs() (git status), which shadowed the bin/gs worktree tool.
  • install.sh now manages ~/.config/cortex-dotfiles/shell/cortex-dotfiles.zsh, the fragment ~/.zshrc sources. It was unmanaged; on the Mac it still points at an old cortex-dotfiles-main checkout.

Test plan

  • zsh -n, bash -n install.sh
  • Isolated zsh profile: new functions load; herdr-screens x and hbarbatdev inside Herdr fail with their messages; gs resolves to the command
  • Clipboard guard: unset in a Herdr terminal, kept over SSH and in a plain shell
  • ./install.sh --check: only new warning is the expected stale shell fragment link
  • Not yet run on Linux

🤖 Generated with Claude Code

https://claude.ai/code/session_01A9D7ph123Jn8iB1eGbr8Nz

barbatdev and others added 2 commits October 30, 2026 17:16
Prepares the move from fish to zsh on every machine.

- profile-helpers.zsh ports hbarbatdev, hrefactoria, gbarbatdev,
  grefactoria and herdr-screens.
- cortex-dotfiles.zsh mirrors fish/conf.d/10-core.fish: per-OS PATH list,
  the Herdr clipboard guard, CORTEX_HOME/ROOT/MULTIPLEXER,
  GENTLE_AI_CHANNEL, ~/.gentle-ai/bin, and the fish defaults for
  PERSONAL_PROJECTS_DIR and TOOLS_DIR; `o` only on macOS.
- Drop the gs() git-status function, which shadowed bin/gs.
- install.sh links the shell fragment ~/.zshrc sources, which was
  unmanaged and could point at another checkout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A9D7ph123Jn8iB1eGbr8Nz
@barbatdev
barbatdev merged commit e7591af into main Oct 30, 2026
1 check passed
@barbatdev

Copy link
Copy Markdown
Owner Author

Fleet review (deepseek)

Lens: evidence + test design. Ports the fish profile to zsh: per-OS PATH list, the #86 Herdr clipboard guard, project dirs, the Herdr/Ghostty profile helpers and install.sh now managing the shell fragment. I compared the diff against fish/conf.d/10-core.fish, zsh/zshrc and install.sh at this head: the PATH lists match element for element, the o/gs parity holds, the new managed link target is exactly the path zsh/zshrc sources ($HOME/.config/cortex-dotfiles/shell/cortex-dotfiles.zsh), install.sh runs mkdir -p "$(dirname "$dst")" before ln -sfn, and every path herdr-screens links (herdr/desktop/{themes,layouts,mods,settings.json}) exists in the repo. No blocking defect found. The findings are about the ordering semantics behind the "same order as fish" claim, one parity claim the diff cannot support, and the Linux check the PR itself leaves pending.

Suggestion (2)

  • PATH order does not reproduce fish's --move semantics, so ~/.local/bin lands in a different position (zsh/cortex-dotfiles.zsh:19): fish treats the same list with fish_add_path --path --move (fish/conf.d/10-core.fish:62-66), i.e. an entry that is already on PATH is moved to the front. _cortex_dotfiles_path_prepend instead skips an entry that is already present ([[ ":$PATH:" == *":$1:"* ]] ||). ~/.local/bin is prepended unconditionally at line 23 before the loop, so when the loop reaches it (entry 8 of the Darwin list, 9 of the Linux list) it is skipped and stays behind every entry the loop prepended. End state on macOS: .cargo, /opt/homebrew/bin, /opt/homebrew/sbin, .opencode, .volta, .bun, .nix-profile, /nix/..., /usr/local/bin, .pi/agent/bin, .local/bin; fish ends with .local/bin ahead of .opencode, .volta, .bun, .nix-profile, /nix/..., /usr/local/bin and .pi/agent/bin. The comment at line 26 ("same order as fish/conf.d/10-core.fish") only holds for entries that were not already on PATH. Suggested test condition: with ~/.local/bin and ~/.pi/agent/bin each holding a same-named executable, assert the shell's command -v result is the same in fish and zsh.
  • The Linux arm of the PATH list is the only untested one, and it is the only one using a glob qualifier (zsh/cortex-dotfiles.zsh:30): The PR's own test plan leaves "Not yet run on Linux" unchecked, and the Linux branch is the only place with $HOME/.local/go-*/bin(N) plus /usr/local/go/bin and ~/.local/share/pnpm/bin. agent-dev and agent-gentle are the Linux hosts this migration targets. zsh -n proves syntax but not that the (N) qualifier plus the -d guard leaves PATH unchanged when no Go install exists. Suggested test condition: on one Linux host, run the same isolated-profile check the PR lists for macOS (functions load, command -v for a tool from each list entry, PATH order captured) before the ~/.zshrc fragment is promoted there.

Question (1)

  • Where does fish define TOOLS_DIR? The PR claims the new default matches it (zsh/cortex-dotfiles.zsh:274): The PR body says "PERSONAL_PROJECTS_DIR / TOOLS_DIR defaults now match fish (barbatdev/products, barbatdev/tools)" and points at fish/conf.d/10-core.fish as the source of truth. PERSONAL_PROJECTS_DIR is there (line 25-27), but TOOLS_DIR does not appear anywhere in that file at this head, so the claim cannot be checked from the diff. Which fish file sets TOOLS_DIR (99-local, config.fish, or a host override), and is $BARBATDEV_DIR/tools the value it uses? If there is no fish default, the sentence in the PR body should say the zsh default is new instead of matching fish.

Verdict: ready to merge

@barbatdev

Copy link
Copy Markdown
Owner Author

Post-merge QA (glm)

First step of the fish-to-zsh move: zsh/scripts/profile-helpers.zsh ports the Herdr/Ghostty profile launchers and herdr-screens with the same guards and messages, cortex-dotfiles.zsh mirrors the fish 10-core PATH order per OS (with the .local/go-(N) glob and unconditional ~/.local/bin), ports the Herdr clipboard guard from #86 (DISPLAY/WAYLAND_DISPLAY dropped only in local Herdr terminals), aligns PERSONAL_PROJECTS_DIR/TOOLS_DIR with fish, adds the CORTEX_ env block and removes the gs() alias that shadowed bin/gs. install.sh now manages the ~/.config/cortex-dotfiles/shell fragment. Syntax checks, isolated profile tests, the clipboard guard cases and install.sh --check pass. The PR body discloses the one unchecked box (not yet run on Linux at merge time); the follow-up PR #94 confirms all machines now run zsh, which covers that gap after the fact.

No findings.

Verdict: clean

@barbatdev

Copy link
Copy Markdown
Owner Author

Post-merge QA (deepseek)

Lens: evidence + test design. The parity port is faithful where it counts: the per-OS PATH list keeps the fish order, the Herdr clipboard guard keeps the same condition, the fragment link becomes managed so the shell reads the clone in place, and profile-helpers.zsh reproduces the four profile launchers and the screens helper with their checks. The test plan, though, only exercises the refusal branches of the two new interactive helpers and never their success path, and one refusal guard keys on a variable the linked issue never names.

Suggestion (1)

  • herdr-screens is only tested with the input it must reject (zsh/scripts/profile-helpers.zsh): The test plan records "herdr-screens x" failing with its message, which covers the count validation and nothing after it. The success path (screen directories 2..count prepared, shared assets linked, settings.json copied once, the layout switch attempted) is the part that runs on every use and has no recorded evidence; the quoted regular expression on the right of =~ is also the kind of line whose behaviour differs between bash and zsh, so a passing test is the only thing that settles it. Test condition: herdr-screens 4 with a stubbed open/herdr-app → $HOME/.config/herdr-app-2..4 exist, each holds the eight shared links, and an existing settings.json is not overwritten.

Question (1)

  • The Herdr refusal guard tests HERDR_ENV, not the marker fix(fish): copy through OSC 52 from Herdr terminals on hosts with a desktop #86 attributed to herdr-core (zsh/scripts/profile-helpers.zsh): _herdr_with_profile refuses to run when HERDR_ENV is set, so that a preview is not launched from inside Herdr. The linked issue fix(fish): copy through OSC 52 from Herdr terminals on hosts with a desktop #86 states that herdr-core marks the terminals it starts with HC_TERMINAL_ID, and this same PR uses exactly that variable for the clipboard guard. If HERDR_ENV is only exported by a herdr child session, then a terminal opened by Herdr Desktop does not trip the guard and hbarbatdev/hrefactoria start a nested herdr with a private socket — the failure the check exists to prevent. Which variable does a Herdr Desktop terminal actually carry, and should the guard accept either?

Verdict: clean

@barbatdev
barbatdev deleted the feat/zsh-parity branch October 31, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant