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

VariableValuesDefault
HASH_TRACEeditor, agent, shell, parser, or all(disabled)
HASH_TRACE_PATHFile path for trace outputhash-trace.jsonl
HASH_TRACE_LEVELverbose, detailed, highverbose

Example: Enable tracing

export HASH_TRACE=all
export HASH_TRACE_PATH=/tmp/hash-trace.jsonl
export HASH_TRACE_LEVEL=detailed
hash

After your session, examine the trace:

cat /tmp/hash-trace.jsonl | jq .

Trace output format

Each line is a JSON object with:

  • timestamp — RFC3339Nano format
  • delta_ms — Time since last event in same subsystem
  • subsystem — Which component emitted the event
  • level — Verbosity level
  • event — Event name
  • data — Event-specific data

PTY tracing

For debugging issues with interactive commands (programs that use the terminal directly), Hash has a separate PTY tracing system.

VariableValuesDefault
HASH_PTY_TRACE1 to enable(disabled)
HASH_PTY_TRACE_PATHFile path for PTY tracehash-pty-trace.log

Example: Debug a hanging command

export HASH_PTY_TRACE=1
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:

ModeHow to invokeFiles sourced
Loginhash -l or via /etc/passwd/etc/profile, ~/.profile, ~/.hash_profile, then ~/.hashrc
Interactivehash (normal invocation)~/.hashrc
Non-interactivehash -c "command"init_commands only

Environment markers

Hash sets these variables so scripts can detect the shell mode:

  • HASH_SHELL=1 — Always set
  • HASH_LOGIN=1 — Set in login mode
  • HASH_INTERACTIVE=1 — Set in interactive mode

Shell identity

Hash identifies itself differently from bash/zsh:

  • $0 is set to hash
  • $SHELL is set to the hash binary path (in login mode)
  • $HASH_SHELL=1 is always set as a detection marker

Builtins

Hash provides these built-in commands:

CommandDescription
cd [dir]Change directory (supports ~ expansion)
exit / quitExit the shell
historyShow recent commands
copyCopy commands or output to clipboard
statusShow system status (agent, history, etc.)
tipsShow helpful tips about Hash features
issueSubmit a GitHub issue with context

history subcommands

history # Show recent 20 commands
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 cmd # Copy last command
copy out # Copy last output
copy all # Copy command + output
copy cmd 2 # Copy 2nd-to-last command

issue options

!! # Quick issue for last failure
issue "title here" # Create issue with title
issue --last # Pre-fill with last command context
issue # Open editor with template

Disabling builtins

Some tools like zoxide or eza replace standard commands. Disable builtins to let external tools take over:

config.toml
[shell]
disable_builtins = ["cd"]