Run the setup script on first installation, after pulling upgrades, and whenever the repository moves to a new location. It is idempotent: re-running it makes no changes when the setup is already current.
# Windows
& <repo>\pwsh\Install.ps1# Linux and WSL
bash <repo>/linux/install.sh- Adds a marker-delimited block to the shell profile that sources the entry
point (
pwsh/main.ps1orlinux/main.sh). On Windows the block is written to the current user's all-hosts profile (profile.ps1). A stale block is updated in place; an unmarked manualsourceline is reported and left untouched. - Persists the environment values listed under Persistent environment.
- Installs or registers shared tool configuration:
- Espanso:
config/espanso/_base.ymlandconfig/espanso/whitelist.ymlare installed into thematch/andconfig/directories of the root Espanso reports for itself. See Espanso layout. - Clink (Windows, when
clinkis available): registersconfig/clinkas a Lua script path withclink installscripts; selects the Clink prompt fromSettings.psd1(oh-my-poshwithohmyposh.themeset toconfig/omp/catppuccin_gruvbox.json, orstarshipwithSTARSHIP_CONFIGset toconfig/starship/catppuccin-powerline.toml;noneselects no custom prompt); and pointsclink.autostartatconfig/clink/clink_start.cmd. Clink only runs insidecmd.exe, so it uses the standalone (glyph) themes. All changes go through the Clink CLI, and the registered path and managed settings are recorded so-Uninstallcan reverse them. Whenclinkis not onPATH, these steps are skipped with an advisory. - Git (Linux, when
gitis available): configures the global credential cache with a six-hour timeout and records the previous helper values for uninstall.
- Espanso:
- Resolves the Espanso root by asking the tool (Windows tries
espansod path configthenespanso path config; Linux triesespansothenespansod), then falls back to the platform default (%APPDATA%\espansoon Windows,${XDG_CONFIG_HOME:-~/.config}/espansoon Linux). The-EspansoRoot/--espanso-rootoption overrides detection. - Reports unavailable expected commands on every run;
-Check/--checkalso reports setup freshness. Missing optional tools never fail the run, and profile startup does not enumerate commands.
All other startup behavior remains runtime-managed: PATH, aliases, prompt
initialization, the SSH agent, and the generated environment.d file are
handled by startup code and are never modified here.
- No package installation and no privilege escalation.
- No creation of symbolic links or junctions on Windows; configuration files are copied so no elevation is required.
- No changes to secrets, SSH data, or CA certificates. Git credential-helper
configuration is the only Git state changed. The installer never writes
environment.ddirectly; runtime startup publishes the managed values.
Setup keeps these values set (Windows values live in the User environment scope unless noted):
GTK_OVERLAY_SCROLLING=0(Linux only) — use traditional GTK scrollbars. The managed profile block exports it and runtime startup publishes it to~/.config/environment.d/90-customshell.conffor graphical applications.UV_SYSTEM_CERTS=true— use the platform certificate store for uv, which otherwise bundles Mozilla roots. On Linux, startup exports it from the managed profile block and publishes it to~/.config/environment.d/90-customshell.conffor the systemd user session.WSLENV=USERPROFILE/up— share the Windows user-profile path with WSL, translating the path and applying only from Windows to WSL.CONDA_PATH=<directory containing conda.exe>— set when conda is found onPATH, so profile startup can lazily initialize conda. It is not set when conda is absent, and an existing valid value is respected and left unmanaged.STARSHIP_CONFIG=<repo>\config\starship\catppuccin-powerline.toml— set whenSettings.psd1selects thestarshipprompt, so Starship (including Clink's starship prompt) reads the repository theme. It is cleared when the prompt changes away from starship.
On Windows these values and the exact values setup applied are tracked in
%LOCALAPPDATA%\CustomShell\environment.json; -Uninstall clears values it
still owns, and locally modified values are reported and kept. This ownership
check also applies when a value is no longer desired after settings change.
Legacy environment.txt state is read conservatively and migrated on the next
successful install. CONDA_PATH is recorded only when setup set it, and
STARSHIP_CONFIG only while the starship prompt is selected.
-EnvironmentScope Process applies changes to the current process only and
exists so tests never touch the registry.
Processes already running before setup keep their old environment block, so a new session may not see new values until the environment refreshes (sign out and back in, or restart the terminal host). Linux shells pick them up the next time they start.
--check Report current state without changing anything.
--dry-run Print intended actions without changing anything.
--uninstall Remove the managed profile, links, and Git helper.
--force Replace conflicting Espanso files (with a backup).
--bashrc <path> Override the rc file to edit.
--espanso-root <dir> Override the Espanso configuration root.
-h, --help Show help and exit.
Linux links config/espanso/_base.yml into <root>/match and
config/espanso/whitelist.yml into <root>/config. A conflicting regular file
is skipped unless --force is given, in which case it is moved to
<file>.customshell.bak before linking. --uninstall removes only links that
still point into the repository.
Linux records previous global Git credential-helper values under
${XDG_STATE_HOME:-~/.local/state}/customshell/. --uninstall restores them
only while the configured cache helper is still unchanged; a locally modified
helper is reported and kept.
--check exits non-zero when the profile block, Espanso links, or Git helper are
missing or stale, and reports the CUSTOM_CA_CERT prerequisite (only needed on
managed devices). Advisories about optional commands do not affect the exit
status.
-Check Report current state without changing anything.
-Help Print help and exit.
-DryRun Print intended actions without changing anything.
-Uninstall Remove the managed profile block and configuration.
-Force Replace conflicting configuration files (with a backup).
-ProfilePath <path> Override the profile file to edit (defaults to the
current user's all-hosts profile).
-EspansoRoot <dir> Override the Espanso configuration root.
-ClinkCommand <cmd> Override the Clink command (defaults to clink on PATH).
-SettingsPath <path> Override the settings data file (defaults to
pwsh/Settings.psd1).
-StateDir <dir> Override the install-manifest and state directory.
-EnvironmentScope User (default) or Process. Process is for testing only.
Windows copies config/espanso/_base.yml into <root>\match and
config/espanso/whitelist.yml into <root>\config, recording destinations in
%LOCALAPPDATA%\CustomShell\installed.txt. A conflicting file is skipped unless
-Force is given, in which case it is backed up to <file>.customshell.bak.
-Uninstall removes only tracked files that still match the shipped source, and
reports and keeps locally modified files. Clink state is tracked separately in
%LOCALAPPDATA%\CustomShell\clink.json.
-Check exits non-zero when the profile block or expected configuration files
are missing or stale, when another profile also sources CustomShell, when a
User-scope environment value differs, or when Clink is installed but its script
path or managed settings are stale. Missing optional commands, and Clink itself,
do not affect the exit status when absent.
The entry scripts are thin and delegate to focused modules so behavior is easy to find and test:
linux/install.sh linux/install/common.sh
linux/install/profile.sh
linux/install/environment.sh
linux/install/espanso.sh
linux/install/git.sh
linux/install/checks.sh
pwsh/Install.ps1 pwsh/Install/Common.ps1
pwsh/Install/Profile.ps1
pwsh/Install/Environment.ps1
pwsh/Install/Espanso.ps1
pwsh/Install/Configs.ps1
pwsh/Install/Clink.ps1
pwsh/Install/Checks.ps1
The prompt is selected by pwsh/Settings.psd1 (PowerShell) or PRETTY_PROMPT
(Bash). Oh My Posh and Starship read their themes directly from config/omp/
and config/starship/. Starship is pointed at the repository theme through
STARSHIP_CONFIG, choosing catppuccin-powerline.toml for standalone terminals
and plain-text-symbols.toml otherwise.
Espanso keeps its configuration under a single root containing config/ and
match/. The repository follows that layout: whitelist.yml lives in config/
and its includes: ../match/_base.yml resolves to the _base.yml installed in
match/.
Scoop installs Espanso in portable mode, so the root is a .espanso junction
under scoop\persist\espanso (reported by espanso path config as the
versioned scoop\apps\espanso\current\.espanso path, which points at the same
place). The installer prefers the tool's own report, so it follows updates
across Espanso versions.
- Clink configuration is skipped when
clinkis not onPATH; installer runs report an advisory and-Checktreats it as optional. - Clink always uses the standalone (glyph) themes, so a glyph-limited console may render them imperfectly.
clink.autostartis executed as a command line, so a repository path containing spaces may need manual quoting.