Skip to content

πŸ—οΈ ZSHAND ArchitectureΒΆ

🎯 This document describes how the framework is structured, how it boots, how bundles work, and how user configuration integrates. Read this first if you're new to the codebase.

!!! abstract "🧠 Design Principles" - ⚑ Performance first β€” target <50ms cold start, <10ms warm - 🧩 Modular β€” every directory is independently compilable - πŸ”„ Override-friendly β€” users can replace any framework file - πŸ›‘οΈ Fail-safe β€” graceful degradation at every layer - πŸ“ Convention-driven β€” numbered prefixes enforce load order


πŸ“ Directory StructureΒΆ

zshand/
β”œβ”€β”€ 🎯 zshrc.zsh                 Entry point (sourced by ~/.zshrc)
β”œβ”€β”€ 🎯 setup.zsh                 First-time bootstrap & OS setup
β”œβ”€β”€ πŸ“¦ build/                    Build system & profiling tools
β”‚   β”œβ”€β”€ compile_full_bundle.zsh  Full bundle compiler
β”‚   β”œβ”€β”€ compile_profile_bundle.zsh  Profiling-instrumented compiler
β”‚   β”œβ”€β”€ profile_bundle_report.zsh   Performance report generator
β”‚   └── ...                      Benchmarking, optimization, loading
β”œβ”€β”€ βš™οΈ core/                     Framework core (numbered 02–90)
β”‚   β”œβ”€β”€ 02_vars.zsh              Variables & identity (FIRST loaded)
β”‚   β”œβ”€β”€ 04_path.zsh              PATH construction
β”‚   β”œβ”€β”€ 06_engine.zsh            Execution engine (zprime, zrun)
β”‚   β”œβ”€β”€ 08_audit.zsh             System integrity & telemetry
β”‚   β”œβ”€β”€ 10_options.zsh           Zsh options (setopt)
β”‚   β”œβ”€β”€ 12_completions.zsh       Completion system
β”‚   β”œβ”€β”€ 14_aliases.zsh           Shell aliases
β”‚   β”œβ”€β”€ 16_widgets.zsh           ZLE widget registration
β”‚   β”œβ”€β”€ 18_hooks.zsh             Hook classification & loading
β”‚   β”œβ”€β”€ 20_plugins.zsh           Plugin management
β”‚   └── 90_functions.zsh         Function autoloading
β”œβ”€β”€ 🧱 shared_functions/         Low-level utilities (01–18)
β”‚   β”œβ”€β”€ 01_stderr_error.zsh      Error output to stderr
β”‚   β”œβ”€β”€ 06_time_millis.zsh       Millisecond timing
β”‚   β”œβ”€β”€ 11_source_with_zwc.zsh   Bytecode-aware sourcing
β”‚   β”œβ”€β”€ 15_load_file_timed.zsh   Timed file loading with budget
β”‚   β”œβ”€β”€ 16_zrun.zsh              Telemetry logging
β”‚   β”œβ”€β”€ 17_clipboard_copy.zsh    Wayland clipboard abstraction
β”‚   └── ...                      Assertions, debug helpers, cache
β”œβ”€β”€ πŸš€ startup/                  Early startup scripts (05–28)
β”‚   β”œβ”€β”€ 05_az_dev_mode_check.zsh Auto-rebuild in dev mode
β”‚   β”œβ”€β”€ 21_az_health_validate_tools.zsh  Dependency validation
β”‚   β”œβ”€β”€ 24_az_safe_mode.zsh      Emergency recovery
β”‚   └── ...                      TOML config, keybindings, profiling
β”œβ”€β”€ πŸ› οΈ functions/                User-facing shell functions
β”‚   β”œβ”€β”€ dcopy.zsh                Copy directory path to clipboard
β”‚   β”œβ”€β”€ zopt.zsh                 Zsh option management
β”‚   └── ...                      ~25 utility functions
β”œβ”€β”€ ⌨️ widgets/                   ZLE widgets (keybinding-driven)
β”‚   β”œβ”€β”€ aicmit.zsh              AI-assisted git commit
β”‚   β”œβ”€β”€ aidebug.zsh             AI debugging assistant
β”‚   └── ...                      ~20 interactive widgets
β”œβ”€β”€ πŸͺ¨ hooks/                    Tool integration hooks (01–81)
β”‚   β”œβ”€β”€ 01_mise.zsh             Polyglot runtime manager
β”‚   β”œβ”€β”€ 02_atuin.zsh            Shell history sync
β”‚   β”œβ”€β”€ 05_ssh-agent.zsh        SSH agent management
β”‚   └── ...                      Docker, zoxide, git identity
β”œβ”€β”€ πŸ“Ÿ bin/                      Executable CLI tools (on $PATH)
β”‚   β”œβ”€β”€ aicontext                AI context generator
β”‚   β”œβ”€β”€ zr                       Framework rebuild shortcut
β”‚   └── ...                      ~30 standalone scripts
β”œβ”€β”€ πŸ” private_functions/        Internal framework functions
β”œβ”€β”€ πŸ“š lib/                      Library support modules
β”‚   └── rebuild/                 Incremental rebuild logic
β”œβ”€β”€ βš™οΈ config/                   Framework-level configuration
β”‚   └── profile-exceptions.conf  Performance exception rules
β”œβ”€β”€ πŸ“₯ installers/               OS-specific system installers
β”œβ”€β”€ πŸ§ͺ tests/                    ShellSpec test suites
β”œβ”€β”€ πŸ“– docs/                     Documentation (this file lives here)
└── πŸ“‚ samples/                  Example user config templates

