# Powerlevel10k Administrator & Developer Guide

This guide is for administrators, power users, and developers who need to understand how
Powerlevel10k works internally: its two-layer architecture, the bundled `gitstatusd`
backend and its IPC protocol, the configuration parameter surface, deployment in shared
and air-gapped environments, security characteristics, and the source-level structure of
the project.

The end-user-facing material — installation, the configuration wizard, troubleshooting,
and customization recipes — lives in the **User Guide**. This document assumes you've
read it (or don't need it) and focuses on internals and operations.

---

## Table of Contents

1. [Executive Summary](#1-executive-summary)
2. [Architecture](#2-architecture)
3. [Repository Structure](#3-repository-structure)
4. [The Load Sequence](#4-the-load-sequence)
5. [The gitstatus Backend](#5-the-gitstatus-backend)
6. [The gitstatus IPC Protocol](#6-the-gitstatus-ipc-protocol)
7. [gitstatusd C++ Internals](#7-gitstatusd-c-internals)
8. [Configuration Reference](#8-configuration-reference)
9. [Instant Prompt Internals](#9-instant-prompt-internals)
10. [Deployment & Operations](#10-deployment--operations)
11. [Security Analysis](#11-security-analysis)
12. [Performance Engineering](#12-performance-engineering)
13. [Code Patterns & Conventions](#13-code-patterns--conventions)
14. [Standalone gitstatus Usage](#14-standalone-gitstatus-usage)
15. [Potential Improvements](#15-potential-improvements)
16. [Quick Reference](#16-quick-reference)

---

## 1. Executive Summary

Powerlevel10k is a **Zsh prompt theme** with an unusual design goal: render an
information-rich prompt with *zero* perceptible latency, while keeping the displayed
information up to date. It achieves this by splitting into two cooperating layers:

- A **Zsh frontend** — a large, heavily optimized Zsh engine (`internal/p10k.zsh`,
  ~9,500 lines) that defines prompt segments, draws them, and manages configuration.
- A **compiled Git backend** — `gitstatusd`, a multithreaded C++ daemon (vendored from
  the sibling [gitstatus](https://github.com/romkatv/gitstatus) project) that computes
  Git repository status via [libgit2](https://github.com/libgit2/libgit2) far faster
  than spawning `git`, and serves results over a binary protocol.

| Property | Value |
|----------|-------|
| **Type** | Zsh prompt theme + bundled compiled helper daemon |
| **Languages** | Zsh (frontend), C++ (gitstatusd backend) |
| **Primary entry point** | `powerlevel10k.zsh-theme` (sourced from `~/.zshrc`) |
| **Configuration** | `~/.p10k.zsh` (generated by `p10k configure`), `POWERLEVEL9K_*` parameters |
| **License** | MIT |
| **Minimum runtime** | Zsh ≥ 5.3 (≥ 5.4 for instant prompt) |
| **External runtime deps** | none required; `git` only if `vcs` is used; `gitstatusd` is bundled/downloaded |
| **Network footprint** | none at runtime, except a one-time `gitstatusd` binary download |

> [!NOTE]
> The upstream project is in maintenance mode (no new features, limited bug fixing) but
> commits to backward compatibility with all `POWERLEVEL9K_*` configuration indefinitely.

---

## 2. Architecture

```
                          ~/.zshrc
                             │ source
                             ▼
                  powerlevel10k.zsh-theme            (loader / option shim)
                             │ source
                             ▼
                   internal/p10k.zsh                 (the engine, ~9.5K lines)
        ┌────────────────────┼─────────────────────────────┐
        │                    │                              │
        ▼                    ▼                              ▼
 internal/icons.zsh   internal/configure.zsh        prompt rendering
 (icon tables per     internal/wizard.zsh           (PS1 / RPS1 builders,
  POWERLEVEL9K_MODE)  internal/parser.zsh            segment functions)
                      internal/worker.zsh                  │
                                                           │ query (async)
                                                           ▼
                                              gitstatus/gitstatus.plugin.zsh
                                                           │ spawns + talks to
                                                           ▼
                                                   gitstatusd  (C++ daemon)
                                                           │ uses
                                                           ▼
                                                       libgit2
```

### The two layers and why they exist

**Frontend (Zsh).** The engine builds the `PS1` and `RPS1` parameters that Zsh uses to
draw the prompt. Each prompt *segment* (dir, vcs, time, kubecontext, …) is a Zsh function
named `prompt_<name>`. The engine is aggressively optimized: it precompiles itself to
`.zwc` bytecode, caches a serialized "dump" of computed state, and avoids forking
external processes on the prompt's critical path.

**Backend (C++).** Computing Git status is the single most expensive thing a prompt can
do. Spawning `git status` on every prompt is slow, especially in large repositories. So
Powerlevel10k delegates that work to `gitstatusd`: a long-lived, multithreaded daemon
that holds repository handles open, talks to libgit2 directly, and answers status
queries over a pair of FIFOs. The frontend queries it **asynchronously** so a slow
answer never blocks the prompt.

### The asynchronous status flow

1. After each command, the engine asks `gitstatusd` for the current directory's status.
2. If a reply arrives within `POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS` (default 10 ms),
   it is rendered immediately.
3. Otherwise the engine renders the *last known* status in grey and registers a callback.
4. When the fresh status arrives, the engine triggers a prompt refresh in full color.

This is the mechanism behind the "fast *and* up to date" guarantee.

---

## 3. Repository Structure

```
powerlevel10k/
├── powerlevel10k.zsh-theme       Loader; sourced from ~/.zshrc
├── powerlevel9k.zsh-theme        Compatibility shim for Powerlevel9k users
├── prompt_powerlevel10k_setup    promptinit integration
├── prompt_powerlevel9k_setup     promptinit integration (9k name)
├── Makefile                      Build helpers (pack/release tasks)
├── README.md                     Canonical user documentation
├── font.md                       Font notes
├── config/                       Six ready-made prompt presets
│   ├── p10k-lean.zsh
│   ├── p10k-lean-8colors.zsh
│   ├── p10k-classic.zsh
│   ├── p10k-rainbow.zsh
│   ├── p10k-pure.zsh
│   └── p10k-robbyrussell.zsh
├── internal/                     The Zsh engine
│   ├── p10k.zsh                  Main engine (~9.5K lines): segments, p10k command
│   ├── icons.zsh                 Icon tables, one set per POWERLEVEL9K_MODE
│   ├── configure.zsh             p10k configure entry / preflight checks
│   ├── wizard.zsh                Interactive configuration wizard UI
│   ├── parser.zsh                Config/zshrc parsing helpers
│   └── worker.zsh                Background worker (async computation in a sub-zsh)
└── gitstatus/                    Vendored gitstatus backend
    ├── gitstatus.plugin.zsh      Zsh bindings (spawns/queries gitstatusd)
    ├── gitstatus.plugin.sh       Bash bindings
    ├── gitstatus.prompt.zsh      Standalone Zsh prompt (no Powerlevel10k)
    ├── gitstatus.prompt.sh       Standalone Bash prompt
    ├── install                   Resolves/downloads the gitstatusd binary
    ├── build / mbuild            Build scripts for gitstatusd from source
    ├── usrbin/                   Cache slot for a vendored gitstatusd binary
    └── src/                      C++ source for gitstatusd (libgit2-based)
```

### Key C++ source files (`gitstatus/src/`)

| File | Responsibility |
|------|----------------|
| `gitstatus.cc` | daemon main loop; reads requests, dispatches, writes responses |
| `git.cc` / `git.h` | libgit2 wrappers; status computation |
| `index.cc` / `index.h` | fast index scan; `Index` class produces dirty candidates |
| `repo.cc` / `repo.h` | per-repository state and scanning logic |
| `repo_cache.cc` / `repo_cache.h` | cache of open repositories (keyed by path) |
| `dir.cc`, `check_dir_mtime.cc` | directory enumeration and mtime-based change detection |
| `arena.cc` / `arena.h` | arena allocator for fast, churn-free allocation |
| `thread_pool.cc` | worker thread pool for parallel scanning |
| `request.cc`, `response.cc` | parse request records / serialize response records |
| `tag_db.cc` | tag lookup (the `VCS_STATUS_TAG` field) |
| `serialization.h`, `strings.*`, `string_view.h`, `string_cmp.h` | low-level string utilities |
| `options.cc` / `options.h` | daemon command-line option parsing |
| `logging.cc`, `timer.cc`, `time.h` | logging and timing instrumentation |

---

## 4. The Load Sequence

When `~/.zshrc` sources `powerlevel10k.zsh-theme`, the following happens (see
`powerlevel10k.zsh-theme` and the top of `internal/p10k.zsh`):

1. **Option shimming.** The loader temporarily disables `aliases`, `sh_glob`, and brace
   expansion so the theme parses identically regardless of the user's option set, then
   restores the originals at the end. (A leading-space trick on `local` works around
   Antigen stripping the keyword.)
2. **Locate the install dir.** `__p9k_root_dir` is set from
   `POWERLEVEL9K_INSTALLATION_DIR` or the script's own path.
3. **Define the intro preamble.** `__p9k_intro` is a reusable `emulate -L zsh …` string
   that every engine function evaluates first, guaranteeing a known option environment.
   A locale variant (`__p9k_intro_locale`) forces a UTF-8 `LC_CTYPE` when the current
   codeset isn't UTF-8.
4. **Load the dump cache.** If a precomputed dump file
   (`${XDG_CACHE_HOME:-~/.cache}/p10k-dump-<user>.zsh`) exists and matches, `_p9k_preinit`
   restores serialized state to skip recomputation.
5. **Self-compile to bytecode.** If the install dir is writable and Zsh ≥ 5.1, each engine
   file (`p10k.zsh`, `icons.zsh`, `configure.zsh`, `worker.zsh`, `parser.zsh`, the
   gitstatus plugin and installer) is `zcompile`d to a `.zwc` next to it (only when stale).
   This makes subsequent loads markedly faster.
6. **Source the engine.** `internal/p10k.zsh` is sourced, defining all segment functions,
   the `p10k` command, and the prompt hooks.
7. **Instant-prompt option toggling.** `prompt_cr`/`prompt_sp` are set or unset depending
   on whether an instant prompt is active.

> [!NOTE]
> Bytecode compilation requires the installation directory and its `internal/` and
> `gitstatus/` subdirectories to be **writable**. In read-only deployments (system
> packages, immutable images) compilation is silently skipped — correctness is unaffected,
> only first-load speed.

---

## 5. The gitstatus Backend

`gitstatusd` is managed entirely by the Zsh/Bash bindings in
`gitstatus/gitstatus.plugin.{zsh,sh}`. Administrators rarely interact with it directly,
but understanding its controls is essential for tuning and troubleshooting.

### Lifecycle functions

| Function | Purpose |
|----------|---------|
| `gitstatus_start [OPTIONS]` | Start `gitstatusd` in the background (idempotent — succeeds silently if already running). |
| `gitstatus_query [OPTIONS]` | Query status for a directory; populates `VCS_STATUS_*` variables. |
| `gitstatus_stop` | Stop the daemon and close its file descriptors. |
| `gitstatus_check` | Return 0 iff a previous `gitstatus_start` succeeded. |

### `gitstatus_start` options → daemon flags

Each binding flag maps to a `gitstatusd` command-line argument:

| Flag | Default | Daemon argument | Meaning |
|------|---------|-----------------|---------|
| `-t FLOAT` | 5 | (init self-check timeout) | Fail init if no response within this many seconds. |
| `-s INT` | 1 | `--max-num-staged` | Report at most this many staged changes (negative = ∞). |
| `-u INT` | 1 | `--max-num-unstaged` | Report at most this many unstaged changes (negative = ∞). |
| `-c INT` | 1 | `--max-num-conflicted` | Report at most this many conflicted changes (negative = ∞). |
| `-d INT` | 1 | `--max-num-untracked` | Report at most this many untracked files (negative = ∞). |
| `-m INT` | -1 | `--dirty-max-index-size` | Report `-1` for unstaged/untracked/conflicted if the index has more than this many files (negative = ∞). |
| `-r INT` | 3600 | `--repo-ttl-seconds` | Close repos unused for this long to free memory/FDs (negative = ∞). |
| `-e` | off | `--recurse-untracked-dirs` | Count files inside untracked directories (like `git status`). |
| `-U` | off | `--ignore-status-show-untracked-files` | Ignore `status.showUntrackedFiles=false`. |
| `-W` | off | `--ignore-bash-show-untracked-files` | Ignore `bash.showUntrackedFiles=false`. |
| `-D` | off | `--ignore-bash-show-dirty-state` | Ignore `bash.showDirtyState=false`. |

The daemon is always launched with `--parent-pid="$$"` (so it dies with its parent) and
`--num-threads` (see [Performance](#12-performance-engineering)).

> [!TIP]
> Powerlevel10k's own standalone prompt scripts call `gitstatus_start -s -1 -u -1 -c -1
> -d -1` — i.e. uncapped counts — because they want exact numbers. The Powerlevel10k
> engine instead tunes these via `POWERLEVEL9K_VCS_*` parameters.

### `gitstatus_query` options

| Flag | Meaning |
|------|---------|
| `-d STR` | Directory to query. Defaults to `$PWD`. Ignored if `GIT_DIR` is set. |
| `-t FLOAT` | Timeout in seconds; block at most this long for a result. |
| `-p` | "Plumbing" mode: skip everything that requires reading the Git index. Sets index-derived counts to 0. |

### Environment variables that control gitstatusd

| Variable | Effect |
|----------|--------|
| `GITSTATUS_DAEMON_PID` | Set by `gitstatus_start`; presence means the daemon is running. |
| `GITSTATUS_LOG_LEVEL` | Daemon log level (e.g. `INFO`, `DEBUG`). Implies logging is enabled. |
| `GITSTATUS_ENABLE_LOGGING` | Set to `1` to enable logging at `INFO` without setting a level. |
| `GITSTATUS_DAEMON_LOG` | Path the binding writes the daemon's log to (`/dev/null` when logging is off). |
| `GITSTATUS_NUM_THREADS` | Override the thread-count heuristic for the daemon. |
| `GITSTATUS_CACHE_DIR` | Where the downloaded `gitstatusd` binary is cached. Defaults to `${XDG_CACHE_HOME:-$HOME/.cache}/gitstatus`. |
| `GITSTATUS_AUTO_INSTALL` | `0` disables the automatic binary download (offline installs). Default `1`. |

---

## 6. The gitstatus IPC Protocol

`gitstatusd` communicates over two FIFOs (request and response) created in a temp
directory. The wire format uses ASCII control characters as delimiters:

- **Unit Separator** `\x1f` (`0o037`) — separates fields *within* a record.
- **Record Separator** `\x1e` (`0o036`) — terminates a record.

### Handshake

On start, the binding writes a request FD and response FD, reads the daemon PID from the
response stream, then performs a hello/bye handshake:

```text
client → daemon:  }hello\x1f\x1e
daemon → client:  }hello\x1f0\x1e        # "0" = ok
...
daemon → client:  }bye\x1f0\x1e          # on clean shutdown
```

While the daemon binary is being fetched on first use, the binding prints a spinner and
the `[gitstatus] fetching gitstatusd ..` message until the `}hello\x1f0` reply arrives.

### Request record

```text
<request_id>\x1f<dir>\x1f<no_diff>\x1e
```

- `request_id` — a random `$RANDOM.$RANDOM.$RANDOM.$RANDOM` token used to match responses.
- `dir` — the directory to query. A leading `:` signals that `GIT_DIR` is being passed
  explicitly rather than a working directory.
- `no_diff` — `1` in plumbing mode (`-p`), else `0`.

### Response record and `VCS_STATUS_*` fields

A response is a `\x1f`-delimited record. The first field echoes the `request_id`; the
second is `1` for a repository hit, anything else for "not a repo". On a hit, the binding
maps positional fields onto these variables (`VCS_STATUS_RESULT=ok-sync`):

| Variable | Meaning |
|----------|---------|
| `VCS_STATUS_WORKDIR` | repository working directory |
| `VCS_STATUS_COMMIT` | HEAD commit hash (40 hex digits, or empty for an empty repo) |
| `VCS_STATUS_COMMIT_ENCODING` | encoding of the HEAD commit message (empty = UTF-8) |
| `VCS_STATUS_COMMIT_SUMMARY` | first line of the HEAD commit message |
| `VCS_STATUS_LOCAL_BRANCH` | local branch name, or empty if detached |
| `VCS_STATUS_REMOTE_NAME` | remote name, e.g. `origin` |
| `VCS_STATUS_REMOTE_BRANCH` | upstream branch name |
| `VCS_STATUS_REMOTE_URL` | remote URL |
| `VCS_STATUS_ACTION` | repository state (merge, rebase, …); empty if none |
| `VCS_STATUS_INDEX_SIZE` | number of files in the index |
| `VCS_STATUS_NUM_STAGED` | staged change count |
| `VCS_STATUS_NUM_UNSTAGED` | unstaged change count |
| `VCS_STATUS_NUM_CONFLICTED` | conflicted change count |
| `VCS_STATUS_NUM_UNTRACKED` | untracked file count |
| `VCS_STATUS_NUM_STAGED_NEW` | staged new files (renames count as delete + new) |
| `VCS_STATUS_NUM_STAGED_DELETED` | staged deleted files |
| `VCS_STATUS_NUM_UNSTAGED_DELETED` | unstaged deleted files |
| `VCS_STATUS_HAS_STAGED` | `1`/`0` |
| `VCS_STATUS_HAS_UNSTAGED` | `1`/`0`, or `-1` if unknown (index over `-m` threshold) |
| `VCS_STATUS_HAS_CONFLICTED` | `1`/`0`, or `-1` if unknown |
| `VCS_STATUS_HAS_UNTRACKED` | `1`/`0`, or `-1` if unknown |
| `VCS_STATUS_COMMITS_AHEAD` / `_BEHIND` | commits ahead of / behind upstream |
| `VCS_STATUS_PUSH_REMOTE_NAME` / `_URL` | push remote name / URL |
| `VCS_STATUS_PUSH_COMMITS_AHEAD` / `_BEHIND` | commits ahead of / behind the push remote |
| `VCS_STATUS_STASHES` | number of stashes |
| `VCS_STATUS_TAG` | last tag (lexicographic) pointing at HEAD |
| `VCS_STATUS_NUM_SKIP_WORKTREE` | files with the skip-worktree bit |
| `VCS_STATUS_NUM_ASSUME_UNCHANGED` | files with the assume-unchanged bit |

When the directory isn't in a repository, `VCS_STATUS_RESULT=norepo-sync` and all the
above variables are unset.

> [!IMPORTANT]
> The `-1` ("unknown") values for `HAS_UNSTAGED/CONFLICTED/UNTRACKED` are how the daemon
> skips expensive file scanning in very large repositories. The `-m` flag
> (`--dirty-max-index-size`) sets the threshold. This is what produces the `─` symbol in
> the prompt — it means "too big to count cheaply", not "error".

---

## 7. gitstatusd C++ Internals

The hottest path in `gitstatusd` is scanning a repository's index for dirty files. The
`Index` class (`src/index.h`) encapsulates this:

```cpp
namespace gitstatus {

class Index {
 public:
  Index(git_repository* repo, git_index* index);
  // Returns the list of paths that *might* be dirty and need a closer look.
  std::vector<const char*> GetDirtyCandidates(const ScanOpts& opts);
 private:
  size_t InitDirs(git_index* index);
  void   InitSplits(size_t total_weight);
  Arena arena_;
  WithArena<std::vector<IndexDir*>> dirs_;
  WithArena<std::vector<size_t>> splits_;
  git_index* git_index_;
  const char* root_dir_;
  RepoCaps caps_;
};

}  // namespace gitstatus
```

Key design elements:

- **Arena allocation.** `Arena` (`arena.cc`) provides bump-pointer allocation with no
  per-object frees, eliminating allocator churn during a scan. `IndexDir` holds its own
  `Arena`, and `WithArena<>` ties STL containers to arena storage.
- **Directory splitting for parallelism.** `InitDirs` builds a tree of `IndexDir` entries;
  `InitSplits` partitions the work by weight so the thread pool (`thread_pool.cc`) can
  scan disjoint subtrees concurrently.
- **Capability probing.** `RepoCaps` records filesystem facts (`trust_filemode`,
  `has_symlinks`, `case_sensitive`, `precompose_unicode`) so the scanner compares
  index entries against the working tree correctly per platform.
- **mtime fast path.** `check_dir_mtime.cc` uses directory modification times to skip
  subtrees that provably haven't changed since the last scan — the primary reason the
  daemon stays fast on warm repositories.
- **Candidate-then-confirm.** `GetDirtyCandidates` deliberately returns files that *might*
  be dirty; a cheaper first pass narrows the set, and a precise check confirms — avoiding
  full-tree diffs on every prompt.

> [!NOTE]
> Building `gitstatusd` from source is only needed for unsupported platforms. Use
> `gitstatus/build` (or `mbuild` for multi-target) — both vendor and statically link
> libgit2 to keep the daemon dependency-free at runtime. Most users get a prebuilt binary
> via `gitstatus/install`.

---

## 8. Configuration Reference

All configuration is expressed as `POWERLEVEL9K_*` shell parameters, conventionally set in
`~/.p10k.zsh` (which `~/.zshrc` sources). The wizard writes this file; you can hand-edit
it freely. The parameter namespace is large; below are the operationally significant ones.
For per-segment colors and icons, the pattern is
`POWERLEVEL9K_<SEGMENT>[_<STATE>]_{FOREGROUND,BACKGROUND,VISUAL_IDENTIFIER_EXPANSION,CONTENT_EXPANSION}`.

### Structural parameters

| Parameter | Purpose |
|-----------|---------|
| `POWERLEVEL9K_LEFT_PROMPT_ELEMENTS` | array of segments shown on the left |
| `POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS` | array of segments shown on the right |
| `POWERLEVEL9K_MODE` | icon set selection (see table below) |
| `POWERLEVEL9K_ICON_PADDING` | spacing around icons (`none`, `moderate`, …) |
| `POWERLEVEL9K_LEGACY_ICON_SPACING` | `true` to mimic Powerlevel9k icon spacing |
| `POWERLEVEL9K_PROMPT_ADD_NEWLINE` | blank line before each prompt |
| `POWERLEVEL9K_MULTILINE_*_PROMPT_{PREFIX,SUFFIX,GAP_CHAR}` | frame/connector characters for multi-line prompts |
| `POWERLEVEL9K_SHOW_RULER` / `POWERLEVEL9K_RULER_CHAR` | horizontal ruler line |
| `POWERLEVEL9K_INSTALLATION_DIR` | override theme location (advanced) |
| `POWERLEVEL9K_CONFIG_FILE` | override the config path (default `${ZDOTDIR:-~}/.p10k.zsh`) |

### `POWERLEVEL9K_MODE` values

The icon mode selects which glyph table `internal/icons.zsh` loads:

| Value | Use |
|-------|-----|
| `nerdfont-v3` | Nerd Fonts v3 codepoints (recommended for current Nerd Fonts) |
| `nerdfont-complete` / `nerdfont-fontconfig` | older Nerd Fonts layouts |
| `awesome-fontconfig` (default) / `awesome-patched` / `flat` | Awesome Terminal Fonts variants |
| `powerline` | Powerline glyphs only |
| `compatible` | a conservative set that renders in most fonts |
| `ascii` | pure ASCII; auto-selected when no UTF-8 locale is present |

> [!NOTE]
> If `POWERLEVEL9K_MODE` is unset and the locale codeset isn't UTF-8, the engine forces
> `ascii` automatically. Setting `POWERLEVEL9K_MODE` **before** sourcing the theme is
> honored by Powerlevel10k (unlike Powerlevel9k) — a common cause of "different icons
> after migration".

### Behavioral parameters

| Parameter | Purpose |
|-----------|---------|
| `POWERLEVEL9K_INSTANT_PROMPT` | `verbose` (default) / `quiet` / `off` |
| `POWERLEVEL9K_DISABLE_HOT_RELOAD` | `false` to apply live `POWERLEVEL9K_*` edits without `p10k reload` |
| `POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD` | `true` to suppress auto-launch of the wizard |
| `POWERLEVEL9K_TERM_SHELL_INTEGRATION` | `true` to enable terminal shell integration (kitty resize fix) |
| `POWERLEVEL9K_<SEG>_SHOW_ON_COMMAND` | regex of commands that reveal a segment |

### VCS / Git parameters

| Parameter | Purpose |
|-----------|---------|
| `POWERLEVEL9K_VCS_BACKENDS` | enabled VCS backends; default `(git)` — `svn`/`hg` are supported but slow |
| `POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS` | grace period before status goes async (default 0.01) |
| `POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN` | glob of workdirs to skip (default `~`) |
| `POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY` | index-size threshold before dirty counts are reported as unknown (`─`) |
| `POWERLEVEL9K_VCS_LOADING_BACKGROUND` | background color while status is being computed (Rainbow) |
| `my_git_formatter` (function) | user-editable function in `~/.p10k.zsh` that formats the Git string |

### Powerline / Zsh interaction parameters

| Parameter | Purpose |
|-----------|---------|
| `ZLE_RPROMPT_INDENT` | Zsh parameter; set `0` to flush right prompt to the screen edge |
| `POWERLEVEL9K_DIR_*` | directory-segment colors/anchors (`_BACKGROUND`, `_FOREGROUND`, `_SHORTENED_FOREGROUND`, `_ANCHOR_FOREGROUND`, `_ANCHOR_BOLD`) |
| `POWERLEVEL9K_CONTEXT_*` | `user@hostname` segment formatting |

---

## 9. Instant Prompt Internals

Instant prompt is what lets the prompt appear before `~/.zshrc` finishes. Mechanically:

1. On a prior successful run, the engine writes a per-user
   `${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-<user>.zsh` containing a
   serialized snapshot of the prompt.
2. The snippet near the top of `~/.zshrc` sources that file if present, printing the
   cached prompt immediately.
3. While instant prompt is active, stdin is redirected to `/dev/null` and stdout/stderr
   are buffered to a temp file. After Zsh finishes initializing, file descriptors are
   restored and buffered output is flushed.
4. `p10k finalize` (which must be the very last line of `~/.zshrc`) completes the
   transition by restoring `prompt_cr`/`prompt_sp`.

> [!WARNING]
> Because stdin is redirected to `/dev/null` during init, any `~/.zshrc` code that reads
> from the console (password prompts, `[y/n]`) must be placed **above** the instant-prompt
> block, or it will silently fail. `POWERLEVEL9K_INSTANT_PROMPT=verbose` (the default)
> prints a warning when it detects console output during init to surface such problems.

The dump cache (`p10k-dump-<user>.zsh`) is a related but distinct optimization: it
serializes computed engine state (icon tables, parsed config) so subsequent loads skip
recomputation. Both caches and the `.zwc` bytecode files live alongside the install or in
the cache dir, and are all safe to delete — they regenerate automatically.

---

## 10. Deployment & Operations

### Single-user (typical)

Source the theme from `~/.zshrc` and let it manage everything. The engine self-compiles
to `.zwc`, downloads `gitstatusd` on first `vcs` use, and writes caches to
`${XDG_CACHE_HOME:-$HOME/.cache}`.

### System-wide / packaged

Distribute via the OS package (`brew`, AUR `zsh-theme-powerlevel10k-git`, Alpine
`zsh-theme-powerlevel10k`) and source from a system `zshrc` or each user's `~/.zshrc`.

> [!CAUTION]
> The project explicitly states it is **not currently easy or recommended** to package
> and redistribute Powerlevel10k yourself, because there's no supported upgrade path for
> custom packages. Prefer the official packages where they exist.

In a read-only install location, `.zwc` compilation is skipped (slower first load,
correct behavior). Per-user caches still work because they live under the user's home.

### Air-gapped / offline

`gitstatusd` is the only component that touches the network, and only once. To pre-stage
it (see also the User Guide):

```sh
# On the offline host, identify the platform:
uname -sm | tr '[A-Z]' '[a-z]'        # e.g. "linux x86_64"

# On a connected host, fetch the matching binary into the clone:
target_uname="linux x86_64"
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k
GITSTATUS_CACHE_DIR="$HOME"/powerlevel10k/gitstatus/usrbin \
  ~/powerlevel10k/gitstatus/install -f -s "${target_uname% *}" -m "${target_uname#* }"
```

Then copy the tree to the offline host. Set `GITSTATUS_AUTO_INSTALL=0` to be certain no
download is attempted at runtime.

### Diagnostics

```zsh
# Is gitstatusd running for this shell?
gitstatus_check && echo "daemon up (pid $GITSTATUS_DAEMON_PID)"

# Enable daemon logging for one shell:
GITSTATUS_LOG_LEVEL=DEBUG exec zsh
# ...then inspect the file pointed to by $GITSTATUS_DAEMON_LOG

# Verify the theme loaded and its version:
typeset -p P9K_VERSION

# Start Zsh without the wizard, to reveal hidden ~/.zshrc errors:
POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true zsh
```

### Cache locations (safe to delete)

```zsh
rm -rf -- "${XDG_CACHE_HOME:-$HOME/.cache}"/p10k-*(N) \
          "${XDG_CACHE_HOME:-$HOME/.cache}"/gitstatus
# plus *.zwc files next to the engine sources, if writable
```

---

## 11. Security Analysis

Powerlevel10k runs entirely within the user's interactive shell with that user's
privileges. It does not require, request, or use elevated privileges.

| Area | Assessment |
|------|------------|
| **Network** | No runtime network activity except a **one-time** download of the `gitstatusd` binary on first `vcs` use, from the gitstatus release host. Disable with `GITSTATUS_AUTO_INSTALL=0`; pre-stage for air-gapped hosts. |
| **Binary provenance** | The downloaded `gitstatusd` is a prebuilt binary. Security-sensitive deployments should pre-build from `gitstatus/src` (`gitstatus/build`) and ship a known-good binary in `gitstatus/usrbin`, with `GITSTATUS_AUTO_INSTALL=0`. |
| **Process isolation** | Background helpers (`gitstatusd`, helper `zsh`) are **not shared** across interactive shells and are launched with `--parent-pid="$$"`, so they terminate when the parent shell exits or `exec`s. This avoids cross-session leakage. |
| **Code execution** | `~/.p10k.zsh` is executed as shell code on every shell start — treat it as trusted config. Custom `CONTENT_EXPANSION`/segment functions run with the user's privileges; only the `-e` form of `p10k segment` performs parameter/process expansion (documented as advanced). |
| **Untrusted repositories** | Status is computed via libgit2 reads; the daemon does not execute repository hooks. However, libgit2 itself is the trust boundary for parsing repository data — keep the bundled libgit2 current by updating Powerlevel10k. |
| **Privilege display** | The `context` segment is shown by default under `sudo`/SSH precisely to make privilege escalation visible. |
| **Secrets** | The theme reads environment/tooling state for display (e.g. cloud profile *names*, kube context). It does not read credential *values*. Be mindful that segment content is rendered to the terminal and may end up in screen recordings. |

> [!IMPORTANT]
> The single most important hardening step for a sensitive environment is to **pin the
> `gitstatusd` binary**: build it from source, place it in `gitstatus/usrbin`, and set
> `GITSTATUS_AUTO_INSTALL=0` so no binary is ever fetched at runtime.

---

## 12. Performance Engineering

Performance is the project's central design constraint. The techniques that make it fast:

- **Asynchronous Git status.** The expensive operation never blocks the prompt
  (see [Architecture](#2-architecture)).
- **Long-lived daemon.** `gitstatusd` keeps repositories open (`repo_cache`) and reuses
  libgit2 handles instead of re-opening per query. The `-r`/`--repo-ttl-seconds` flag
  bounds memory by closing idle repos.
- **mtime-pruned scanning.** Subtrees with unchanged directory mtimes are skipped
  (`check_dir_mtime.cc`).
- **Arena allocation + thread pool.** Index scanning uses bump allocation and parallel
  subtree scanning. The default thread count is derived from CPU count:

  ```text
  threads = (cpus > 16) ? 32 : (cpus > 0) ? 2 * cpus : 16
  ```

  Override with `GITSTATUS_NUM_THREADS`.
- **Count caps.** `--max-num-{staged,unstaged,conflicted,untracked}` (the `-s/-u/-c/-d`
  flags) stop counting early; `--dirty-max-index-size` (`-m`) skips dirty scanning
  entirely for huge indexes, reporting `-1`/`─`.
- **Bytecode + dump cache.** The engine compiles to `.zwc` and serializes computed state,
  cutting per-shell startup cost.
- **No forks on the hot path.** The engine avoids spawning external commands while
  rendering; helper work is offloaded to a persistent background `zsh`
  (`internal/worker.zsh`).

> [!TIP]
> If you operate on enormous monorepos and see `─` in place of counts, that's the
> `--dirty-max-index-size` guard. Raise `POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY` (and/or
> the daemon `-m` value) if you want exact counts at the cost of more scanning.

---

## 13. Code Patterns & Conventions

Observed throughout the engine source:

- **Hermetic option environment.** Every public engine function begins by evaluating the
  `__p9k_intro` preamble (`emulate -L zsh -o …`), so behavior is independent of the
  user's interactive options. This is essential for a theme that must run inside arbitrary
  user configurations.
- **`__p9k_` / `_p9k_` namespacing.** Globals use `__p9k_`; internal functions and
  transient state use `_p9k_`. The teardown trap (`unset -m _p9k__\*`) bulk-clears
  transient state.
- **Defensive quoting against plugin managers.** Idioms like spacing before `local` and
  `'builtin'`/`'setopt'` quoting exist specifically to survive aggressive plugin managers
  (e.g. Antigen) that rewrite sourced code.
- **Capability detection over assumptions.** Both layers probe the environment (locale,
  color depth, font glyphs, filesystem case sensitivity) rather than assume — the wizard
  hides styles whose glyphs won't render, and the C++ scanner adapts to `RepoCaps`.
- **Self-documenting usage strings.** The `p10k` command's help text
  (`__p9k_p10k_*_usage`) is embedded in the engine and surfaced via `p10k help <cmd>`.
- **C++: ownership via arenas + RAII scope guards.** `scope_guard.h` and arena ownership
  keep the hot path allocation-light and exception-safe.

### Extension surface for developers

| Hook / API | Use |
|------------|-----|
| `prompt_<name>()` + `p10k segment` | define a custom prompt segment |
| `p10k-on-init` | run once when the prompt initializes |
| `p10k-on-pre-prompt` | run before each prompt is drawn |
| `p10k-on-post-prompt` | run after each prompt is drawn |
| `p10k-on-post-widget` | run after each ZLE widget |
| `POWERLEVEL9K_<SEG>_CONTENT_EXPANSION` | rewrite a segment's content without code |

---

## 14. Standalone gitstatus Usage

The `gitstatus` subproject is usable on its own, without Powerlevel10k — handy for custom
prompts or scripts. Two ready-made prompts ship with it.

**Bash** (`gitstatus/gitstatus.prompt.sh`): sources `gitstatus.plugin.sh`, starts the
daemon with uncapped counts (`-s -1 -u -1 -c -1 -d -1`), and on every prompt sets
`GITSTATUS_PROMPT` (e.g. `master ⇡42`) for inclusion in `PS1`:

```bash
source ~/gitstatus/gitstatus.prompt.sh
# PS1 now includes ${GITSTATUS_PROMPT}; example:
#   user@host ~/projects/skynet master ⇡42
```

**Zsh** (`gitstatus/gitstatus.prompt.zsh`): the Zsh equivalent.

Programmatic use from a script:

```bash
source ~/gitstatus/gitstatus.plugin.sh
gitstatus_start                       # start the daemon (idempotent)
gitstatus_query -d /path/to/repo      # populate VCS_STATUS_* for that dir
if [[ "$VCS_STATUS_RESULT" == ok-sync ]]; then
  echo "branch: $VCS_STATUS_LOCAL_BRANCH  staged: $VCS_STATUS_NUM_STAGED"
fi
gitstatus_stop                        # tear down
```

> [!NOTE]
> The Bash bindings require **Bash ≥ 4.0** (`gitstatus_start` checks `$BASH_VERSION` and
> errors out otherwise).

---

## 15. Potential Improvements

These are observations for operators and contributors, not defects in normal use:

- **Binary trust by default.** First-run auto-download of `gitstatusd` is convenient but
  is a supply-chain consideration for hardened fleets. A documented, signed-binary
  verification step (beyond pre-building) would strengthen the offline-first story.
- **Packaging story.** The project itself notes that redistribution/packaging is not yet
  easy. A supported, upgrade-aware packaging path would help distros and enterprises.
- **Resize handling depends on the terminal.** The terminal-reflow prompt-corruption
  issue is fundamentally a terminal limitation; the kitty shell-integration mitigation
  (`POWERLEVEL9K_TERM_SHELL_INTEGRATION=true`) is the most robust fix and could be more
  broadly applicable as terminals adopt shell integration.
- **libgit2 coverage gaps.** Because status comes from libgit2, features it doesn't
  support (e.g. `skipHash`, possibly enabled implicitly by Git's `manyFiles`) can cause
  prompt/`git status` discrepancies. Tracking libgit2 upstream remains the mitigation.
- **VCS backends beyond git.** `svn`/`hg` are supported but unoptimized and slow; bringing
  them onto the async/daemon model would generalize the performance guarantee.

---

## 16. Quick Reference

### gitstatus binding cheat-sheet

```bash
gitstatus_start [-t SEC] [-s N] [-u N] [-c N] [-d N] [-m N] [-r SEC] [-e] [-U] [-W] [-D]
gitstatus_query [-d DIR] [-t SEC] [-p]
gitstatus_stop
gitstatus_check
```

### Daemon-controlling environment variables

| Variable | Default | Effect |
|----------|---------|--------|
| `GITSTATUS_NUM_THREADS` | CPU-derived | worker threads |
| `GITSTATUS_CACHE_DIR` | `~/.cache/gitstatus` | binary cache location |
| `GITSTATUS_AUTO_INSTALL` | `1` | `0` disables binary download |
| `GITSTATUS_LOG_LEVEL` | unset | daemon log level |
| `GITSTATUS_ENABLE_LOGGING` | `0` | `1` enables INFO logging |

### `p10k` commands

| Command | Purpose |
|---------|---------|
| `p10k configure` | run the configuration wizard |
| `p10k reload` | reload configuration |
| `p10k segment ...` | emit a user-defined segment (during render) |
| `p10k display PART=STATE` | show/hide/toggle prompt parts |
| `p10k help [command]` | usage help |
| `p10k finalize` | final init stage (last line of `~/.zshrc`) |

### Key paths

| Path | Role |
|------|------|
| `powerlevel10k.zsh-theme` | loader |
| `internal/p10k.zsh` | engine |
| `internal/icons.zsh` | icon tables by `POWERLEVEL9K_MODE` |
| `gitstatus/gitstatus.plugin.zsh` | daemon bindings |
| `gitstatus/src/` | C++ daemon source |
| `~/.p10k.zsh` | user configuration |
| `${XDG_CACHE_HOME:-~/.cache}/p10k-*` | dump / instant-prompt caches |
| `${XDG_CACHE_HOME:-~/.cache}/gitstatus` | downloaded daemon binary |

---

_Generated June 2026 from romkatv/powerlevel10k at a0c9dbe. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
