Skip to content

Shell prompt

Show the active checkout in your prompt, the way git prompts show the current branch:

~/lab/G004 $                # outside a workspace: unchanged
🌲 G004 ~/lab/G004 $        # inside a workspace with an active checkout

Install

Add one line to your shell's rc file:

# ~/.bashrc
eval "$(forest prompt init bash)"
# ~/.zshrc
eval "$(forest prompt init zsh)"

The snippet is pure shell — it never invokes the forest CLI while rendering a prompt, so your prompt stays fast. It reads .forest/HEAD directly, the same pointer every forest command uses (ADR-0003).

Customizing the icon

Set FOREST_PROMPT_ICON to replace the 🌲 (useful in terminals that render emoji at single width):

export FOREST_PROMPT_ICON='(f)'

When the segment appears

The prompt walks up from the current directory and stops at the first directory containing .forest or .git — the same boundary rule forest commands use (ADR-0010). The segment shows only when that boundary is a healthy workspace:

  • .forest/config.yaml exists at the boundary, and
  • .forest/HEAD names a valid checkout.

In every other case — outside any workspace, inside a plain git repo, missing or malformed HEAD — the segment renders nothing and your prompt is unchanged.

Framework notes

  • oh-my-zsh / powerlevel10k / other zsh themes: put the eval line after the theme is initialized. Themes assign PROMPT wholesale and would drop the segment if they load second.
  • bash ≥ 5.1 array PROMPT_COMMAND: the snippet prepends itself as a string, which flattens an array-valued PROMPT_COMMAND to its first element. If you use a framework that relies on the array form, register _forest_prompt_update yourself instead of using the emitted registration.
  • shopt -u promptvars (bash, rare): disables variable expansion in PS1, so the literal ${FOREST_PROMPT} would appear. Re-enable promptvars or embed $(...) substitution manually.

The eval line is idempotent — sourcing your rc file twice registers the hook and prompt prefix only once.