πŸ“ Numbering ConventionΒΆ

Files are numbered with 2-digit prefixes to enforce deterministic load order:

Range Purpose Example
01–09 🧱 Foundation / bootstrap 02_vars.zsh, 01_mise.zsh
10–19 βš™οΈ Core configuration 10_options.zsh, 14_aliases.zsh
20–29 πŸ”Œ Plugins & integrations 20_plugins.zsh, 20_docker.zsh
30–49 πŸ› οΈ Mid-priority tools 30_zoxide.zsh
50–79 πŸ“¦ Optional / less critical 50_gitid.zsh
80–89 🧹 Cleanup & maintenance 80_archclean.zsh
90–99 🏁 Late-stage / finalization 90_functions.zsh

πŸ’¬ Even numbers are used by the framework. Odd numbers are reserved for user insertion (e.g., user can place 03_my_vars.zsh in rc.d/).


πŸš€ Boot SequenceΒΆ

The boot process is orchestrated by zshrc.zsh and follows a strict phase order. Multiple loading strategies exist depending on the mode:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    zshrc.zsh Entry Point                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  0. 🚫 Non-interactive check (early exit for scripts/cron)     β”‚
β”‚  1. πŸ“ Path & cache initialization                             β”‚
β”‚  2. πŸ”€ Loading strategy selection (see below)                  β”‚
β”‚  3. 🎨 P10k instant prompt (zero-latency visual)               β”‚
β”‚  4. πŸ›‘οΈ Safe mode check (emergency recovery)                    β”‚
β”‚  5. βœ… Health validation (system dependencies)                  β”‚
β”‚  6. βš™οΈ Core config loading (02β†’04β†’06β†’08β†’...β†’90)                β”‚
β”‚  7. πŸͺ¨ Hook integration (critical sync, then lazy/deferred)    β”‚
β”‚  8. πŸ” Staleness check & auto-recompile                        β”‚
β”‚  9. πŸ‘€ User post.d/ scripts                                    β”‚
β”‚ 10. πŸ“Š Debug summary & cleanup                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”€ Loading StrategiesΒΆ

The framework picks the fastest available strategy at boot:

Priority Strategy Trigger Speed Use Case
1️⃣ Profile Bundle ZSHAND_PROFILE_BUNDLE=1 ~100ms Performance analysis
2️⃣ Full Bundle (fast path) ZSHAND_AUTO_FULL=1 + bundle exists ⚑ <50ms Production (fastest)
3️⃣ Full Bundle (auto-compile) ZSHAND_AUTO_FULL=1 + no bundle ~200ms first, then ⚑ First run
4️⃣ Monolithic Bundle ZSHAND_USE_MONOLITHIC=1 ~60ms Framework-only bundle
5️⃣ Hybrid Production default ~80ms Pre-compiled per-dir bundles
6️⃣ Individual Files ZSHAND_DEV_MODE=1 or fallback ~200ms Development / debugging

Which mode am I in?

Check echo $ZSHAND_DEV_MODE and echo $ZSHAND_AUTO_FULL. In production, the fast path loads a single .zsh file from cache β€” everything in one read.


πŸ“¦ Bundle SystemΒΆ

Bundles are the core performance optimization. The build system concatenates framework + user files into a single source file, then zcompiles it to .zwc bytecode for instant loading.

πŸ“Š Bundle TypesΒΆ

