Getting started
Create a workspace, install the CLI, connect your agents, and ask why. About five minutes.
Requirements
- Node.js 22.13 or newer.
- git, for
whyline initandwhyline blame. - For prompt and edit capture: Claude Code.
1. Create a workspace
Open the dashboard, enter a name and choose Create. Copy the API key (it starts with wl_). It is shown once and cannot be recovered; if it leaks, replace it with whyline rotate-key. Anyone with the key can read and write that workspace.
2. Install the CLI
Whyline is not published to the npm registry. Install it straight from GitHub:
pnpm add -g github:Gauravkumar6617/whyline
# or: npm install -g github:Gauravkumar6617/whylineCheck it worked with whyline --help. The Claude Code plugin and the git hook both call whyline, so it must be on your PATH. Without a global install you can still run the CLI from a clone with node cli/whyline.js.
3. Log in
whyline login --url https://whyline.wrklyst.com --key wl_...This checks the key and saves it to ~/.config/whyline/config.json. For your own server, use its URL. Alternatively set WHYLINE_URL and WHYLINE_KEY.
4a. Connect Claude Code (prompts, edits and commits)
/plugin marketplace add Gauravkumar6617/whyline /plugin install whyline@whyline
The plugin runs whyline hook claude-code after each prompt and after each Edit, Write, MultiEdit or NotebookEdit. It needs the CLI from step 2. Also run whyline init (below) in each repository so commits are recorded and linked to those prompts.
4b. Connect Cursor, Codex or Gemini CLI (prompts, edits and commits)
Add Whyline to the agent's own hooks. These files are per user, so they cover every project; if the file already exists, merge these entries into it. Like the Claude Code plugin, they need the CLI from step 2, and whyline init (below) in each repository so commits are recorded and linked to the prompts.
Cursor: ~/.cursor/hooks.json
{
"version": 1,
"hooks": {
"beforeSubmitPrompt": [{ "command": "whyline hook cursor" }],
"afterFileEdit": [{ "command": "whyline hook cursor" }]
}
}Codex CLI: ~/.codex/hooks.json. Codex runs a new hook only after you trust it: open /hooks in Codex once.
{
"hooks": {
"UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "whyline hook codex", "timeout": 5 }] }],
"PostToolUse": [{ "matcher": "apply_patch", "hooks": [{ "type": "command", "command": "whyline hook codex", "timeout": 5 }] }]
}
}Gemini CLI: ~/.gemini/settings.json
{
"hooks": {
"BeforeAgent": [{ "hooks": [{ "type": "command", "command": "whyline hook gemini", "timeout": 5000 }] }],
"AfterTool": [{ "matcher": "write_file|replace", "hooks": [{ "type": "command", "command": "whyline hook gemini", "timeout": 5000 }] }]
}
}Codex edits are read from apply_patch, so files a Codex shell command changes are not recorded as edits. Cursor Tab completions are not recorded.
4c. Connect any agent (commits)
whyline init
Run this in each repository. It adds a post-commit hook that records every commit, and a post-rewrite hook so that commits rewritten by an amend or a rebase keep the agent and prompts of the commits they replace. If the commit includes files a connected agent edited (4a, 4b), it is recorded as that agent with the prompts behind it. Otherwise the agent is read from the commit message: a Co-Authored-By:, AI-Agent: or Assisted-by: trailer that identifies the agent itself, such as Co-Authored-By: Claude <noreply@anthropic.com>, Co-Authored-By: Cursor Agent <cursoragent@cursor.com> or Assisted-by: Claude (the trailer the Linux kernel asks for). The recognised agents are claude-code (Claude), cursor, copilot, codex, gemini, aider, devin and windsurf. A co-author who only shares an agent's name, such as Devin Smith, is not treated as an agent. Without one, the commit is recorded as agent none.
The hook goes wherever git runs hooks, including a core.hooksPath directory. If a post-commit hook already exists, it must be an executable shell script: Whyline adds one line after its #! line and leaves the rest as it was. For any other hook (Node, Python, a binary, a symlink, or one that is not executable), init changes nothing, exits with an error and tells you to call whyline hook git from it yourself. A post-rewrite hook that already exists is never edited: init prints a warning, and rebased commits are then recorded without their prompts.
AI-Agent: cursor. The formats are explained in AI commit trailers.5. Ask why
whyline blame src/orders.ts:2
Prints the code on that line, then the commit, agent, author, time and message, and the prompt if one was linked. Example output from a local demo repository:
$ whyline blame src/orders.ts:2
src/orders.ts:2 const amount_cents = Math.round(order.total * 100);
a7394e0b · claude-code · dev@example.com · 10/7/2026, 11:10:20 AM
add orders
Prompt:
store money as integer centsMessages you may see: not committed yet for uncommitted lines, and no Whyline record for commits made before setup, without the git hook, or outside your machine, such as a squash merge on GitHub.
6. View events
- CLI:
whyline eventsprints one tab-separated line per event: id, time, agent, kind, author, and the first line of the summary or prompt. Add--since <id>for newer events only. - Dashboard: open /app, paste your key, and filter the newest 500 events by file, prompt, agent, author or commit. The count line shows how many of the commits shown were AI-assisted, so filtering by an author or a path gives the share for just those.
- CSV: choose Export CSV in the dashboard for the full history.
Offline and privacy
Events that cannot be sent are queued in ~/.config/whyline/queue.jsonl and sent with the next event. If the server rejects your API key (401 or 403), new events are not queued and the error says so; events already queued wait until you log in with a valid key. To keep prompt text off the server, log in with --no-prompts. Details are in data and privacy.
CLI reference
| Command | What it does |
|---|---|
whyline login --url <server> --key <wl_...> [--no-prompts] | Save credentials. --no-prompts never sends prompt text; logging in again keeps that choice until you pass --prompts. |
whyline init | Install the git post-commit and post-rewrite hooks in this repository. |
whyline blame <file>:<line> | Show the commit, agent and prompt behind a line. |
whyline events [--since <id>] | Show recent events. |
whyline hook claude-code|cursor|codex|gemini | Used by the agent's hooks. Reads hook JSON on stdin. |
whyline rotate-key | Replace the workspace's API key and save the new one. The old key stops working at once, for everyone using it. |
whyline delete-workspace --yes | Delete the workspace and all of its events, for everyone using its key. Logs the CLI out and clears its local queue. Cannot be undone. |
whyline hook git | Used by the git post-commit hook. |
whyline hook rewrite amend|rebase | Used by the git post-rewrite hook. Reads the rewritten commits on stdin. |
Environment variables
WHYLINE_URL,WHYLINE_KEY: server and key, overriding the saved config.WHYLINE_NO_PROMPTS=1(ortrue,yes,on): never send prompt text.0,false,no,offor empty leave it to the saved login setting; an opt-out in either place wins.WHYLINE_HOME: where config, queue and edit records are kept. Default~/.config/whyline.
Next: the API reference, or run your own server.