Skip to content
ghostshell

Process tree and analyze

View a session as a structured process tree with exit codes and timings, then analyze it - optionally with a fully local Ollama AI summary.

Beyond the flat replay, a recorded session can be viewed as a structured process tree: which command ran which, nested by the shell that spawned it, with per-command exit status and timing.

Process tree

console
$ sudo ghostshell tree 20260711T142031-4471 bash (session root) ├─ npm install [exit 0, 12.4s] ├─ python migrate.py [exit 0, 0.8s] ├─ docker compose up [exit 0, 3.2s] └─ ./deploy.sh [exit 1, 5.9s] ├─ git pull [exit 0, 0.4s] └─ pytest [exit 1, 5.1s]

Add --json for tooling. (ghostshell tree with no argument prints the users-to-sessions store tree instead — see audit mode.)

Analyze

bash
sudo ghostshell analyze 20260711T142031-4471

analyze runs a deterministic pass over the tree — failures with the output they produced, retry loops, repeated/cacheable commands, slowest steps — and then, unless you pass --no-ai, hands the compact summary to a local model via Ollama for a plain-English review.

Flag Effect
--no-ai Deterministic report only
--model N Choose the Ollama model
--allow-remote Permit a non-loopback Ollama endpoint

It is fully offline by default: the endpoint must be loopback unless you pass --allow-remote, so session data — which can contain secrets — never leaves the machine. If Ollama is not installed, the deterministic report still prints; the AI pass is never a hard dependency.

What is and isn't traced — honestly

Note: The process tree is captured by a bash trace shim (DEBUG/EXIT traps), not by kernel-level process tracing. That means:

  • Interactive bash sessions are traced (the recorder launches the shell with --rcfile, which sources your real rc first).
  • Nested bash scripts (./deploy.sh with a #!/bin/bash shebang, bash script.sh, bash -c ...) are traced and nest under their parent, via BASH_ENV — that is how the deploy.sh → git pull, pytest nesting above is produced.
  • #!/bin/sh (dash) and non-bash shells (zsh, fish) are not structurally traced — sh has no DEBUG trap or BASH_ENV in the form the shim needs. Those sessions are still fully captured in the raw encrypted transcript (play/tail/search/export), just without a process tree. ghostshell tree <id> says so plainly.
  • Non-shell subprocesses (a Python or Node process spawning children via subprocess/child_process) are not expanded into the tree — that would need language-level instrumentation. Their output is still in the raw transcript.

A dropped span is always acceptable and never blocks the shell — the same fail-open principle as recording itself. Spans are encrypted at rest with the same key as the recordings.

Source of truth: README on GitHub