# Zsh Setup Cross-platform Zsh installers and managed dotfiles for Oh My Zsh and Starship. ## Zsh ### Ubuntu ```zsh bash -c "$(curl -fsSL https://tinyurl.com/y6fhb594)" ``` ### WSL ```zsh bash -c "$(curl -fsSL https://tinyurl.com/ycyct6wp)" ``` ### macOS ```zsh bash -c "$(curl -fsSL https://tinyurl.com/yptybtpa)" ``` ### Configuration ```zsh bash -c "$(curl -fsSL https://tinyurl.com/y8vf753j)" ``` The platform installers share `config.sh`, which owns the managed-file list and download logic. Both configuration menu options install the canonical `zshrc` file. Existing files are replaced only after a non-empty download succeeds; failures return a nonzero status. Updates are atomic per file, not across the whole configuration set. When run from a checkout, installers load the adjacent `config.sh`. The curl-based entry points fetch it from the gist. `GIST_RAW_BASE` overrides the download base URL for both the helper and managed files. ## Repository layout | Files | Purpose | | --- | --- | | `zsh_ubuntu.sh`, `zsh_wsl.sh`, `zsh_macos.sh` | Platform setup and interactive menus | | `config.sh` | Shared configuration installer; also runnable on its own | | `zshrc`, `alias`, `func`, `pathrc`, `sourcerc`, `vimrc` | Managed shell and editor dotfiles | | `starship.toml` | Prompt configuration | | `ai-commit*.md`, `ai-commit*.txt` | Commit agents and prompts | | `test_*.py`, `test_plan_build.zsh` | Isolated regression tests | ## Shell framework and prompt The installers use Oh My Zsh for framework features and plugins, with the OMZ theme disabled: ```zsh ZSH_THEME="" source "$ZSH/oh-my-zsh.sh" eval "$(starship init zsh)" ``` Starship owns the prompt and loads after Oh My Zsh. The managed Starship config is installed at `~/.config/starship.toml`. A Nerd Font is required for the Powerline symbols. ## AI commits The managed `aicommit` function can use Claude, Copilot, or OpenCode to create a commit from staged changes: ```zsh aicommit opencode ``` The installers place the shared commit instructions at `~/.config/ai-commit-prompt.txt` and the required OpenCode agent at `~/.config/opencode/agents/ai-commit.md`. The agent is hidden from the interactive agent selector but remains available to `aicommit opencode`. It may inspect Git status, the cached diff, and recent history, and may execute `git commit`; all unrelated tools and shell commands are denied. **Changes affecting more than 30 staged paths default to per-module commits.** In an interactive terminal, the function asks whether to split; declining requests one combined commit. Without a terminal, or with `--yes`, it splits automatically. Use `--single` to explicitly request one commit, or `--modules` to split at any size; these options are mutually exclusive. The count uses the full staged set before diff filtering or truncation, including lock/minified files and both paths of a rename. Exactly 30 paths retains the single-commit default: ```zsh aicommit --modules opencode aicommit --modules --yes claude aicommit --single opencode ``` Automatic splitting uses the same planning and confirmation flow as `--modules`; `--yes` skips confirmation in either case (for example, `aicommit --yes opencode`). Plans that collapse a change above the threshold into one group are rejected before committing, with the index untouched. Grouping follows cohesive modules or submodules; 30 is the automatic-splitting threshold, not a hard size limit per planned module. The engine first plans the split using `~/.config/ai-commit-split-prompt.txt` and replies with a JSON plan that maps every staged path to a `type(scope)` group, ordered so dependencies land first. The function validates the plan against the staged paths, ignores paths that are not staged, appends any unplanned paths as a final commit, and shows the plan for confirmation (`--yes` skips it). It then stages each group from a snapshot of the original index, so partially staged files keep only their staged hunks and unstaged or untracked work is never touched, and asks the engine to commit that group with the normal commit instructions. If a group produces no commit, or a commit includes files outside its group, the run stops and restages the remaining groups. With OpenCode, planning uses the hidden `ai-commit-plan` agent at `~/.config/opencode/agents/ai-commit-plan.md`, which is denied every tool. Python 3 is required to parse the plan. ## Plan-build workflow The local `plan_build` function is a thin cached launcher for the canonical public [plan-build gist](https://opengist.resetrix.work/weehong/plan-build). When curl is available, each invocation stages `plan_build.zsh`, `SKILL.md`, and `ARCHITECT.md`, requires all three to be non-empty, and syntax-checks the executable. It then moves the complete bundle into a unique immutable release directory and atomically switches one `current` symlink. Refresh activation is serialized with a kernel-backed Zsh file lock so concurrent callers cannot mix releases and crashes cannot leave a stale lock. If refresh fails, the launcher preserves and uses the last complete, validated release and repairs its skill links. Zsh is always required; curl is required only when no valid cached release exists. ```zsh plan_build plan_build --prompt plan_build --writing-plan plan_build --prompt --brainstorm plan_build --yolo --writing-plan plan_build --architect plan_build --architect --new plan_build --architect --yolo ``` The canonical executable defines the current command behavior and options. Each invocation binds the executable and both skills to its selected immutable release. The launcher also points the installed Claude Code skill paths through the active `current` release: - `SKILL.md` → `~/.claude/skills/plan-build/SKILL.md` - `ARCHITECT.md` → `~/.claude/skills/plan-build-architect/SKILL.md` The launcher defaults to `https://opengist.resetrix.work/weehong/plan-build/raw/HEAD` and `${XDG_CACHE_HOME:-$HOME/.cache}/plan-build`. Override these with `PLAN_BUILD_BASE_URL` and `PLAN_BUILD_CACHE_DIR`. Installed skill paths remain fixed at `~/.claude/skills`; cached invocations receive immutable release paths through environment variables. The downloaded script is remote executable code: syntax validation catches malformed Zsh but is not a security sandbox, so only point `PLAN_BUILD_BASE_URL` at a source you trust. Remote code is executed in a child Zsh process and is never sourced into the caller shell. Invoking `plan_build` once installs or repairs both skill links. To install standalone files without the cached launcher, follow the installation instructions in the canonical gist instead. ## Development checks Run from the repository root with Bash, Zsh, Python 3, Git, and curl installed: ```sh for file in *.sh; do bash -n "$file" || exit; done for file in alias func pathrc sourcerc zshrc; do zsh -n "$file" || exit; done PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -p 'test_*.py' zsh -f test_plan_build.zsh git diff --check ``` Tests use temporary homes and local fixtures rather than installing packages or invoking AI services.