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
8 changes: 5 additions & 3 deletions .github/workflows/check-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches: [main]
paths:
- "public/setup/**"
- "public/sh/**"
- "public/zsh/**"
- "tests/**"
Expand Down Expand Up @@ -62,22 +63,23 @@ jobs:
set -eu
sh -x ./public/sh/install.sh -a annex
test -f "${XDG_DATA_HOME:-$HOME/.local/share}/zi/bin/zi.zsh"
grep -q "z-shell/z-a-meta-plugins" ~/.zshrc
grep -q "z-shell/z-a-meta-plugins" "${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup/shell.zsh"
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
- name: "⚙️ Check: install.sh -a loader"
run: |
set -eu
sh -x ./public/sh/install.sh -a loader
test -f "${XDG_DATA_HOME:-$HOME/.local/share}/zi/bin/zi.zsh"
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/zi/init.zsh"
grep -q "zzinit" ~/.zshrc
grep -Fq "source '${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup.zsh'" ~/.zshrc
grep -Fq "zzinit" "${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup.zsh"
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
- name: "⚙️ Check: install.sh -a zunit"
run: |
set -eu
sh -x ./public/sh/install.sh -a zunit
test -f "${XDG_DATA_HOME:-$HOME/.local/share}/zi/bin/zi.zsh"
grep -q "@zunit" ~/.zshrc
grep -q "@zunit" "${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup/shell.zsh"
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
- name: "⚙️ Check: install_zpmod.sh"
run: sh -x ./public/sh/install_zpmod.sh
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/check-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
push:
branches: [main]
paths:
- "public/setup/**"
- "public/sh/**"
- "public/zsh/**"
- "tests/**"
Expand Down Expand Up @@ -62,22 +63,23 @@ jobs:
set -eu
sh -x ./public/sh/install.sh -a annex
test -f "${XDG_DATA_HOME:-$HOME/.local/share}/zi/bin/zi.zsh"
grep -q "z-shell/z-a-meta-plugins" ~/.zshrc
grep -q "z-shell/z-a-meta-plugins" "${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup/shell.zsh"
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
- name: "⚙️ Check: install.sh -a loader"
run: |
set -eu
sh -x ./public/sh/install.sh -a loader
test -f "${XDG_DATA_HOME:-$HOME/.local/share}/zi/bin/zi.zsh"
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/zi/init.zsh"
grep -q "zzinit" ~/.zshrc
grep -Fq "source '${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup.zsh'" ~/.zshrc
grep -Fq "zzinit" "${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup.zsh"
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
- name: "⚙️ Check: install.sh -a zunit"
run: |
set -eu
sh -x ./public/sh/install.sh -a zunit
test -f "${XDG_DATA_HOME:-$HOME/.local/share}/zi/bin/zi.zsh"
grep -q "@zunit" ~/.zshrc
grep -q "@zunit" "${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup/shell.zsh"
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
- name: "⚙️ Check: install_zpmod.sh"
run: sh -x ./public/sh/install_zpmod.sh
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/checksum.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ name: Checksum
on:
push:
paths:
- "public/setup/**"
- "public/sh/generate-checksums.sh"
- "public/sh/install_zpmod.sh"
- "public/sh/install.sh"
- "public/sh/setup.sh"
- "public/sh/sync-init.sh"
- "public/zsh/init.zsh"
- ".github/workflows/checksum.yml"
Expand Down
30 changes: 20 additions & 10 deletions .github/workflows/win-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ name: Windows Install
on:
pull_request:
paths:
- "public/setup/**"
- "public/sh/**"
- "public/zsh/**"
- "tests/**"
- ".github/workflows/win-install.yml"
push:
paths:
- "public/setup/**"
- "public/sh/**"
- "public/zsh/**"
- "tests/**"
Expand Down Expand Up @@ -46,20 +48,28 @@ jobs:
- name: 🪟 Dependencies (Windows)
uses: egor-tensin/setup-cygwin@fca9069f92361187d4abfaa5d8a7490e435d8349 # v4.0.2
with:
platform: x64
packages: curl git zsh
- name: 🪟 Run Install
run: |
set -eu
cd "$(cygpath -u "$GITHUB_WORKSPACE")"
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
sh ./tests/installers.sh
sh -x ./public/sh/install.sh -- -i skip
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" /home/runneradmin/.zi
sh -x ./public/sh/install.sh -- -a annex
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" /home/runneradmin/.zi
sh -x ./public/sh/install.sh -- -a loader
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" /home/runneradmin/.zi
sh -x ./public/sh/install.sh -- -a zunit
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" /home/runneradmin/.zi
sh -x ./public/sh/install.sh -- -a zpmod
sh -x ./public/sh/install.sh -i skip
test -f "${XDG_DATA_HOME:-$HOME/.local/share}/zi/bin/zi.zsh"
test ! -e ~/.zshrc
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
sh -x ./public/sh/install.sh -a annex
grep -Fq "z-shell/z-a-meta-plugins" "${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup/shell.zsh"
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
sh -x ./public/sh/install.sh -a loader
grep -Fq "source '${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup.zsh'" ~/.zshrc
grep -Fq "zzinit" "${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup.zsh"
command rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/zi" ~/.zi ~/.zshrc "${XDG_CONFIG_HOME:-$HOME/.config}/zi"
sh -x ./public/sh/install.sh -a zunit
grep -Fq "@zunit" "${XDG_CONFIG_HOME:-$HOME/.config}/zi/setup/shell.zsh"
# The Cygwin package is older than zpmod's required Zsh 5.8.1.
# Linux and macOS exercise the native module build.
shell: C:\tools\cygwin\bin\bash.exe --login -o igncr '{0}'
- name: 🪟 Smoke-test — verify zi.zsh present
run: |
Expand Down
59 changes: 49 additions & 10 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,45 @@
- **Installer**: [get.zshell.dev](https://get.zshell.dev)
- **jsDeliver CDN**: [cdn.jsdelivr.net/gh/z-shell/src@main/](https://cdn.jsdelivr.net/gh/z-shell/src@main/)

### Guided setup

`public/sh/install.sh` now delegates installation to the POSIX `sh` setup planner. The default `loader` profile writes a reviewable plan, applies the Zi checkout as one phase, and applies loader configuration as a separate phase. The `annex` and `zunit` profiles add pinned recipes that run on the first shell start.

For a normal installation, run:

```sh
sh -c "$(curl -fsSL https://get.zshell.dev)"
```

The downloaded `install.sh` remains the only entry point; it retrieves and
verifies its planner assets automatically. To install an exact source revision,
use the same tag, branch, or commit for the script and `ZI_SRC_REF`:

```sh
ref=v1.2.3
curl -fsSL "https://raw.githubusercontent.com/z-shell/src/${ref}/public/sh/install.sh" |
ZI_SRC_REF="${ref}" sh
```

To inspect and apply a plan manually:

```sh
sh public/sh/setup.sh plan --plan /tmp/zi-setup-plan --profile loader
plan_sha="$(cat /tmp/zi-setup-plan/plan.id)"
sh public/sh/setup.sh apply --plan /tmp/zi-setup-plan --phase checkout --expect "${plan_sha}"
sh public/sh/setup.sh apply --plan /tmp/zi-setup-plan --phase files --expect "${plan_sha}"
```

The files phase manages `init.zsh`, `setup.zsh`, `setup/pre.zsh`, `setup/shell.zsh`, and a marked `.zshrc` block. The user-facing block stays intentionally short:

```zsh
# >>> zi setup >>>
source '/home/you/.config/zi/setup.zsh'
# <<< zi setup <<<
```

The generated `setup.zsh` entrypoint owns the startup sequence and diagnostics. The files phase validates every recorded target before writing any target. A symlinked `.zshrc`, an externally changed managed block, an unrecognized Zi startup block, or checkout drift is refused with remediation output instead of being overwritten.

### Loader configuration

`public/zsh/init.zsh` defines `zzinit()`. Sourcing the file only declares the
Expand All @@ -61,13 +100,13 @@ function and applies defaults; nothing is cloned, sourced, or written until

The loader owns only the settings that must exist before Zi does:

| Setting | Default | Purpose |
| ------------------- | -------------------------------------------- | ---------------------------- |
| `ZI[REPOSITORY]` | `https://github.com/z-shell/zi.git` | Clone source |
| `ZI[STREAM]` | `main` | Branch or tag to clone |
| `ZI[HOME_DIR]` | Legacy home, otherwise XDG data `zi` root | Working-directory root |
| `ZI[BIN_DIR]` | `${ZI[HOME_DIR]}/bin` | Where `zi.zsh` is cloned |
| `ZI[MUTE_WARNINGS]` | `0` | Loader warning control |
| Setting | Default | Purpose |
| ------------------- | ----------------------------------------- | ------------------------ |
| `ZI[REPOSITORY]` | `https://github.com/z-shell/zi.git` | Clone source |
| `ZI[STREAM]` | `main` | Branch or tag to clone |
| `ZI[HOME_DIR]` | Legacy home, otherwise XDG data `zi` root | Working-directory root |
| `ZI[BIN_DIR]` | `${ZI[HOME_DIR]}/bin` | Where `zi.zsh` is cloned |
| `ZI[MUTE_WARNINGS]` | `0` | Loader warning control |

The loader mirrors Zi core's home-resolution contract because it must find or
clone `zi.zsh` before core can run. An explicit `ZI[HOME_DIR]` wins. A
Expand All @@ -85,9 +124,9 @@ it; do not add a duplicate default to the loader. See the

One loader-only toggle exists:

| Setting | Default | Purpose |
| --------------------- | ------- | ----------------------------------------------------------- |
| `ZI[LOADER_HISTORY]` | `1` | Set to `0` to leave `HISTFILE`/`SAVEHIST`/`HISTSIZE` alone |
| Setting | Default | Purpose |
| -------------------- | ------- | ---------------------------------------------------------- |
| `ZI[LOADER_HISTORY]` | `1` | Set to `0` to leave `HISTFILE`/`SAVEHIST`/`HISTSIZE` alone |

### Maintainer — Verify and Sync Loader

Expand Down
4 changes: 3 additions & 1 deletion public/checksum.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
6de66efba021ebcf462e7672577d9f6876f13db55691f04e7009ff7e78d658b8 public/sh/install_zpmod.sh
ef5ba08f64df01abbe752f6fbab13d231d863d03d41a71fe8eac85979b268de0 public/sh/install.sh
e322f6aea1c7878bdf6d12032fbb83528f7bbccb4738748335373d0c8380cbe5 public/sh/install.sh
5fd4e53be0a80877afd504b6f707d998786c8ceb088b361c49eb5d4d401783eb public/sh/setup.sh
08cc893ceb982fc99d17db1966c6c30790cc571e16e4f5392352d995f5252952 public/sh/sync-init.sh
fff8d1c340fb1e87c76f80cac2224e28761ccc7e2b117839b7be6f5311a1ac11 public/setup/profiles.tsv
c979e39748d1d86ace17a61ff2b1bf6e1224a43291c25bf7fad985d1e9e11af1 public/zsh/init.zsh
3 changes: 3 additions & 0 deletions public/setup/profiles.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# label verified z-a-meta-plugins revision
annexes 74bd8a8bc3bcff8398420ff5a38758dec5b90e2b
zunit 74bd8a8bc3bcff8398420ff5a38758dec5b90e2b
14 changes: 9 additions & 5 deletions public/sh/generate-checksums.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ set -eu
ROOT="$(
unset CDPATH
cd "$(dirname "$0")/../.." 2>/dev/null && pwd
)" || { printf '%s\n' "generate-checksums: cannot determine repository root" >&2; exit 1; }
)" || {
printf '%s\n' "generate-checksums: cannot determine repository root" >&2
exit 1
}

CHECKSUM_FILE="${ROOT}/public/checksum.txt"

Expand All @@ -31,15 +34,16 @@ sha256_file() {
}

# Clear (or create) the checksum file before writing fresh entries with `: > file`.
: > "${CHECKSUM_FILE}"
: >"${CHECKSUM_FILE}"
for f in \
public/sh/install_zpmod.sh \
public/sh/install.sh \
public/sh/setup.sh \
public/sh/sync-init.sh \
public/zsh/init.zsh
do
public/setup/profiles.tsv \
public/zsh/init.zsh; do
hash="$(sha256_file "${ROOT}/${f}")"
printf '%s %s\n' "${hash}" "${f}" >> "${CHECKSUM_FILE}"
printf '%s %s\n' "${hash}" "${f}" >>"${CHECKSUM_FILE}"
done

printf '%s\n' "Checksums written to ${CHECKSUM_FILE}"
Loading
Loading