Files
mesh-catalog/modules/zsh/README.md
T
jochen cfe1dffa45
mesh/merge-gate pass: builds zsh → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group withhold-login-shell-execute delivered: every member is delivered
zsh: let a machine withhold node-login-shell's execute
execute runs any command as the operator account, which can become root
without a person. The operator withholds it on the control-node until a
call needs a person's approval (hq ADR 0268); the other machines keep it
for now. The setting execute (serve by default) is written into a
root-owned file the tools bundle reads at start, and anything but serve
withholds the verb, so the machine's runtime does not offer it.
2026-10-09 00:10:28 +02:00

94 lines
5.3 KiB
Markdown

# zsh
The login shell as a module (novox/hq ADR 0176, ADR 0204, to-be 41).
- Installs the `zsh` package and makes it the operator account's login shell through the `user`
shape. The host gives the found shell back when the module goes.
- Claims the mesh's `node-login-shell` seat and serves its verb `execute`: one command, run as the
account in a zsh login shell in the account's home. It is ended with everything it started after
20 s by default (25 s at most, below the runtime's 30 s call limit). Each stream is cut at 256 KiB
and the answer says so in `truncated`.
- **A machine may withhold `execute`** (hq ADR 0268). It runs any command as the operator account,
which can become root without a person. The setting `execute` is `serve` by default; a machine's
layer `withhold` (`mesh-controller.settings` with `module` zsh, `node` the machine, `values`
`{"execute":"withhold"}`, then a push) makes the runtime there offer no `execute` at all. The mesh
writes the value into a root-owned `tools.conf` in the module's directory, which the tools bundle
reads when the runtime starts it; a change restarts the runtime. Anything but `serve` (a wrong value,
no file) withholds it, and says why on stderr and in `zsh_config`'s `execute`. The control-node
withholds it until a call to it needs a person's approval (hq research 039).
- Its own tool `zsh_config` shows `~/.zshenv` and `~/.zshrc` as they are, with the mesh block's line
count in each, and whether this machine serves `execute`, and why.
- Contributes to the account's environment (ADR 0203): `EDITOR` and `VISUAL` (vim), `XDG_CONFIG_HOME`,
and `~/.local/bin`, `~/scripts`, `~/scripts/bin` at the start of `PATH`. The holder of
`node-environment` (`node-env`) writes them; this module writes no `export` of its own.
## The two blocks
Each block is the mesh's, between `# BEGIN mesh zsh.<id>` and `# END mesh zsh.<id>`. Every line
outside a block is yours, kept byte for byte, and given back when the module goes.
- **`~/.zshenv`, at the start:** sources `~/.config/mesh/environment.sh` if it is readable. Every zsh
reads this file: a login, a script, and `execute`.
- **`~/.zshrc`, at the start:** the defaults every machine shares, with the three slots other modules
fill (`first`, the defaults, `normal`, `last`). The defaults are the terminal title, seven
keybindings, the colour aliases, `ll`/`la`/`l`, `drun`, `disksize` and `sudo-disksize`. Your lines
below it run after it, so they win.
## The one-off migration (ADR 0182)
The mesh removes nothing it did not make. After the first push that assigns this module, the lines
below are in the block **and** in your own part of `~/.zshrc`. Until you delete your copies, they run
twice, which is harmless and visible. Deleting them is a person's act, once per machine.
**Delete once `zsh` is assigned.** The block or the environment now carries these:
1. `export EDITOR=vim`
2. `export VISUAL=vim`
3. `export XDG_CONFIG_HOME=$HOME/.config`
4. `export PATH="$HOME/.local/bin:$HOME/scripts:$HOME/scripts/bin:$HOME/.dotnet:$PATH"`. Keep the
one entry no module carries yet, as `export PATH="$HOME/.dotnet:$PATH"`.
5. The terminal title: `function set_terminal_title() { … }` and
`precmd_functions+=(set_terminal_title)`.
6. The seven `bindkey` lines (Home twice, Ctrl+A, End twice, Ctrl+E, Del).
7. `alias drun='docker run -it --rm'`, and the functions `disksize() { … }` and
`sudo-disksize() { … }`.
8. The `if [ -x /usr/bin/dircolors ]; then … fi` block, with its aliases `ls`, `dir`, `vdir`,
`grep`, `fgrep` and `egrep`.
9. `alias ll='ls -alhF'`, `alias la='ls -Ah'` and `alias l='ls -CFh'`.
**Delete once `powerlevel10k` is assigned.** Its contribution in the `normal` slot loads the prompt:
1. `#user_p10k_cache_file="${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${USER}.zsh"`, and the
`if [[ -r "$user_p10k_cache_file" ]]; then … fi` after it. It does nothing today, because the
variable is commented out.
2. `[[ ! -f ~/.zsh/themes/powerlevel10k/powerlevel10k.zsh-theme ]] || source …`
3. `[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh`
**Delete once `zsh-autosuggestions` / `zsh-syntax-highlighting` are assigned.** Each module loads
the distribution's copy from its own slot:
1. `[[ ! -f ~/.zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh ]] || source …`
2. `[[ ! -f ~/.zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ]] || source …`
**What stays yours.** Keep these below the block until a module carries them:
- the `NVM_DIR` lines;
- `MY_KV_PATH` and `MY_LIB_PATH`;
- `CLAUDE_CODE_DISABLE_TERMINAL_TITLE`;
- the `killport` and `findport` aliases;
- the `zstyle` lines;
- the line sourcing `~/.zshrc.local`, and that file itself.
**Paths no longer used.** The predecessor cloned these and nothing of the mesh reads them. Remove
them by hand once the module that replaces each is assigned:
- `~/.zsh/themes/powerlevel10k`: replaced by `powerlevel10k`'s pinned copy in
`~/.local/share/powerlevel10k`;
- `~/.p10k.zsh`: replaced by `~/.config/powerlevel10k/p10k.zsh`, the same bytes, once
`powerlevel10k` is assigned;
- `~/.zsh/plugins/zsh-autosuggestions` and `~/.zsh/plugins/zsh-syntax-highlighting`: replaced by
the distribution's packages;
- `~/.zsh/plugins/zsh-autocomplete`: loaded by nothing today.
Anything else under `~/.zsh/` is yours.