Bundle File Contains Built By
πŸ—οΈ Full zshand-full.zsh / .zwc Framework + user config compile_full_bundle.zsh
πŸ“Š Profile zshand-profile.zsh / .zwc Full + timing instrumentation compile_profile_bundle.zsh
πŸ“‚ Per-directory <dir>/.compiled/<dir>-all.zsh Single directory contents compile_single_directory.zsh

πŸ”„ Bundle Compilation FlowΒΆ

Source Files  ──→  Merge (user overrides)  ──→  Concatenate  ──→  .zsh  ──→  zcompile  ──→  .zwc
                         ↑                                                        β”‚
              User config dir files                                    Bytecode (instant load)
              override framework files
              with same basename

⚑ Compilation Commands¢

Command What It Does
zprime Compile all directories + reload shell
zprime --quiet / zrq Background compilation (no output)
zprime --full / zfull Compile full bundle
zprime-dir <dir> Rebuild single directory
zr Alias for zprime (convenience)

Bundle staleness

Bundles are checked for staleness at boot. If source files are newer than the compiled bundle, you'll see a warning. Run zprime to rebuild.


πŸ”„ Override SystemΒΆ

Users can override any framework file by placing a file with the same basename in their config directory. The merge resolution is:

Framework: $ZSHAND/core/14_aliases.zsh
User:      $ZSHAND_CONFIG_DIR/rc.d/14_aliases.zsh   ← wins (replaces framework)

πŸ“ User Config DirectoryΒΆ

~/.config/zshand/                   ($ZSHAND_CONFIG_DIR)
β”œβ”€β”€ env.zsh           🌍 Environment variables (auto-exported)
β”œβ”€β”€ secrets.zsh       πŸ”’ API keys and tokens (chmod 600)
β”œβ”€β”€ aliases.zsh       πŸ“ Custom aliases
β”œβ”€β”€ path.txt          πŸ›€οΈ Additional PATH entries (one per line)
β”œβ”€β”€ config.toml       βš™οΈ Framework behavior settings
β”œβ”€β”€ bin/              πŸ“Ÿ Personal scripts (added to $PATH)
β”œβ”€β”€ functions/        πŸ› οΈ Custom functions (override or extend)
β”œβ”€β”€ widgets/          ⌨️ Custom ZLE widgets
β”œβ”€β”€ hooks/            πŸͺ¨ Custom integration hooks
β”œβ”€β”€ rc.d/             βš™οΈ Core config overrides (same numbering as core/)
β”œβ”€β”€ init.d/           πŸš€ Pre-initialization (before framework loads)
└── post.d/           🏁 Post-initialization (after everything)

πŸ“Š User File Load OrderΒΆ

