diddo tracks your git commits and turns them into daily summaries.
It installs a global post-commit hook, stores commit metadata in a local SQLite database, and can summarize that history with an AI CLI tool or a direct API provider.
Supported platforms: macOS (Apple Silicon, Intel), Linux (x86_64, aarch64), Windows (x86_64, ARM64). Pre-built binaries are published for each release. Pre-built Linux binaries are built on Ubuntu 22.04 and require glibc 2.35+ (e.g. Ubuntu 22.04 or Debian 12). On older distros, install from source: cargo install --path ..
If you use Homebrew:
brew tap drugoi/tap
brew install diddoInstall the latest release:
curl -sSL https://raw.githubusercontent.com/drugoi/diddo-hooks/main/install.sh | shTo pin a version:
DIDDO_VERSION=0.1.0 curl -sSL https://raw.githubusercontent.com/drugoi/diddo-hooks/main/install.sh | shInstall the latest release (run PowerShell as current user):
irm https://raw.githubusercontent.com/drugoi/diddo-hooks/main/install.ps1 | iexTo pin a version:
$env:DIDDO_VERSION = "0.1.0"; irm https://raw.githubusercontent.com/drugoi/diddo-hooks/main/install.ps1 | iexInstall options (environment variables):
- DIDDO_VERSION — Pin the install to a specific release (e.g.
0.1.0). - DIDDO_INSTALL_DIR — Directory where the binary is installed. Defaults:
$HOME/.local/bin(macOS/Linux),%LOCALAPPDATA%\diddo(Windows).
Alternatively, download the diddo-<version>-x86_64-pc-windows-msvc.zip (or ARM64) from Releases, extract diddo.exe, and add the folder to your PATH.
cargo install --path .To try without installing:
cargo run -- --helpInstall the managed global hooks directory:
diddo initWhat diddo init does:
- Creates a managed hooks directory for
diddo - Sets global git
core.hooksPathto that directory - Preserves and forwards any previously configured global hooks so existing hooks keep running
On Windows, global hooks run only if you use Git for Windows (or another Git that runs hook scripts with a Unix-like shell). The generated hooks are #!/bin/sh scripts; Git for Windows runs them with its bundled sh.
Repositories that set a local core.hooksPath (e.g. Husky’s .husky) override the global path. Git only runs hooks from the local directory, so the global hooks are never invoked.
Run diddo init from within such a repo to add a post-commit hook to the local hooks directory. This ensures commits are recorded:
cd your-husky-repo
diddo initYou’ll see:
Installed diddo hooks in ... and updated global core.hooksPath.
Also added diddo post-commit to this repo's local hooks (.husky) so commits are recorded.
If a post-commit already exists in that directory, it is backed up as post-commit.diddo-prev and the new script chains to it.
diddo only records commits made after setup. It does not backfill old git history into the database.
To see where diddo stores its config, database, and managed hooks on your machine:
diddo configExample output:
macOS:
Config file: /Users/you/Library/Application Support/diddo/config.toml
Database path: /Users/you/Library/Application Support/diddo/commits.db
Hooks dir: /Users/you/Library/Application Support/diddo/hooks
Linux:
Config file: /home/you/.config/diddo/config.toml
Database path: /home/you/.local/share/diddo/commits.db
Hooks dir: /home/you/.config/diddo/hooks
Windows:
Config file: C:\Users\you\AppData\Roaming\diddo\config.toml
Database path: C:\Users\you\AppData\Local\diddo\commits.db
Hooks dir: C:\Users\you\AppData\Roaming\diddo\hooks
Run diddo in a terminal to launch interactive mode — an arrow-key menu of all available commands. Any -- flags without a subcommand (e.g. diddo --table, diddo --md) also launch interactive mode; the flags are ignored.
Interactive mode includes direct shortcuts for month and a range form that collects from and optional to dates in either YYYY-MM-DD or DD.MM.YYYY before launching the command.
Show summaries:
diddo today
diddo yesterday
diddo week
diddo month
diddo range --from 2026-03-01
diddo range --from 01.03.2026 --to 11.03.2026
diddo range --from 2026-03-01 --to 2026-03-11
diddo standupOutput modes (require a subcommand):
diddo today --md
diddo today --table
diddo yesterday --json
diddo week --raw
diddo month --md
diddo range --from 2026-03-01 --json
diddo range --from 2026-03-01 --to 2026-03-11 --raw
diddo today --no-cache
diddo yesterday --json
diddo yesterday --table
diddo week --raw
diddo week --tableOutput flags must be used with a subcommand (today, yesterday, week, standup):
--md— Output summary as markdown. Includes the repository activity table.--json— Output summary as JSON.--raw— Skip AI and show grouped raw commit data only (no activity table).--table— Skip AI and show only the per-repository activity table.--no-cache— Skip the AI summary cache and force a fresh summary.
Default terminal and markdown summaries include a repository activity table after the AI summary (or raw fallback). The table shows per-repository commit counts and percentages for the selected period:
repository commits percentage
----------- ------- ----------
diddo 5 62.5%
api-service 3 37.5%
----------- ------- ----------
Total 8 100.0%
Use --table with a subcommand to skip AI and show only the table:
diddo today --table
diddo week --tableCurrent CLI behavior:
diddowithout a subcommand launches interactive mode in a terminal; any--flags are ignoreddiddo today,diddo yesterday,diddo week,diddo standuprun the corresponding summary directlydiddo standupshows commits from the last 24 hours ([now - 24h, now]), useful when your daily meeting is in the afternoondiddoanddiddo todayare equivalentdiddo monthshows the current calendar month from day 1 through todaydiddo range --from YYYY-MM-DD|DD.MM.YYYY [--to YYYY-MM-DD|DD.MM.YYYY]shows an inclusive custom date rangediddo range --from ...defaults--toto today's local daterangeaccepts bothYYYY-MM-DDandDD.MM.YYYYon input, and normalizes output labels back toYYYY-MM-DD- Output flags (
--md,--json,--raw,--table,--no-cache) only take effect with a subcommand --tableis mutually exclusive with--md,--json, and--raw--rawskips AI and shows grouped commit data without the activity table--tableskips AI and shows only the repository activity table- Default terminal and
--mdsummaries include the repository activity table after the AI summary (or raw fallback) --mdand--jsonstill try AI first unless you also use--raw- If no commits are recorded for the selected period,
diddoprints an empty-period message instead of failing
Summaries are grouped by git profile (user.email) then by repo; there is one AI summary per profile. Commits with no configured email are grouped under "unknown".
Other commands:
diddo init
diddo uninstall
diddo config
diddo metadata
diddo updatediddo metadata— Show database metadata: file size, total commit count, oldest recorded commit, and hooks status (global and local). Use it to verify your setup; it shows hints when something is misconfigured (e.g.Local hooks: .husky (missing diddo hook — run 'diddo init')).diddo update— Self-update to the latest release (detects Homebrew vs GitHub install; use--yesto skip the confirmation prompt).
diddo is CLI-first by default.
AI summaries are cached in the same SQLite database as your commits. When the commit set and period are unchanged (and you use the same provider/model), diddo returns the stored summary instead of calling the AI again. Use --no-cache to force a fresh summary.
Without extra configuration, it tries installed AI CLIs in this order:
claudecodexopencodecursor-agent
If no supported CLI is available, diddo falls back to a direct API provider when configuration and credentials are available.
If neither CLI tools nor a usable API configuration are available, diddo falls back to grouped raw commit output and prints a warning on stderr.
- Default behavior: try detected CLI tools first, then try API
ai.cli.prefer = "cli": keep CLI-first behavior, then API fallback if configuredai.cli.prefer = "claude","codex","opencode", or"cursor-agent": force that CLI first, then API fallback if configuredai.cli.prefer = "api": skip CLI detection and use API only
Supported API providers:
openaianthropic
Default API models:
- OpenAI:
gpt-4o-mini - Anthropic:
claude-sonnet-4-6
When ai.prompt_instructions is not set (or empty), the CLI uses a built-in prompt. There is no config key for the default; it is fixed in the binary. The prompt sent to the AI is (with {period} and commit count/list filled in):
You are summarizing git activity for {period}.
Using only the commit data provided, produce a concise repository-based summary of changes.
Format:
Repository: <repository_name>
1. <short description of change or feature>
2. <short description of fix or improvement>
Repository: <another_repository>
1. <short description of change or feature>
2. <short description of fix or improvement>
Examples:
Repository: diddo
1. Added AI-powered daily summaries for recorded commits.
2. Improved the global hook installation flow.
Repository: api-service
1. Fixed token refresh handling for expired sessions.
2. Refactored request validation for clearer error responses.
Guidelines:
- Group commits by repository.
- Convert commit messages into short, clear descriptions of what changed.
- Combine similar commits into a single bullet when possible.
- Focus on meaningful work (features, fixes, refactors, improvements).
- Ignore trivial commits (formatting, typos, merge commits) unless important.
- Keep each bullet to one short sentence.
Use only the commit data below.
Period: {period}
Commit count: {n}
Commits:
1. [repo_name] message (hash) on branch at 2026-03-10T12:00:00Z; files: 3, +12, -4
...
Return plain text only.
{period} is e.g. today, yesterday, this week, this month, or a concrete date span like 2026-03-01 to 2026-03-11; {n} is the commit count. The list is one line per commit in the format above.
The config file is optional. If it does not exist, diddo still works for raw summaries and for AI summaries when a supported CLI tool is already installed.
Run diddo config to get the exact config path on your machine.
Options:
| Key | Description |
|---|---|
ai.provider |
API provider: openai or anthropic |
ai.api_key |
API key (overrides environment variables) |
ai.model |
Model for direct API; defaults: gpt-4o-mini (OpenAI), claude-sonnet-4-6 (Anthropic) |
ai.prompt_instructions |
Custom AI instructions (tone, language, length); period and commit list are always appended |
ai.cli.prefer |
CLI/API preference: api, cli, claude, codex, opencode, or cursor-agent |
filters.ignored_profiles |
List of author emails to exclude from reports. Defaults to ["test@test.com"]. Set to [] to disable filtering. |
Example:
[ai]
provider = "openai"
model = "gpt-4o-mini"
[ai.cli]
prefer = "cli"To use the direct API fallback, provide credentials either in the config file:
[ai]
provider = "anthropic"
api_key = "your-api-key"
model = "claude-sonnet-4-6"
prompt_instructions = "Summarize in German. One short paragraph, plain text only."
[ai.cli]
prefer = "cli"or through environment variables:
export DIDDO_OPENAI_KEY=your-openai-key
export DIDDO_ANTHROPIC_KEY=your-anthropic-keyNotes:
ai.provideracceptsopenaioranthropicai.cli.preferacceptsapi,cli,claude,codex,opencode, orcursor-agent(alias:cursor_agent)ai.modelapplies to direct API providers only; CLI tools use their own default model selectionai.api_keyin the config file overrides environment variablesai.prompt_instructions(optional): when set, replaces the default AI instructions (tone, language, length); period, commit count, and commit list are always appended. Use for a different language or more concise output. Empty or missing = default instructions.- If
ai.provideris omitted and exactly one ofDIDDO_OPENAI_KEYorDIDDO_ANTHROPIC_KEYis set,diddoinfers the provider from that environment variable filters.ignored_profilesexcludes commits whose author email matches any entry (trimmed, case-insensitive) from summary and activity reports.test@test.comis ignored by default; override with a custom list or[]to keep everything
Example:
[filters]
ignored_profiles = ["test@test.com", "ci-bot@example.com"]Remove diddo from your global git hooks setup:
diddo uninstallCurrent uninstall behavior:
- Removes the managed
diddohooks directory - Restores the previous global
core.hooksPathifdiddostill owns that setting - Unsets global
core.hooksPathifdiddocreated it and there was no previous value - Leaves the current global
core.hooksPathuntouched if you changed it after installingdiddo - Does not remove
post-commithooks added to local hooks directories (e.g..husky); remove those manually if desired
MIT
