Trace your terminal sessions, annotate them inline, and generate structured summaries.
term-trace is a CLI tool that logs all commands and outputs from your zsh terminal sessions, allows inline notes, and summarizes activity into human-readable formats (in Google Docs and/or Markdown).
- 📝 Automatic session logging - Captures all commands, outputs, and exit codes in JSONL format
- 🤖 AI-powered summaries - Generate concise summaries using OpenAI, GitHub Models, or HuggingFace
- 📄 Multiple output formats - Export to Markdown files and/or Google Docs
- 🏢 Workspace organization - Group related sessions into workspaces
- 🔄 Live summarization - Summaries update in real-time as you work
- 💬 Inline notes - Add annotations directly from your terminal
- 🖥️ Interactive TUI viewer - Browse sessions with a tree-based interface, color-coded exit codes, and search
- Python 3.11 or higher
- macOS or Linux: supports zsh shell only
- Optional: API tokens for LLM providers (OpenAI, GitHub, or HuggingFace)
- Optional: Google OAuth credentials for Google Docs integration
$ git clone https://github.com/jaafar-chakrani/term-trace.git
$ cd term-trace
$ pip install -e .Copy .env.example to .env and customize:
cp .env.example .envThen edit .env:
# API Keys
OPENAI_API_KEY=sk-...
GITHUB_TOKEN=ghp_...
HUGGINGFACE_TOKEN=hf_...
# Google Docs integration
GOOGLE_CLIENT_SECRET=/path/to/credentials.json
# Custom settings
OPENAI_MODEL=gpt-4
TERMTRACE_BASE_DIR=/custom/pathThe .env file will be loaded automatically from:
- Current directory (
.env) ~/.termtrace/.env- Project root
- Go to Google Cloud Console
- Create a new project or select existing
- Enable the Google Docs API
- Create OAuth 2.0 credentials (Desktop app)
- Download the credentials JSON file
- Set
GOOGLE_CLIENT_SECRETto the file path
On first use, you'll be prompted to authorize the application in your browser.
$ term-trace start --workspace <workspace-name>This launches a new shell session where all commands are automatically logged.
Logging only (Markdown/Google Docs, no LLM summary):
$ term-trace start --workspace my-projectUse GitHub Models:
$ term-trace start --workspace my-project --llm githubUse HuggingFace models:
$ term-trace start --workspace my-project --llm huggingface$ term-trace start [OPTIONS]
Options:
--workspace TEXT Workspace name (required)
--session-name TEXT Custom session name (default: auto-generated timestamp)
--llm TEXT LLM provider for summarization
Choices: openai, gpt, github, huggingface, hf, markdown, none
Default: openai
--no-summarize Disable summarization (logging only)
-h, --help Show help messageWhile in a traced session, simply start a line with # to log a note:
$ # Starting database migration
$ psql -d mydb -f migration.sql
$ # Testing the new schema
$ psql -d mydb -c "SELECT * FROM users LIMIT 5"
$ # Migration completed successfullyNotes are automatically captured and included in both the session log and summaries.
All commands are logged to the full log section (Google Docs/Markdown) immediately as they are executed, regardless of summarization settings.
By default, automatic summarization (which generates AI summaries of your commands) is disabled. You can enable it via .env configuration:
# In your .env file:
TERMTRACE_SUMMARIZE_BATCH_SIZE=10 # Summarize every 10 entries
TERMTRACE_SUMMARIZE_INTERVAL=300 # Or summarize every 5 minutes (300 seconds)Set TERMTRACE_SUMMARIZE_BATCH_SIZE=0 and TERMTRACE_SUMMARIZE_INTERVAL=-1 (defaults) to disable automatic summarization.
To generate a summary immediately at any point from within a traced session:
$ term-trace summarizeThis is useful when you want to capture a summary at a specific milestone or before switching to a different task. Note that this command is only possible from within a traced session.
Launch an interactive Terminal User Interface to browse and review your session logs:
$ term-trace viewThe viewer features:
- Tree-based navigation for workspaces and sessions
- Expandable commands with color-coded exit codes (green=success, red/orange/yellow=errors)
- Search and filter by command or output text
All session data is stored in ~/.termtrace/workspaces/<workspace-name>/ (or your custom TERMTRACE_BASE_DIR):
~/.termtrace/
└── workspaces/
└── my-project/
├── my-project_summary.md # Workspace-level summary (all sessions)
├── session_20250127_143022.jsonl # Raw session log
├── session_20250127_150315.jsonl # Another session
└── ...
At the start of each session, you'll see:
Session started: session_20250127_143022 in workspace: my-project
Using OpenAI GPT summarizer
Starting live summarization (mode: openai)
============================================================
Session Log Locations:
============================================================
JSONL log: /Users/you/.termtrace/workspaces/my-project/session_20250127_143022.jsonl
Summary: /Users/you/.termtrace/workspaces/my-project/my-project_summary.md (workspace-level)
Google Doc: https://docs.google.com/document/d/...
============================================================
- Models:
gpt-4,gpt-3.5-turbo, etc. - Requires:
OPENAI_API_KEY - Best quality summaries
- Models:
xai/grok-3-mini,meta-llama/Llama-3.3-70B-Instruct, etc. - Requires:
GITHUB_TOKEN(GitHub Personal Access Token with models scope) - Free tier available for GitHub users
- Models: Any HuggingFace model with text generation
- Requires:
HUGGINGFACE_TOKEN - Free tier available
- Generates deterministic markdown summaries
- No API token required
- Good for privacy-sensitive environments
term-trace/
├── term_trace/
│ ├── cli.py # CLI entry point
│ ├── config.py # Centralized configuration
│ ├── logger/
│ │ └── session_manager.py # Session management
│ ├── summarizer/
│ │ ├── core.py # Background summarization
│ │ ├── generic_llm.py # OpenAI-compatible APIs
│ │ ├── hf_llm.py # HuggingFace API
│ │ └── google_docs.py # Google Docs integration
│ ├── workspaces/
│ │ └── manager.py # Workspace management
│ └── scripts/
│ ├── write_jsonl_entry.py # Note-taking command
│ └── zsh_jsonl_trace.sh # Shell hooks
├── pyproject.toml
└── README.md
Here's what a small traced session looks like:
Terminal session:
$ term-trace start --workspace demo-project
Session started: session_20250127_143022 in workspace: demo-project
Using OpenAI GPT summarizer
...
$ # Setting up a new Python project
$ mkdir my-app && cd my-app
$ python -m venv venv
$ source venv/bin/activate
$ pip install requests flask
Successfully installed requests-2.31.0 flask-3.0.0 ...
$ # Creating the main application file
$ echo 'from flask import Flask\napp = Flask(__name__)' > app.py
$ ls
app.py venv
$ exit
Session ended.Generated JSONL log (session_20250127_143022.jsonl):
{"type": "note", "timestamp": "2025-01-27T14:30:45Z", "text": "Setting up a new Python project"}
{"type": "command", "timestamp": "2025-01-27T14:30:48Z", "command": "mkdir my-app && cd my-app", "output": "", "exit_code": 0}
{"type": "command", "timestamp": "2025-01-27T14:30:52Z", "command": "python -m venv venv", "output": "", "exit_code": 0}
{"type": "command", "timestamp": "2025-01-27T14:30:55Z", "command": "source venv/bin/activate", "output": "", "exit_code": 0}
{"type": "command", "timestamp": "2025-01-27T14:31:02Z", "command": "pip install requests flask", "output": "Collecting requests\n Downloading requests-2.31.0-py3-none-any.whl\nCollecting flask\n Downloading flask-3.0.0-py3-none-any.whl\nSuccessfully installed requests-2.31.0 flask-3.0.0 Werkzeug-3.0.1 click-8.1.7", "exit_code": 0}
{"type": "note", "timestamp": "2025-01-27T14:31:15Z", "text": "Creating the main application file"}
{"type": "command", "timestamp": "2025-01-27T14:31:18Z", "command": "echo 'from flask import Flask\\napp = Flask(__name__)' > app.py", "output": "", "exit_code": 0}
{"type": "command", "timestamp": "2025-01-27T14:31:22Z", "command": "ls", "output": "app.py\nvenv", "exit_code": 0}AI-generated summary (demo-project_summary.md):
## Session Summary
- Set up a new Python project
- Created and activated a virtual environment
- Installed requests and flask packages
- Created main application file (app.py)
- Verified project structureMIT License - see LICENSE file for details
Contributions welcome! Please open an issue or PR on GitHub.