Documentation
Everything you need to install, configure, and use workscribe.
Getting Started
Requirements
| Dependency | Version |
|---|---|
| Node.js | 22 or later |
| Shell | zsh or bash |
| OS | macOS or Linux (Windows not supported — WSL2 works) |
$ node --version
Install
$ npm install -g @workscribe/cli
Initialise
$ workscribe init
init will:
- Create
~/.workscribe/and initialise the local database - Detect your shell (zsh or bash) and install the capture hook
- Walk you through choosing an AI provider
After init, activate the hook without restarting your terminal:
$ source ~/.zshrc # or ~/.bashrc
Verify it's working
$ workscribe status
You should see Capture active and your configured AI provider. Run a few commands, then check:
$ workscribe events
Events should appear within seconds of running commands.
Generate your first summary
$ workscribe summary
workscribe groups your captured events into sessions and sends them to your AI provider, which returns a standup-ready narrative.
What gets captured
Every command you run in the terminal is intercepted by the shell hook, filtered, redacted, and stored locally. workscribe never stores:
- Raw file contents
- File paths
- Passwords, tokens, or API keys (stripped before writing to disk)
- Commands you've added to the ignore list
See Privacy & Security for full details.
Commands
workscribe init
Set up workscribe — installs the shell hook and configures your AI provider.
$ workscribe init
Run once after install. Safe to re-run — it skips steps that are already complete.
What it does:
- Creates
~/.workscribe/with owner-only permissions - Initialises the SQLite database
- Installs the shell hook into
~/.zshrcor~/.bashrc - Prompts you to choose an AI provider and enter your API key
workscribe summary
Generate an AI work summary for today or a specific date.
$ workscribe summary$ workscribe summary --date 2026-05-20$ workscribe summary --week$ workscribe summary --fresh$ workscribe summary --slack$ workscribe summary --webhook <url>
| Option | Description |
|---|---|
--date <YYYY-MM-DD> | Summarise a specific date instead of today |
--week | Summarise Mon–today for the current week |
--fresh | Bypass cache and regenerate the summary |
--slack | Post the summary to your configured Slack webhook |
--webhook <url> | Post the summary to a custom webhook URL |
Output format:
## project-name (branch) — 2h 15m - Implemented auth middleware and JWT validation - Resolved failing test suite - Committed fixes and pushed to remote
Each session gets its own heading. The heading is always generated from your captured data — project name, branch, and duration — not from the AI.
Caching:
- Daily summaries are cached per session in the database
- Weekly summaries are cached in
~/.workscribe/weekly-cache/<YYYY-WW>.md - Use
--freshto force regeneration
workscribe sessions
List detected work sessions for a date.
$ workscribe sessions$ workscribe sessions --date 2026-05-20
| Option | Description |
|---|---|
--date <YYYY-MM-DD> | Show sessions for a specific date |
Sessions are computed by grouping events with idle gaps greater than session.idleTimeout (default 30 minutes) and splitting across different repositories.
workscribe events
List raw captured events for a date.
$ workscribe events$ workscribe events --date 2026-05-20$ workscribe events --limit 20
| Option | Description |
|---|---|
--date <YYYY-MM-DD> | Show events for a specific date |
--limit <n> | Limit the number of events shown |
Events are colour-coded by category: commits (green), tests (magenta), builds (cyan), infrastructure (red), etc.
workscribe undo
Remove the last N captured events.
$ workscribe undo$ workscribe undo -n 5$ workscribe undo --dry-run$ workscribe undo -n 3 --dry-run
| Option | Description |
|---|---|
-n, --count <number> | Number of events to remove (default: 1) |
--dry-run | Preview what would be deleted without deleting |
Notes:
- Removes events from the database only — does not modify any exported markdown files
- Automatically invalidates sessions for affected dates so they rebuild on next access
- Running undo twice is safe — the second call removes the next N events
workscribe export
Generate a summary and save it as a markdown file.
$ workscribe export$ workscribe export --date 2026-05-20$ workscribe export --output ~/Desktop/standup.md
| Option | Description |
|---|---|
--date <YYYY-MM-DD> | Export a specific date |
--output <path> | Custom output path (default: ~/.workscribe/exports/workscribe-<date>.md) |
workscribe status
Show capture status and event counts.
$ workscribe status
Output includes:
- Whether capture is active or paused
- Number of events captured today and total
- Last captured event
- Configured AI provider and model
workscribe pause / resume
Pause and resume capture.
$ workscribe pause$ workscribe resume
When paused, the shell hook still fires but events are silently discarded. Useful when sharing your screen or running sensitive commands you don't want journaled.
workscribe config
View and update configuration.
$ workscribe config$ workscribe config set <key> <value>$ workscribe config get <key>
$ workscribe config set ai.provider anthropic$ workscribe config set ai.apiKey sk-...$ workscribe config set ai.model claude-haiku-4-5-20251001$ workscribe config set session.idleTimeout 20$ workscribe config set redact.extra "MY_SECRET_PATTERN"$ workscribe config set integrations.slackWebhook https://hooks.slack.com/services/...$ workscribe config set projects./Users/me/sandbox/myrepo actual-repo-name
See Configuration for the full config reference.
Configuration
Config is stored at ~/.workscribe/config.json with owner-only permissions (0600). Use workscribe config set <key> <value> to update any value. Nested keys use dot notation.
AI
| Key | Type | Default | Description |
|---|---|---|---|
ai.provider | string | "" | AI provider: anthropic, openai, ollama, openai-compatible |
ai.apiKey | string | "" | API key for the selected provider |
ai.model | string | "" | Model override (uses provider default if empty) |
ai.baseUrl | string | "" | Base URL for openai-compatible providers |
Provider defaults:
| Provider | Default model |
|---|---|
anthropic | claude-haiku-4-5-20251001 |
openai | gpt-4o-mini |
ollama | llama3 |
openai-compatible | — (set ai.model manually) |
$ workscribe config set ai.provider anthropic$ workscribe config set ai.apiKey sk-ant-...$ workscribe config set ai.model claude-sonnet-4-6
Session
| Key | Type | Default | Description |
|---|---|---|---|
session.idleTimeout | number | 30 | Minutes of inactivity before a new session starts |
$ workscribe config set session.idleTimeout 20
Capture
| Key | Type | Default | Description |
|---|---|---|---|
capture.ignore | string[] | ["cd", "ls", "pwd", …] | Commands to ignore — matched against the base command |
The default ignore list: cd, ls, ll, la, ls -la, ls -l, ls -a, pwd, clear, exit, history, man.
$ workscribe config set capture.ignore '["cd","ls","htop","top"]'
Redact
| Key | Type | Default | Description |
|---|---|---|---|
redact.extra | string[] | [] | Additional regex patterns to redact from captured commands |
workscribe automatically redacts common secret patterns (tokens, API keys, passwords, JWTs). Use redact.extra to add custom patterns.
$ workscribe config set redact.extra '["MY_INTERNAL_TOKEN"]'
Summary
| Key | Type | Default | Description |
|---|---|---|---|
summary.format | "markdown" | "json" | "markdown" | Output format for summaries |
Projects
Override the display name for a repository whose local folder name differs from the actual project name.
| Key | Type | Description |
|---|---|---|
projects.<absolute-path> | string | Display name to use for this path |
$ workscribe config set projects./Users/me/sandbox/chronicle workscribe
Priority order for project name resolution:
- Config override (this setting)
git remote get-url origin— extracts repo name from the remote URLpackage.jsonnamefield (strips@scope/prefix)- Folder name (fallback)
Integrations
| Key | Type | Description |
|---|---|---|
integrations.slackWebhook | string | Slack Incoming Webhook URL — used with workscribe summary --slack |
integrations.webhook | string | Generic webhook URL — POST { text: "..." } |
$ workscribe config set integrations.slackWebhook https://hooks.slack.com/services/...$ workscribe summary --slack
Both keys are masked in workscribe config output for security.
Full example config
{
"ai": {
"provider": "anthropic",
"apiKey": "sk-ant-...",
"model": "claude-haiku-4-5-20251001",
"baseUrl": ""
},
"session": {
"idleTimeout": 30
},
"capture": {
"ignore": ["cd", "ls", "ll", "la", "pwd", "clear", "exit", "history", "man"]
},
"redact": {
"extra": []
},
"summary": {
"format": "markdown"
},
"projects": {
"/Users/me/sandbox/chronicle": "workscribe"
},
"integrations": {
"slackWebhook": "https://hooks.slack.com/services/..."
}
}AI Providers
workscribe sends structured event data to your AI provider only when you explicitly run workscribe summary. It never sends raw commands, file contents, or file paths — only event categories and metadata.
Anthropic (Claude)
$ workscribe config set ai.provider anthropic$ workscribe config set ai.apiKey sk-ant-...
| Setting | Value |
|---|---|
| Default model | claude-haiku-4-5-20251001 |
| API key required | Yes |
Override the model:
$ workscribe config set ai.model claude-sonnet-4-6
Get an API key at console.anthropic.com.
OpenAI
$ workscribe config set ai.provider openai$ workscribe config set ai.apiKey sk-...
| Setting | Value |
|---|---|
| Default model | gpt-4o-mini |
| API key required | Yes |
Override the model:
$ workscribe config set ai.model gpt-4o
Get an API key at platform.openai.com.
Ollama (local)
Run AI summaries entirely on your machine — no API key, no external calls, fully offline.
$ workscribe config set ai.provider ollama
| Setting | Value |
|---|---|
| Default model | llama3 |
| API key required | No |
| Base URL | http://localhost:11434 |
Requirements:
- Install Ollama: ollama.com
- Pull a model:
ollama pull llama3 - Start Ollama:
ollama serve
Override the model:
$ workscribe config set ai.model mistral
OpenAI-compatible
Works with any endpoint that implements the OpenAI chat completions API — Groq, Together AI, Mistral, and others.
$ workscribe config set ai.provider openai-compatible$ workscribe config set ai.apiKey <your-key>$ workscribe config set ai.baseUrl https://api.groq.com/openai/v1$ workscribe config set ai.model llama-3.1-70b-versatile
| Setting | Value |
|---|---|
| Default model | None — set ai.model manually |
| API key required | Depends on provider |
| Base URL required | Yes |
Switching providers
Switch at any time — existing summaries are cached in the database and unaffected:
$ workscribe config set ai.provider ollama
Troubleshooting
"AI provider not configured"
Run workscribe config set ai.provider <provider> and ensure an API key is set if required.
Ollama: connection refused
Make sure Ollama is running: ollama serve
Anthropic / OpenAI: 401 Unauthorized
Check your API key: workscribe config get ai.apiKey
Summary quality is poor on local models
Try a larger model: workscribe config set ai.model llama3:70b. Local models with fewer than 7B parameters may produce inconsistent output.
Privacy & Security
What stays local
Everything. All captured data is stored in ~/.workscribe/ on your machine. Nothing is written to any remote server except what you explicitly send to your AI provider when you run workscribe summary.
| Location | Contents |
|---|---|
~/.workscribe/workscribe.db | SQLite database — events, sessions, cached summaries |
~/.workscribe/config.json | Configuration including API keys |
~/.workscribe/exports/ | Markdown files from workscribe export |
~/.workscribe/weekly-cache/ | Cached weekly summaries |
Both the database and config file are written with 0600 permissions (owner read/write only).
What gets redacted
Before any event is written to disk, workscribe strips sensitive patterns from the raw command string.
Automatically redacted:
- Bearer tokens (
Bearer <token>) - Authorization headers
- API keys and secrets in common formats
- Passwords passed as flags (
--password,-p) - JWT tokens
- Private keys
Add your own patterns:
$ workscribe config set redact.extra '["MY_INTERNAL_SECRET"]'
Redaction is applied as a regex replace — matched values are replaced with [REDACTED] before the command touches the database.
What is sent to your AI provider
Only when you run workscribe summary. Only structured event categories — never raw commands.
Sent:
Project: api-service
Branch: feature/auth
Duration: 2h 15m
Events:
- 3x code_commit
- 2x test_run [failed]
- test_run
- dependency_install {"tool":"npm","packages":["bcrypt"]}Never sent:
- Raw command strings
- File paths or file contents
- Environment variables
- Credentials or tokens
- Hostnames or IP addresses
Using Ollama for full offline operation
If you want zero external data transmission, use Ollama — workscribe summary never makes an external network request. Everything runs on your machine.
$ workscribe config set ai.provider ollama
Pausing capture
To temporarily stop capturing — for example, when working with sensitive data or sharing your screen:
$ workscribe pause# ... do sensitive work ...$ workscribe resume
When paused, the shell hook still fires but all events are silently discarded before touching disk.
Removing your data
$ rm -rf ~/.workscribe
This removes the database, config, exports, and cache. The shell hook in your ~/.zshrc or ~/.bashrc will still fire but write nothing. To remove the hook, delete the block between # workscribe:hook:start and # workscribe:hook:end in your shell rc file.
Troubleshooting
Capture isn't working
Check status first:
$ workscribe status
If it shows Capture active but no events are appearing, the shell hook may not be loaded.
$ source ~/.zshrc # or ~/.bashrc
Then run a command and check:
$ workscribe events
Enable debug mode to see what the capture process is doing:
$ WORKSCRIBE_DEBUG=1 workscribe status$ cat ~/.workscribe/debug.log
Shell hook is not installed
If workscribe init didn't detect your shell or the hook is missing, re-run init — it's safe and skips steps already completed:
$ workscribe init
If you're using a non-standard shell (fish, nushell), the hook is not currently supported. You can manually trigger capture:
$ workscribe _capture --command "your command" --cwd "$PWD" --exit-code 0
Windows is not supported. The shell hook requires zsh or bash. If you're on Windows, use WSL2 with zsh or bash — workscribe works normally inside WSL2.
"No activity captured for today"
Either no events have been captured yet, or all commands ran were on the ignore list. Check:
$ workscribe events
If events exist but summary shows nothing, check the date:
$ workscribe summary --date $(date +%Y-%m-%d)
Summary looks wrong or generic
Wrong project name:
$ workscribe config set projects./full/path/to/repo correct-name
Bullet points are off-topic: Try --fresh to regenerate without cache:
$ workscribe summary --fresh
For local models (Ollama), try a larger model:
$ workscribe config set ai.model llama3:70b
"AI provider not configured"
$ workscribe config set ai.provider anthropic # or openai, ollama$ workscribe config set ai.apiKey <your-key>
Ollama: "connection refused"
$ ollama serve
And ensure the model is pulled:
$ ollama pull llama3
API key errors (401 / 403)
$ workscribe config get ai.apiKey
Reset it:
$ workscribe config set ai.apiKey <new-key>
Webhook not posting
Test your webhook URL directly:
$ curl -X POST <your-webhook-url> \$ -H "Content-Type: application/json" \$ -d '{"text":"test"}'
If that works but --slack doesn't, check the config:
$ workscribe config get integrations.slackWebhook
Database errors
If you see SQLite errors, the database may be corrupted. Back up first, then reinitialise — config is unaffected:
# Back up first$ cp ~/.workscribe/workscribe.db ~/.workscribe/workscribe.db.bak# Delete and reinitialise$ rm ~/.workscribe/workscribe.db$ workscribe status # triggers reinitialisation
Uninstalling
$ npm uninstall -g @workscribe/cli$ rm -rf ~/.workscribe
Then remove the hook block from your ~/.zshrc or ~/.bashrc — delete everything between # workscribe:hook:start and # workscribe:hook:end.