Advanced / Debugging
When things go wrong, or you want to see what's happening under the hood.
Tracing
Hash has a comprehensive tracing system for debugging. Events are written to JSONL files.
Environment variables
| Variable | Values | Default |
|---|---|---|
HASH_TRACE | editor, agent, shell, parser, or all | (disabled) |
HASH_TRACE_PATH | File path for trace output | hash-trace.jsonl |
HASH_TRACE_LEVEL | verbose, detailed, high | verbose |
Example: Enable tracing
export HASH_TRACE_PATH=/tmp/hash-trace.jsonl
export HASH_TRACE_LEVEL=detailed
hash
After your session, examine the trace:
Trace output format
Each line is a JSON object with:
timestamp— RFC3339Nano formatdelta_ms— Time since last event in same subsystemsubsystem— Which component emitted the eventlevel— Verbosity levelevent— Event namedata— Event-specific data
PTY tracing
For debugging issues with interactive commands (programs that use the terminal directly), Hash has a separate PTY tracing system.
| Variable | Values | Default |
|---|---|---|
HASH_PTY_TRACE | 1 to enable | (disabled) |
HASH_PTY_TRACE_PATH | File path for PTY trace | hash-pty-trace.log |
Example: Debug a hanging command
export HASH_PTY_TRACE_PATH=/tmp/pty-debug.log
hash
PTY traces capture:
- I/O timestamps for stdin, stdout, PTY read/write
- Terminal drain operations (escape sequence cleanup)
- Stalled I/O detection
- Process termination reasons
Login vs interactive mode
Hash follows traditional shell conventions for startup files:
| Mode | How to invoke | Files sourced |
|---|---|---|
| Login | hash -l or via /etc/passwd | /etc/profile, ~/.profile, ~/.hash_profile, then ~/.hashrc |
| Interactive | hash (normal invocation) | ~/.hashrc |
| Non-interactive | hash -c "command" | init_commands only |
Startup file dialect
Startup files are parsed with the configured shell.dialect (bash by default). With dialect = "zsh" you can point [shell.startup_files] at your zsh files (~/.zprofile, ~/.zshrc) and Hash sources them with experimental zsh parsing. See the Configuration Reference.
Environment markers
Hash sets these variables so scripts can detect the shell mode:
HASH_SHELL=1— Always setHASH_LOGIN=1— Set in login modeHASH_INTERACTIVE=1— Set in interactive mode
Shell identity
Hash identifies itself differently from bash/zsh:
$0is set tohash$SHELLis set to the hash binary path (in login mode)$HASH_SHELL=1is always set as a detection marker
Builtins
Hash provides these built-in commands:
| Command | Description |
|---|---|
cd [dir] | Change directory (supports ~ expansion) |
exit / quit | Exit the shell |
history | Show recent commands |
copy | Copy commands or output to clipboard |
status | Show system status (agent, history, etc.) |
tips | Show helpful tips about Hash features |
issue | Submit a GitHub issue with context |
source / . | Source shell setup files |
setup-zoxide | Configure zoxide integration automatically |
model | List or switch the agent model (ACP agents) |
Compatibility no-op builtins such as bindkey, setopt, and compdef also exist so common zsh setup files can be sourced without failing.
history subcommands
history search git # Search history for "git"
history failed # Show failed commands (non-zero exit)
history sudo # Show commands run with sudo
history asked # Show agent interactions
copy subcommands
copy out # Copy last output
copy all # Copy command + output
copy cmd 2 # Copy 2nd-to-last command
issue options
issue "title here" # Create issue with title
issue --last # Pre-fill with last command context
issue # Open editor with template
model subcommands
model Sonnet # Select directly by display name or value
model --list # Print available models; current marked with *
Available models come from the ACP agent itself, and the choice persists for the current shell session. See Agents for details.
Disabling builtins
Some tools like zoxide or eza replace standard commands. Disable builtins only when an external tool must replace a builtin command (for example, alias cd="z"):
disable_builtins = ["cd"] # Example: when using alias cd="z"
For complete setup guides including directory change hooks, see Integrations.