1. init.d/*.zsh          Before framework (early overrides)
2. env.zsh + secrets.zsh Environment variables
3. path.txt + bin/       PATH configuration
4. Framework core (merged with rc.d/ overrides)
5. Framework hooks, functions, widgets
6. User hooks/, functions/, widgets/
7. aliases.zsh           Custom aliases (can override framework)
8. post.d/*.zsh          Final tweaks

βš™οΈ Key SubsystemsΒΆ

πŸ”§ Engine (core/06_engine.zsh)ΒΆ

The engine is the largest and most critical core module. It provides:

  • zprime β€” Framework compilation and shell reload
  • zrun β€” Telemetry-aware command execution wrapper
  • _z_system_init β€” System initialization (Atuin, security, terminal title)
  • Incremental rebuilds β€” Only recompile changed directories
  • Completion generation β€” Atomic completion for external tools

🧱 Shared Functions (shared_functions/)¢

These are the lowest-level building blocks, loaded before everything else. They provide the primitives that all other code depends on:

Function Purpose
stderr_error / stderr_warn Colored error/warning output
echo_info / echo_ok Status messages
time_millis Millisecond-precision timing
assert_dir_exists / assert_file_exists / assert_function_exists Guard assertions
source_with_zwc Bytecode-aware file sourcing
load_file_timed Source file with timing + performance budget
_zrun Low-level telemetry logging
clipboard_copy / clipboard_paste Wayland clipboard abstraction

πŸ›‘οΈ Safe Mode (startup/24_az_safe_mode.zsh)ΒΆ

Emergency recovery when the framework fails to initialize:

  • Triggered by ZSHAND_SAFE_MODE=1 exec zsh or auto-detected via failure count
  • Provides minimal shell with basic PATH and no framework
  • Recovery menu for diagnostics and repair

πŸ“Š Profiling PipelineΒΆ

ZSHAND_PROFILE_BUNDLE=1 exec zsh     ← Start profiled shell
      β”‚
      β–Ό
compile_profile_bundle.zsh            ← Builds instrumented bundle
      β”‚
      β–Ό
profile-timing.log                    ← Raw timing data (TYPE|NAME|START|END)
      β”‚
      β–Ό
profile_bundle_report.zsh            ← Generates graded performance report
      β”‚
      β–Ό
Terminal output with grades A–F       ← Human-readable with bar charts

πŸͺ¨ Hook ClassificationΒΆ

Hooks are classified by core/18_hooks.zsh into two categories:

Type Loading Purpose Examples
⚑ Critical Synchronous (immediate) Must be ready at first prompt 01_mise, 02_atuin, 05_ssh-agent
πŸ• Lazy Deferred (1s delay) or sync Can wait until after prompt 20_docker, 30_zoxide, 50_gitid

When ZSHAND_LAZY_LOAD=1, non-critical hooks load in a background subshell after a 1-second delay, keeping the prompt responsive.


πŸ§ͺ Testing ArchitectureΒΆ

tests/
β”œβ”€β”€ run_all.zsh              Master test runner
β”œβ”€β”€ bootstrap_env.zsh        Test environment setup
β”œβ”€β”€ bin/                     bin/* tool tests
β”œβ”€β”€ build/                   Build system tests
β”œβ”€β”€ core/                    Core module tests
└── dependencies/            Dependency validation tests
  • Framework: ShellSpec (BDD-style Describe/It blocks)
  • Coverage: Kcov via CI
  • Runner: just test or just test spec/path/
  • Spec mirroring: functions/dcopy.zsh β†’ spec/functions/dcopy_spec.sh

🌍 Environment Variables¢

πŸŽ›οΈ Framework ControlsΒΆ

Variable Type Default Purpose
ZSHAND string auto-detected Framework root directory
ZSHAND_CONFIG_DIR string $XDG_CONFIG_HOME/zshand User config directory
ZSHAND_CACHE_DIR string $XDG_CACHE_HOME/zshand Cache & compiled bundles
ZSHAND_LOG_DIR string $HOME/logs/zshand Log file directory
ZSHAND_DEV_MODE bool 0 Enable development mode
ZSHAND_AUTO_FULL bool 0 Auto-compile full bundle
ZSHAND_DEBUG bool 0 Verbose debug output
ZSHAND_PROFILE_BUNDLE bool 0 Enable profiling
ZSHAND_LAZY_LOAD bool 0 Defer non-critical hooks
ZSHAND_SAFE_MODE bool 0 Emergency recovery mode
ZSHAND_AUDIT_MODE bool 0 Full audit (recompile + test)
ZSHAND_PERF_BUDGET int 100 Max ms per file before warning

πŸ”‘ XDG ComplianceΒΆ

The framework follows the XDG Base Directory Specification:

XDG Variable ZSHAND Maps To Default
XDG_CONFIG_HOME ZSHAND_CONFIG_DIR ~/.config/zshand
XDG_CACHE_HOME ZSHAND_CACHE_DIR ~/.cache/zshand
XDG_DATA_HOME β€” (not currently used)

πŸ“ Dependency GraphΒΆ

zshrc.zsh
  β”œβ”€β”€ shared_functions/*    (loaded FIRST β€” primitives for everything)
  β”œβ”€β”€ startup/*             (loaded with shared_functions, alphabetically merged)
  β”œβ”€β”€ build/detect_dev_mode.zsh  (if not using bundle)
  β”œβ”€β”€ core/02_vars.zsh      ← no deps (self-sufficient bootstrap)
  β”‚   └── core/04_path.zsh  ← depends on 02_vars (ZSHAND, config paths)
  β”‚       └── core/06_engine.zsh  ← depends on 02, 04 (paths, vars)
  β”‚           └── core/08_audit.zsh  ← depends on 02, 06 (LOG_DIR, _zrun)
  β”‚               └── core/10_options.zsh β†’ 12 β†’ 14 β†’ 16 β†’ 18 β†’ 20 β†’ 90
  β”œβ”€β”€ hooks/*               (after core; classified by 18_hooks.zsh)
  β”œβ”€β”€ P10k theme            (after bundles, before user config)
  └── post.d/*              (last β€” user final overrides)

Circular dependency prevention

shared_functions/ and startup/ are loaded before any core/ files. Core files load in strict numeric order. No file may depend on a higher-numbered file in the same directory.


Document Purpose
πŸ“ HEADER_STANDARD.md Documentation header conventions
πŸ“– README.md Project overview and quick start
πŸ—οΈ build/README.md Build system documentation
πŸ“‚ samples/user-config/README.md Example user configuration