madelogdocs

Commands

Every command with what it does, what it prints, its exit codes, the files it touches and its edge cases, followed by the binary's own --help text so the reference cannot drift from the code.

Every command runs inside a git repository and finds it by searching upward from the current directory, like git does. Output shown here is what madelog 0.1.0 prints, with the home directory shortened to /Users/ana. The --help text of every command, captured from the binary by landing/scripts/gen-commands.sh, is at the end of this page. If a flag is not there, it does not exist.

Exit codes

CodeWhen
0The command did its job. --help, -h, --version, -V and madelog help <command> also exit 0 and print to standard output
1The command ran and failed: no .madelog/ yet, a broken chain, an invalid config value, an aborted preview, a refused or unreachable server, an editor that did not save, a browser that would not open. Also madelog doctor when a check failed
2Wrong usage: an unknown command, a bad flag, a missing argument, --record-ai-sessions together with --no-record-ai-sessions. Also madelog ask and madelog model pull, which are not available in this version

Errors go to standard error, start with madelog:, and name the problem, then the fix. madelog hook post-commit is the one exception to the table: it exits 0 whatever happens, so a recording problem can never fail a commit.

$ madelog frobnicate
error: unrecognized subcommand 'frobnicate'

Usage: madelog <COMMAND>

For more information, try '--help'.
$ madelog hide
error: the following required arguments were not provided:
  <EVENT_ID>

Usage: madelog hide <EVENT_ID>

For more information, try '--help'.

Both exit 2. Every command that needs the log and finds none prints the same line and exits 1:

madelog: no madelog log in this repository yet — run `madelog init` first (/Users/ana/projects/ledger/.madelog/log.db is missing)

Outside a git repository: madelog: not inside a git repository (could not find repository at '/Users/ana'): run `git init` first.

Where things are

PathWhat
.madelog/log.dbThe event log, SQLite, append-only. log.db-wal and log.db-shm sit next to it
.madelog/config.tomlSettings; see Configuration
.madelog/intent.mdYour answers from madelog init as Markdown, a copy for you; the page reads the intent event
.madelog/site/index.htmlThe rendered page, written by every madelog publish
.madelog/bin/madelogThe binary, in a per-project install only
.git/hooks/post-commitTwo lines under # madelog-cli:post-commit
.git/hooks/post-mergeTwo lines under # madelog-cli:post-merge
.git/hooks/post-rewriteTwo lines under # madelog-cli:post-rewrite
.git/info/excludeOne line, .madelog/
~/.config/madelog/device.keyThe ed25519 key that signs a publish, mode 0600

init

Sets madelog up in the repository: asks four questions, writes .madelog/, appends the intent event, installs the hooks, creates the device key, and records the history the repository already had.

$ madelog init --what "A CLI that reconciles bank CSV exports against invoices" \
    --for-whom "A small accounting firm that closes its books by hand" \
    --tools "claude-code, cursor" --record-ai-sessions
madelog is recording in /Users/ana/projects/ledger/
  .madelog/intent.md      what you are building, in your own words
  .madelog/log.db         the event log, hash chained
  .madelog/config.toml    settings, including privacy.redact
Your commits are recorded from now on. Nothing leaves this machine.

6 commits in this repository are not recorded yet.

recorded 6 commits, oldest first
  from ff8a9fd  to cd2619d
  no AI sessions were attached: the logs of a session that ran months ago are long gone, and guessing at one would be worse than leaving it out

note: backfilled commits carry no secs_since_prev signal. They were all recorded just now, so the gaps between records say nothing about the gaps between commits; the page uses committed_at for the timeline instead.

Next: `madelog note "why you did it that way"` after a decision.

Without flags it asks What are you building? , Who is it for? , Which AI tools do you use? (comma separated) and Record the AI sessions behind your commits? [Y/n] on standard output and reads one line each. An empty answer to the last one means yes. --yes asks nothing: flags given are used, the rest are empty strings, and AI sessions are recorded. --tools is split on commas and trimmed.

The backfill at the end is the same walk madelog backfill --yes does, and it is the reason a page never claims a project took one day. --no-backfill leaves the history alone; a failure there is printed and init still succeeds, because madelog is set up either way.

Files: creates .madelog/intent.md, .madelog/config.toml (loaded first, so an existing file keeps its values; project.name is set to the directory name when empty) and .madelog/log.db; appends .madelog/ to .git/info/exclude once; appends its two lines to .git/hooks/post-commit, .git/hooks/post-merge and .git/hooks/post-rewrite once each, creating any of them with #!/bin/sh and making it executable if it did not exist; creates ~/.config/madelog/device.key if there is none.

A repository that already has madelog from an older version has only post-commit. madelog doctor --fix adds the other two.

Edge cases:

  • Run again. Everything above is idempotent, the event included. In a repository that already has an intent event, init with none of --what, --for-whom or --tools asks nothing, appends nothing and leaves intent.md alone; it prints madelog is already recording in /Users/ana/projects/ledger/ and Nothing changed. Pass --what, --for-whom or --tools to record a new intent., exit 0. Give any of those three and a new intent event is appended with the answers merged over the newest one: the flags you passed win, the ones you left out carry over, record_ai_sessions included unless --record-ai-sessions or --no-record-ai-sessions says otherwise. intent.md is rewritten to match. The old intent stays in the chain, and the hook, the page and madelog export all read the newest one.
  • No commits yet. Allowed. The intent event has no commit_sha, and the hook starts recording at the first commit.
  • An existing hook. Kept. madelog's lines go at the end of each of the three hooks, after a blank line. A hook managed by another tool that rewrites the file later removes them; run init again, or madelog doctor --fix, to add them back.
  • core.hooksPath set. madelog writes to .git/hooks/ regardless, and git will not run it. Add the two lines to the hook in the configured directory by hand.
  • Bare repository. Refused: madelog: this is a bare git repository; madelog needs a working tree.
  • The hook line. madelog hook post-commit || true, and the same for post-merge and post-rewrite, unless the binary runs from <repo>/.madelog/bin/, in which case its full path is written, quoted when it has spaces. See MADELOG_EXE in Configuration.

Exit codes: 0; 1 outside a git repository or when a file cannot be written; 2 when both AI-session flags are given.

onboard

Prints the banner and three sentences about what madelog records, checks for git and ollama on PATH, lists the AI tools it can read, offers the global git hook, and offers to run init when you are inside a repository that has no log yet. Safe to run at any time.

$ madelog onboard
  +---+
  | +-+-+   madelog - Proof of Process
  +-+-+ |   Records how your project came together.
    +---+

madelog records three things: the commits you make, the AI sessions that produced them, and the one-sentence decisions you write with `madelog note`.
All of it stays on this machine, in .madelog/log.db, until you run `madelog publish`.
No keystrokes, no screenshots, no files git ignores. `madelog export` hands you everything back as JSON.

git      found    /opt/homebrew/bin/git
ollama   found    /usr/local/bin/ollama

AI tools madelog can read:
  claude-code: transcripts found in /Users/ana/.claude/projects, 1 session touches this repo
  codex: no rollouts in ~/.codex, so nothing to read
  cursor: Cursor keeps conversation bodies encrypted; madelog records that a session happened, 1 session touches this repo
  copilot: not installed
  AI sessions: not recording (no madelog log here — run `madelog init`)

Record every repository you commit in? [y/N] n
Only the repositories you run `madelog init` in, then.

Set up madelog in this repo now? [Y/n] n
Nothing changed. Run `madelog init` when you are ready.
  • Outside a repository the last block is You are not inside a git repository, so there is nothing to record yet. followed by git init and madelog init, exit 0.
  • In a repository that already has .madelog/log.db: madelog is already set up in /Users/ana/projects/ledger/. and two suggestions, madelog log and madelog verify. --yes and --project do not change that — nothing is appended and intent.md is left alone.
  • --yes answers yes and then runs init with --yes, so the intent is empty. --project does the same and is what the per-project installer runs. An interactive yes runs init with its questions.
  • The box-drawing banner needs a terminal, TERM other than dumb, and a UTF-8 locale (Windows Terminal on Windows). Everything else gets the ASCII banner shown above.
  • Every repository. Answering y to Record every repository you commit in? [y/N] asks two more questions — Set madelog up in a new repository without asking? [Y/n] and Record the AI sessions behind those commits? [Y/n] — writes both answers to ~/.config/madelog/config.toml as auto_init and record_ai_sessions, installs post-commit, post-merge and post-rewrite in ~/.config/madelog/hooks/, and sets git's global core.hooksPath to that directory. A core.hooksPath that was already set is chained: madelog's script runs first and then calls the hook of the same name in the old directory, passing post-rewrite the same standard input. A core.hooksPath that is already madelog's own directory is left alone. Re-running onboard afterwards prints Every repository: on. and asks nothing.
  • --yes and --project never touch the machine's git configuration: a per-project install is about one repository on purpose.

Files: none of its own; init writes what it writes. Exit code: 0, or whatever init returns.

note

Appends one decision event, anchored to HEAD or to the commit --at names. No editor, no confirmation.

$ madelog note "chose SQLite over Postgres: one binary, no service to run"
noted at ec66d42
$ madelog note --private "the client sends CSVs with a BOM; strip it before parsing"
noted at ec66d42 (private, never published)

The words after note are joined with single spaces, so quoting is optional unless the sentence contains shell characters. Leading and trailing whitespace is trimmed.

--at <sha> anchors the note to a commit other than HEAD, which is what you want after madelog backfill: the reason for a decision made in August belongs next to the August commit, not next to today's. Anything git can resolve works — a short sha, a full sha, a tag, a branch name:

$ madelog note --at 45fe301 "chose SQLite over Postgres: one binary, no service to run"
noted at 45fe301
  • Empty. madelog: a note needs a sentence: madelog note "why you did it that way", exit 1.
  • No commits yet. Allowed; the event has no anchor and the output is just noted.
  • --at names nothing. madelog: no commit `deadbee` in this repository, exit 1. Nothing is appended: a note anchored to a commit that does not exist is a note nothing can ever find.
  • --private. The event is chained, listed by madelog log with (private), counted by nothing on the page, absent from the preview and the summaries. There is no way to make it public later other than writing a new note.

Files: .madelog/log.db. Exit codes: 0; 1 without a log, with an empty sentence, or with an --at git cannot resolve.

backfill

Records the commits this repository already had when madelog arrived. Walks first parents back from HEAD, skips every commit the log already has, and appends the rest oldest first, with the same stats and diff excerpts the hook writes.

madelog init already does this once, so backfill is for a branch you merged later or a repository set up with --no-backfill.

$ madelog backfill
6 commits in this repository are not recorded yet.
Record them now? [Y/n] y

recorded 6 commits, oldest first
  from ff8a9fd  to cd2619d
  no AI sessions were attached: the logs of a session that ran months ago are long gone, and guessing at one would be worse than leaving it out

note: backfilled commits carry no secs_since_prev signal. They were all recorded just now, so the gaps between records say nothing about the gaps between commits; the page uses committed_at for the timeline instead.

Each event gets ts of now — the chain records when madelog saw the commit — and committed_at from git, which is what the page draws the timeline from. secs_since_prev is left empty, because everything in one backfill is recorded in the same second and a number there would be a lie. See Concepts.

  • Nothing to do. nothing to record: all 8 commits on this branch are already in the log, exit 0. Running it twice is safe.
  • --yes. Records without asking. An empty answer to the question means yes; n prints Nothing changed. and appends nothing.
  • --since <date|sha>. The oldest commit to record, inclusive. A YYYY-MM-DD date is read as a date, anything else is handed to git, so short shas, tags and branch names all work. Neither: madelog: `--since yesterday` is neither a commit this repository has nor a date like 2026-01-31, exit 1.
  • 2000 commits at most in one run. Above that the newest 2000 are recorded and the command says Recording the newest 2000. Run `madelog backfill --since <date|sha>` for the rest.
  • AI sessions. None. madelog reads an AI tool's local logs at commit time, and the logs behind a commit made weeks ago are gone. Backfilled commits carry commits and decisions, never sessions.
  • Merges. Only the first-parent line is walked, which is the branch's own history. Commits that only exist on a merged-in side branch are not recorded.
  • No .madelog/. madelog: there is no madelog log in /Users/ana/projects/ledger/ — run `madelog init` first. `madelog backfill` records history into an existing log; it does not start one., exit 1.
  • No commits at all. no commits in this repository yet, so there is no history to record, exit 0.

Files: .madelog/log.db; reads .madelog/config.toml for privacy.redact. Exit codes: 0; 1 without a log or with an unusable --since.

hook post-commit, post-merge, post-rewrite

The three hooks madelog init installs. Git runs them; you do not, except to record a commit they missed.

hook post-commit records the commit HEAD points at as a commit event and then does the rest of the work automatically:

  1. AI sessions. When the newest intent has record_ai_sessions: true, it reads the sessions that ran since the previous commit, matches the lines they wrote against the lines the commit added, and appends one ai_session event per session. See AI sessions.
  2. Patterns. Runs the four rules over the log and appends a pattern event for anything not already recorded.
  3. Summaries. Writes a summary for any week that has none, and rewrites the newest week when the facts have moved on — unless you edited that week yourself, in which case it is left alone. A local model is used only when it is already pulled, and never for more than three seconds; otherwise the template writes it.
  4. The page. Re-renders .madelog/site/index.html, unless nothing changed and the page is already there.
$ git commit -m "feat: match bank rows to invoices by amount and reference"
[main 9a1246f] feat: match bank rows to invoices by amount and reference
 2 files changed, 9 insertions(+)
 create mode 100644 src/reconcile.rs

On success it prints nothing. Everything it says goes to standard error and starts with madelog:. It always exits 0.

  • .madelog/ missing. Returns silently. The hook may outlive the directory.
  • Already recorded. A commit sha that already has a commit event is skipped, so running the hook twice, or amending and re-running, adds nothing. An amended commit has a new sha and is recorded as a new event; the old one stays.
  • No AI sessions. Nothing printed. A commit you wrote by hand is not a commit with something missing, and a machine with no AI tool on it is not a broken machine. madelog status says whether sessions are being recorded and why not.
  • A tool log that will not read. Skipped line by line; the commit is recorded either way. madelog: could not read the AI sessions for <sha>: <reason> is printed only when the whole step fails.
  • Refresh failed. madelog: recorded the commit, but could not refresh the page: <reason>, exit 0. The commit is in the log; madelog publish --local renders the page.
  • Binary not found. With the hook line madelog hook post-commit || true and no madelog on the PATH git uses, the shell prints .git/hooks/post-commit: line 5: madelog: command not found and the commit still goes through. Nothing is recorded. GUI clients often start hooks with a short PATH; a per-project install avoids this.
  • Anything else. madelog: could not record this commit: <reason>, exit 0.

hook post-merge does the same for the commit a merge or a git pull leaves at HEAD. It records that one commit, not everything the merge brought in: a hook that quietly recorded a hundred commits would be a surprise rather than a feature. Run madelog backfill after a large pull to pick up the rest.

hook post-rewrite reads <old-sha> <new-sha> pairs on standard input, which is how git reports a rebase or a git commit --amend, and records every new sha the log does not already have. Nothing is marked as rewritten: the old commits stay in the chain, because they did happen. A pair whose second field is not a 40-character sha is ignored, and each new sha is recorded once however often git names it.

$ git rebase -i HEAD~2        # reword the older of the two
$ git log --oneline -2
608441a chore: move the CLI out of main
aa8a3d7 feat: write the unmatched rows to an exceptions report
$ madelog log | tail -3
  14  2026-09-18T11:45:10.989Z  commit     217b80c  chore: move the CLI out of main
  15  2026-09-18T11:45:28.292Z  commit     aa8a3d7  feat: write the unmatched rows to an exceptions report
  16  2026-09-18T11:45:28.326Z  commit     608441a  chore: move the CLI out of main

Event 14 is the commit before the rebase. Events 15 and 16 are the two commits the rebase produced: the reworded one, and the one that had to be re-applied on top of it. Both are recorded, and 14 stays.

All three exit 0 whatever happens, and none of them ever appends an event for a commit the log already has.

Files: .madelog/log.db, .madelog/site/index.html; reads .madelog/config.toml for privacy.redact and, for AI sessions, the tool logs listed in AI sessions. Exit code: always 0.

hook auto

What the global hook calls. You never type this; madelog onboard installs three one-line scripts in ~/.config/madelog/hooks/ that do, once you have answered yes to Record every repository you commit in?.

$ cat ~/.config/madelog/hooks/post-commit
#!/bin/sh
# madelog-cli:global:post-commit - madelog decides what to do in this repository
madelog hook auto post-commit || true

Three outcomes, in order:

  1. The repository has a .madelog/. Does exactly what the hook of that name does.
  2. It does not, and auto_init is on. Runs init non-interactively, with record_ai_sessions taken from ~/.config/madelog/config.toml, then does the hook. One line on standard error: madelog: recording /Users/ana/projects/other from now on.
  3. Neither. Prints madelog: run `madelog init` here to record this project on standard error, once for that repository, ever. The marker is an empty file in ~/.config/madelog/hinted/, named after a hash of the repository's path, so the directory never becomes a list of everything you work on.

Outside a git repository it does nothing at all. The argument is the name of the hook that called it and defaults to post-commit; post-rewrite reads its <old> <new> pairs from standard input as usual, and the script hands the same bytes to any chained hook.

Files: whatever the hook it delegates to touches, plus ~/.config/madelog/hinted/<hash>. Exit code: always 0.

status

One screen: what is recorded, what git has that the log does not, and how this repository is wired up. Read-only; the only thing it touches over the network is Ollama's model list.

$ madelog status
repo         /Users/ana/projects/ledger/
log          17 events chained   ai_session 2, commit 8, decision 1, intent 1, pattern 1, summary 4
last commit  97c43c9  fix: equal amounts with a different reference were counted as a match
             recorded 2026-09-18T12:36:15.920Z   committed 2026-09-18T12:36:15Z
git          every commit on this branch is recorded
hooks        post-commit   calls madelog
             post-merge    calls madelog
             post-rewrite  calls madelog
ai tools     claude-code  transcripts found in /Users/ana/.claude/projects, 1 session touches this repo
             codex        no rollouts in ~/.codex, so nothing to read
             cursor       Cursor keeps conversation bodies encrypted; madelog records that a session happened, 1 session touches this repo
             copilot      not installed
ai sessions  recording
ollama       off (llm.provider = none); summaries use the template
server       https://madelog-server-production.up.railway.app
published    not published
page         /Users/ana/projects/ledger/.madelog/site/index.html

Line by line:

  • log — every event, and how many of each kind. nothing recorded yet — run `madelog init` when there is no log.

  • last commit — the newest commit event: its short sha, its subject, when madelog recorded it and when git says it was made. committed (not recorded) for a commit recorded before madelog carried committed_at.

  • git — commits on the first-parent line from HEAD that the log does not have, with the hint to run madelog backfill:

    git          7 commits in git are not recorded — run `madelog backfill`
  • hooks — one line per hook, the binary its line calls, and a note when that file is gone or the hook was never installed:

    hooks        post-commit   calls /Users/ana/projects/ledger/.madelog/bin/madelog
                 post-merge    not installed — run `madelog doctor --fix`
                 post-rewrite  not installed — run `madelog doctor --fix`
  • ai tools — one line per AI tool madelog knows how to read: what it found on this machine and how many of its sessions touch this repository in the last ninety days.

  • ai sessions — whether the sessions behind your commits are being recorded, and why not when they are not:

    ai sessions  not recording (you said no at `madelog init`; `madelog init --record-ai-sessions` turns it on)
    ai sessions  recording (no sessions have touched this repository yet)
    ai sessions  recording, but no AI tool on this machine keeps a log madelog can read
  • ollama — the host, the configured model and whether it is pulled; off when llm.provider is none.

  • serverserver.url.

  • published — the page's address and when it was last sent, or not published. When .madelog/site/index.html is newer than that, the second line says so:

    published    https://madelog-server-production.up.railway.app/p/north-fable-4xt3
                 last sent 2026-09-18T09:14:02Z — the page on disk is newer; run `madelog publish` again
  • page — where the rendered page is, and whether it has been rendered. A second line appears when the log has moved on since the file was written:

    page         /Users/ana/projects/ledger/.madelog/site/index.html
                 page older than log — `madelog open` renders it again

--json prints the same facts as one object, with repo, events, events_by_kind, last_commit, unrecorded_commits, hooks, git_ai, ollama, server_url, published and page:

$ madelog status --json
{
  "repo": "/Users/ana/projects/ledger/",
  "events": 9,
  "events_by_kind": {
    "commit": 7,
    "decision": 1,
    "intent": 1
  },
  "last_commit": {
    "sha": "8385ec859ee98913716af2f227e788d1cc8d5abe",
    "recorded_at": "2026-09-18T11:42:25.405Z",
    "committed_at": "2026-09-15T07:30:00Z",
    "message": "chore: split the CLI out of main"
  },
  "unrecorded_commits": 0,
  "hooks": [
    {
      "name": "post-commit",
      "installed": true,
      "command": "madelog",
      "command_exists": true
    },
    ...
  ],
  "git_ai": null,
  "ollama": {
    "provider": "none",
    "host": "http://localhost:11434",
    "reachable": false,
    "model": "qwen3:4b",
    "model_ready": false
  },
  "server_url": "https://madelog-server-production.up.railway.app",
  "published": null,
  "page": {
    "path": "/Users/ana/projects/ledger/.madelog/site/index.html",
    "rendered": true,
    "newer_than_publish": false,
    "older_than_log": false
  }
}

ai_tools is an array of {name, installed, note, sessions} — one entry per adapter, sessions being how many of that tool's sessions touch this repository, or null for a tool that is not installed. ai_sessions is the same sentence the plain form prints.

status needs a git repository but not a log. Files: reads .madelog/log.db, .madelog/config.toml and the three hooks. Exit codes: 0; 1 outside a git repository.

capture

Shows the AI sessions a commit would get, and why. A dry run: it opens the same logs the hook opens, uses the window the hook used for that commit, and appends nothing.

$ madelog capture --commit 55e37d5
commit   55e37d5  feat(cli): own AI-session capture (Claude Code, Codex, Cursor, Copilot), automatic hook refresh, global hooks with auto_init, 0.1.1
window   2026-09-18T11:53:37Z to 2026-09-18T12:48:43Z
found    1 session in that window
dry run  nothing was recorded

claude-code  f6a75ad1-60d0-4dbd-a43d-417a147b0171  claude-opus-5
  ran      2026-09-17T20:23:26Z to 2026-09-18T13:02:08Z
  prompt   'PRD Proof of Process.pdf' koristi ovaj prd i napravi to
  wrote    14 files in this window
  would be recorded, accepted = true
    cli/src/capture/mod.rs                           478 ai, 7 reworked
    cli/src/global.rs                                346 ai, 21 reworked
    cli/src/commands/hook.rs                         202 ai, 19 reworked

This exists because the interesting failure is silence. A commit with no ai_session event is not an error — plenty of commits are written by hand — so the hook says nothing, and the only way to tell "no session ran" from "the session was not found" is to ask.

--record appends what the dry run shows, for a commit the hook missed:

$ madelog capture --record --commit 55e37d5
55e37d5  recorded 1 AI session
  claude-code  f6a75ad1-60d0-4dbd-a43d-417a147b0171  3729 AI lines across 14 files

--record --all walks every recorded commit that has no sessions yet, oldest first:

$ madelog capture --record --all
38 commits in the log, 0 commits already answered, 38 to look at.

9d1f891  recorded 1 AI session
  claude-code  f6a75ad1-60d0-4dbd-a43d-417a147b0171  3401 AI lines across 18 files
55e37d5  recorded 1 AI session
  claude-code  f6a75ad1-60d0-4dbd-a43d-417a147b0171  3729 AI lines across 14 files

recorded 2 AI sessions across 2 commits; 36 commits had nothing to attribute
the page is older than the log now — `madelog open` renders it again
  • --commit <sha>. Anything git understands: a full sha, a short sha, a tag, HEAD~2. HEAD when omitted. A commit this repository does not have exits 1 and says so.

  • --json. {commit, message, window: {since, until}, sessions: [...], would_record: [...]}. sessions is what the adapters found, with writes_recorded and how many files each one wrote in the window; would_record is the ai_session payloads the hook would append, exactly as they would be stored.

  • The window. For a commit already in the log it is the window that was in force when madelog recorded it: from the commit before it to the moment it was written down. For one that is not recorded yet, it is the window the next hook run would use. So a replay says what happened, not what would happen now.

  • Nothing to show. No AI session touched this repository in that window., followed by what each adapter found on this machine, so the silence is diagnosable.

  • Recording turned off. The sessions are still shown, with one extra line saying the hook would record none of it.

  • --record. Appends the ai_session events instead of only showing them, anchored to that commit, with the same redaction the hook applies. It only ever adds to a commit that has none: a commit that already has sessions prints 55e37d5 already has 1 AI session. Nothing was recorded; the chain is append-only and what is in it stays as it is. and exits 0, so running it twice is safe. A commit the log does not have is refused with the hint to run madelog backfill first, exit 1. A repository with AI sessions turned off is refused, exit 1 — the dry run still works, so you can see what you are turning down.

  • --record --all. Every recorded commit with no sessions, oldest first, each with the window it actually had. Commits that already have sessions are counted and skipped; commits with nothing to attribute are counted and left alone. Ends with one summary line. Cannot be combined with --commit, and --all on its own is refused: recording is not something to do by accident.

  • What it does not do. Re-render the page or re-run the analysis. Recording moves the log on, so madelog status will say page older than log afterwards and madelog open renders it again.

Files: reads .madelog/log.db, .madelog/config.toml and the tool logs in AI sessions. Writes nothing without --record, and only appends ai_session events with it. Exit codes: 0; 1 outside a repository, without a log, with an unknown commit, or when --record is asked for in a repository that has AI sessions turned off.

doctor

Checks the setup and, with --fix, repairs what is safe to repair. Every line starts with its verdict, so the output greps.

$ madelog doctor
ok    log            17 events, chain verifies, root be71da247ec0
ok    post-commit    calls madelog
ok    post-merge     calls madelog
ok    post-rewrite   calls madelog
ok    git exclude    .madelog/ is excluded
ok    device key     /Users/ana/.config/madelog/device.key is there, mode 0600
ok    claude-code    transcripts found in /Users/ana/.claude/projects, 1 session touches this repo
warn  codex          no rollouts in ~/.codex, so nothing to read
ok    cursor         Cursor keeps conversation bodies encrypted; madelog records that a session happened, 1 session touches this repo
warn  copilot        not installed
ok    ai sessions    recording
ok    ollama         off by configuration (llm.provider = none)
ok    server         https://madelog-server-production.up.railway.app answers

2 things madelog can live without are missing; nothing is broken

Three verdicts, and only one of them sets the exit code:

VerdictMeaning
okNothing to do
warnSomething optional is missing and madelog carries on with less. Exit code unaffected
FAILmadelog's own setup is broken. Exit 1

The checks, in order:

  1. log.madelog/log.db opens and madelog verify would pass. Missing, unopenable or broken is a FAIL.
  2. post-commit, post-merge, post-rewrite — madelog's line is in the hook and names a binary that exists. Missing or dangling is a FAIL.
  3. git exclude.madelog/ is a line in .git/info/exclude. Missing is a FAIL; without it git offers to commit your log.
  4. device key~/.config/madelog/device.key exists and is mode 0600 (on Windows there is no mode to check). Missing or loose is a FAIL.
  5. claude-code, codex, cursor, copilot — whether each AI tool left a log on this machine, and how many of its sessions touch this repository. A tool that is not installed is a warn, never a FAIL: a machine without Cursor on it is a perfectly healthy machine.
  6. ai sessions — whether the sessions behind your commits are being recorded here. ok when they are, warn with the reason when they are not.
  7. ollama — the configured host answers and the configured model is pulled. Neither is a warn; llm.provider = none is an ok.
  8. serverGET <server.url>/healthz answers 200 within 2 seconds. Anything else is a warn: an offline machine is not a broken one.

A failing run prints the same lines and one sentence on standard error, exit 1:

$ madelog doctor
...
FAIL  post-merge     not installed — `madelog doctor --fix` reinstalls it
...
madelog: 1 check failed — `madelog doctor --fix` repairs the hooks, the git exclude entry and the key mode

--fix repairs the hooks, the exclude entry and the key, in place, without asking:

$ madelog doctor --fix
ok    log            17 events, chain verifies, root be71da247ec0
ok    post-commit    calls madelog
ok    post-merge     reinstalled, calls madelog
ok    post-rewrite   calls madelog
ok    git exclude    .madelog/ is excluded
ok    device key     /Users/ana/.config/madelog/device.key is there, mode 0600
ok    claude-code    transcripts found in /Users/ana/.claude/projects, 1 session touches this repo
warn  codex          no rollouts in ~/.codex, so nothing to read
ok    cursor         Cursor keeps conversation bodies encrypted; madelog records that a session happened, 1 session touches this repo
warn  copilot        not installed
ok    ai sessions    recording
ok    ollama         off by configuration (llm.provider = none)
ok    server         https://madelog-server-production.up.railway.app answers

2 things madelog can live without are missing; nothing is broken

Reinstalling a hook removes madelog's own two lines and writes them again with the path of the binary running doctor; everything else in the file is kept, in order. --fix never touches the log: a broken chain is reported and left alone, because a chain that a tool can repair is not evidence of anything.

Files: .git/hooks/*, .git/info/exclude, ~/.config/madelog/device.key with --fix; reads .madelog/log.db and .madelog/config.toml. Exit codes: 0 when nothing failed; 1 when something did.

open

Opens .madelog/site/index.html in your default browser, rendering it first if it is not there yet or if the log has moved on since it was written. The comparison is the newest event's timestamp against the file's modification time, which is the same thing madelog status prints as page older than log.

$ madelog open
opened /Users/ana/projects/ledger/.madelog/site/index.html

--print prints the path and opens nothing, which is what you want in a script or over ssh:

$ madelog open --print
/Users/ana/projects/ledger/.madelog/site/index.html

The page is one self-contained file, so there is no server and no port. The opener is open on macOS, xdg-open on Linux and cmd /C start on Windows; MADELOG_OPENER replaces it.

  • No page yet. Rendered locally first, exactly as madelog publish --local would, without patterns, summaries or the preview, and without contacting anything.
  • A page that is already there is opened as it stands. It is not re-rendered, so run madelog publish --local after new commits if you want the page to be current.
  • The opener fails. madelog: `xdg-open` could not open …. Open it by hand: …, exit 1.
  • No log. madelog: there is no madelog log in /Users/ana/projects/ledger/ — run `madelog init` first, then commit something., exit 1.

Files: writes .madelog/site/index.html when it is missing. Exit codes: 0; 1 without a log or when the opener fails.

log

Prints every event in order.

$ madelog log
   1  2026-09-18T07:53:48.617Z  intent     9659671  A CLI that reconciles bank CSV exports against invoices
   2  2026-09-18T07:53:48.915Z  commit     ec66d42  feat: reconcile skeleton
   3  2026-09-18T07:53:48.935Z  decision   ec66d42  chose SQLite over Postgres: one binary, no service to run
   4  2026-09-18T07:53:48.943Z  decision   ec66d42  the client sends CSVs with a BOM; strip it before parsing (private)
   5  2026-09-18T07:53:49.023Z  commit     77433d9  feat: match bank rows to invoices by amount and reference
   6  2026-09-18T07:53:49.023Z  ai_session 77433d9  claude-code: Write src/reconcile.rs: load two CSVs (amount, reference), index invoices by amount in cents, and count bank rows that match an invoice by amount and reference.

Columns: seq, ts, kind, the first seven characters of commit_sha when there is one, and a title: the intent's what, a commit's subject line, <tool>: <first line of the prompt> or <tool>: (prompt not recorded) for a session, the decision text, <pattern>: <detail>, week of <start> for a summary, hid <id> for a hide. An empty log prints nothing recorded yet.

--json prints a JSON array of every event with every field, pretty-printed. Use it to find an event's id:

$ madelog log --json | grep -B4 '"kind": "ai_session"' | grep '"id"'
    "id": "01a0b381-e2df-7002-92b7-c2716ed68011",

Files: reads .madelog/log.db. Exit codes: 0; 1 without a log.

verify

Recomputes the chain from the first event and prints the root.

$ madelog verify
chain ok
8 events, root fe97dbc626e14dc52a58c6f49352bf0467bed76c7ae4dd4aadc02729ae4f9265

On the first break it prints one line on standard error and exits 1: chain broken at seq 3: hash does not match the event contents (18 events read). The three reasons and how to produce each are in Concepts. An empty log is chain ok, 0 events, and the genesis root of 64 zeros.

Files: reads .madelog/log.db. Exit codes: 0 intact; 1 broken or no log.

export

Writes everything madelog holds about the repository as one JSON document.

$ madelog export ledger-export.json
wrote 16 events to /Users/ana/projects/ledger/ledger-export.json
$ madelog export | head -5
{
  "version": 1,
  "exported_at": "2026-09-18T07:53:49.657Z",
  "intent": {
    "what": "A CLI that reconciles bank CSV exports against invoices",

The path is relative to the current directory. Without one, the document goes to standard output. The shape is {version, exported_at, intent, intent_md, config, root, events}; Privacy describes each field. The export is not signed and is not something the server accepts; it is for you.

Files: reads .madelog/log.db, .madelog/intent.md, .madelog/config.toml; writes the file you name. Exit codes: 0; 1 without a log or when the path cannot be written.

hide

Appends a hide event for one ai_session. The session stays in the chain; the page withholds it.

$ madelog hide 01a0b381-e2df-7002-92b7-c2716ed68011
hidden. The session stays in the chain; the page will say one session is hidden.
  • Any other kind: madelog: only ai_session events can be hidden; event `01a0…` is a commit, exit 1.
  • Unknown id: madelog: no event with id `…` in this log, exit 1.
  • Same session twice: nothing is appended. already hidden. Nothing was recorded; the page already leaves this session out., exit 0. The page still counts one hidden session. There is no unhide.

The preview's h key runs this command. Files: .madelog/log.db. Exit codes: 0; 1.

config get, set, list

Reads or changes .madelog/config.toml. list prints every key, get prints one value, set validates, saves and prints the new value. Errors exit 1 and change nothing. Every key, every validation message and the file's layout are in Configuration.

$ madelog config set llm.provider none
llm.provider = none
$ madelog config get llm.provider
none

config needs a git repository but not a log: it works after git init and before madelog init, creating .madelog/config.toml on the first set. Files: .madelog/config.toml. Exit codes: 0; 1.

publish

Brings patterns and summaries up to date, shows the preview, renders .madelog/site/index.html, and unless --local is given, signs the chain root and uploads the page.

$ madelog publish --yes
1 pattern in this log:
  fix_after_ai  77433d9 8a322f5          8a322f5 reworked AI-written code in src/reconcile.rs less than a minute after 77433d9.
nothing new to record

1 moment for the page:
  1. Fixing AI-written code in src/reconcile.rs (fix_after_ai)
     77433d9 ("feat: match bank rows to invoices by amount and reference") carried AI-written lines in src/reconcile.rs. Less than a minute later, 8a322f5 went back to the same code: "fix: equal amounts with a different reference were counted a...". 27 lines in 77433d9 were written by the model.

every week already has a summary — run `madelog summarize --force` to write them again

page   /Users/ana/projects/ledger/.madelog/site/index.html
page   /Users/ana/projects/ledger/.madelog/site/index.html
verify https://madelog-server-production.up.railway.app/v1/verify/north-fable-4xt3

published  https://madelog-server-production.up.railway.app/p/north-fable-4xt3
Send that link. `madelog unpublish` takes it down again.

The steps, in order:

  1. Refuse outside a repository with a log: madelog: there is no madelog log in /Users/ana/projects/ledger/ — run `madelog init` first, then commit something. `madelog publish` has nothing to publish until then.
  2. Run analyze and summarize exactly as the commands do, output included. With fewer than 15 events print warning: this project has 13 events so far, and a page built from fewer than 15 events says very little. It will still publish. Keep committing and run `madelog publish` again later.
  3. Open the preview, unless --yes is given or standard output is not a terminal. Enter continues; q or Esc stops with publish aborted, exit 1, nothing rendered or sent. Sessions hidden and summaries edited in the preview are appended to the log before anything is rendered, and the lines those commands printed are shown after the preview closes.
  4. Render the page to .madelog/site/index.html and print its path. With --local, print not published. Run `madelog publish` without --local to put it online. and stop, exit 0.
  5. Refuse a page over 2 MiB before uploading it: madelog: the page is <size> MB and the server accepts 2.0 MB at most. It is written at …; hide a session or two with `madelog hide` and publish again.
  6. Register the device (POST /v1/devices) when server.device_id is empty, sign root + "\n" + published_ts + "\n" + slug (slug empty on a first publish) and POST /v1/pages. On 404 (the server no longer knows the device id) register again and retry once.
  7. Save server.device_id and server.slug, render once more with the server's confirmation in the badge, and upload again to the same slug. That is why page is printed twice. A failure at this last step is a warning, not an error: warning: the page is online, but the confirmed badge could not be sent to it (…). Visitors see "not yet published" until the next `madelog publish`.

Flags: --local stops after step 4 and never opens a connection; --server <url> replaces server.url for this run (a bare host gets https://); --yes skips the preview. An empty --server "" is a typo, not a request to fall back to server.url: it is refused before anything is rendered or sent, `--server` needs a url, for example `--server https://madelog.app`. Leave the flag off to use `server.url`, or pass `--local` to stay offline., exit 2 (no madelog: prefix, like the other exit-2 messages).

Failures after the page was written locally, all exit 1:

  • Nothing answering: madelog: could not reach http://127.0.0.1:9/v1/devices: io: Connection refused (os error 61). Your page is written locally either way.
  • A web server that is not madelog: madelog: the server has nothing at that address (registering this device).
  • 401: madelog: the server did not accept this device's signature. Your device key at ~/.config/madelog/device.key does not match the key it has on file — register again from this machine, or publish from the machine that first published this page. The server said: signature does not verify for this device
  • 403: madelog: that page belongs to another device. Publish from the machine that created it, or run `madelog unpublish` there first. The server said: this slug belongs to another device
  • 413: the page is larger than the 2 MB the server accepts. Trim the project page, or publish fewer sessions.
  • 5xx: the server is having trouble. Try again in a minute; your page is already written locally.
  • No server at all (server.url empty and no --server): madelog: no server to publish to. Set one with `madelog config set server.url <url>`, pass `--server <url>`, or stay offline with `madelog publish --local`.

Files: .madelog/log.db (pattern, summary, hide events), .madelog/site/index.html, .madelog/config.toml (server.device_id, server.slug); reads ~/.config/madelog/device.key. Exit codes: 0; 1; 2 for an empty --server.

unpublish

Sends a signed delete for the page this repository owns and clears server.slug.

$ madelog unpublish
north-fable-4xt3 is gone from https://madelog-server-production.up.railway.app. The chain is untouched, and `madelog publish` can put it back.
  • No slug in the config: madelog: this repository has no published page. `madelog publish` first, or check `madelog config get server.slug`., exit 1.
  • The server has already forgotten the page (404): treated as success, the slug is cleared.
  • Another device's page (403), a wrong key (401), an unreachable server: the same messages as publish, exit 1, the slug is kept.

--server <url> names the server the page is on; an empty --server "" is refused with the same message publish gives. Files: .madelog/config.toml; reads the device key. Exit codes: 0; 1; 2 for an empty --server.

analyze

Runs the four pattern rules, appends a pattern event for each new match, and prints the moments the page would show.

$ madelog analyze
4 patterns in this log:
  fix_after_ai  fb7eeec d366a14          d366a14 reworked AI-written code in src/import.rs two hours after fb7eeec.
  retry         fcd9b5f b17e06a 1595716  Three commits in 50 minutes reworked the same file.
  revert        ea23143 50f2f57          Reverted 2 files changed in ea23143 one hour earlier.
  stall         50f2f57 72ddd54          After six days without commits, 72ddd54 changed 12 files (444 lines).
recorded 4 new pattern events

4 moments for the page:
  1. Fixing AI-written code in src/import.rs (fix_after_ai)
     fb7eeec ("feat: csv import with BOM handling") carried AI-written lines in src/import.rs. Two hours later, d366a14 went back to the same code: "fix: importer dropped the last row when the file has no trai...". 51 lines in fb7eeec were written by the model.
  ...

The pattern line shows up to three short shas and +N for the rest. A second run finds the same patterns and prints nothing new to record. With nothing to find: no patterns yet — keep committing and no moments yet — a moment needs a fix after AI, a decision that changed the shape of the project, or a long gap. --json prints {"moments": [...], "patterns": [...]} with full shas and the event ids each moment refers to. Rules and thresholds: Concepts.

Files: .madelog/log.db. Exit codes: 0; 1 without a log.

summarize

Writes a summary event for every week that has none, from Ollama or the template.

$ madelog summarize
Ollama at http://localhost:11434 has no model `qwen3:4b`; writing the summaries from the template (run `ollama pull qwen3:4b` to use it)

week 1  2026-09-14 to 2026-09-20  (generated)  heuristic  01a0b381-e41b-73af-9c25-190f485d0fbd
In the week of 2026-09-14 you made 4 commits over 1 day. Most of the changes landed in src/reconcile.rs, src/main.rs and .gitignore.

You wrote down 1 decision: chose SQLite over Postgres: one binary, no service to run.

The analysis found 1 pattern that week: a fix after an AI session (8a322f5 reworked AI-written code in src/reconcile.rs less than a minute after 77433d9).

edit any of them with `madelog summary edit <id>`

Flags: --week N limits the run to one week; --force rewrites weeks that already have a summary. Every notice, error and the exact request sent to Ollama are in Summaries. Files: .madelog/log.db; reads .madelog/config.toml; talks to llm.host, OLLAMA_HOST or localhost:11434, in that order, unless llm.provider is none. Exit codes: 0; 1 without a log, for a week that does not exist, or when llm.provider is ollama and Ollama or the model is missing.

summary edit

Opens one summary in your editor and appends what you saved as a new summary event with generated_by: user.

$ madelog summary edit 01a0b381-e41b-73af-9c25-190f485d0fbd
week of 2026-09-14 to 2026-09-20  (edited by you)  01a0b381-e442-718d-91c3-12e4160b580d
This week I built the matcher and fixed the equal-amount bug the same afternoon.

I wrote down why SQLite: one binary, nothing to operate.

Unchanged text: unchanged — nothing appended, exit 0. Empty text, an editor that exits non-zero, or an id that is not a summary: exit 1 with the messages listed in Summaries. The editor is MADELOG_EDITOR, EDITOR, VISUAL or vi. Files: .madelog/log.db, a temporary file in the system temp directory. Exit codes: 0; 1.

model pull, ask

Both exist because a later version fills them in. In this version:

$ madelog model pull
`madelog model pull` is not available in this version
$ madelog ask "why did I choose sqlite"
`madelog ask` is not available in this version

Exit code 2, nothing written.

Help text, verbatim

madelog

madelog runs alongside git. It records your commits, your AI sessions and the one-sentence decisions you write down, chains them with sha256, and turns them into a page you can send to a company. Nothing leaves your machine until you run `madelog publish`.

Usage: madelog <COMMAND>

Commands:
  init       Set up madelog in this repository
  onboard    Explain what madelog does, check your tools, and offer to set up this repo
  note       Write down a one-sentence decision
  backfill   Record the commits this repository already had before madelog arrived
  hook       Hooks madelog installs into git. You do not run these by hand
  status     Show what madelog has recorded and how this repository is set up
  capture    Show the AI sessions a commit would get, without recording anything
  doctor     Check the setup, and repair what is safe to repair
  open       Open the rendered page in your browser
  log        Print the recorded events
  verify     Recompute the hash chain and print the root
  export     Write everything madelog has recorded as JSON
  hide       Hide one AI session from the published page
  config     Read or change a configuration value
  publish    Render the project page and publish it
  unpublish  Take the published page down again
  analyze    Look for patterns in the log and record them
  summarize  Write weekly summaries
  summary    Work with existing summaries
  model      Manage the local language model
  ask        Ask a question about this project's history
  help       Print this message or the help of the given subcommand(s)

Options:
  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

madelog init

Set up madelog in this repository

Usage: madelog init [OPTIONS]

Options:
      --what <WHAT>            What are you building?
      --for-whom <FOR_WHOM>    Who is it for?
      --tools <TOOLS>          Which AI tools do you use, comma separated
      --record-ai-sessions     Record the AI sessions behind your commits
      --no-record-ai-sessions  Do not record AI sessions
  -y, --yes                    Do not ask anything; take the answers given and defaults for the rest
      --no-backfill            Do not record the commits this repository already had
  -h, --help                   Print help

madelog onboard

Explain what madelog does, check your tools, and offer to set up this repo

Usage: madelog onboard [OPTIONS]

Options:
      --project  Per-project install: set this repository up without asking
  -y, --yes      Do not ask anything
  -h, --help     Print help

madelog note

Write down a one-sentence decision

Usage: madelog note [OPTIONS] <TEXT>...

Arguments:
  <TEXT>...  The decision, in one sentence

Options:
      --private   Keep this note out of the published page
      --at <SHA>  Anchor the note to this commit instead of HEAD. A short sha will do
  -h, --help      Print help

madelog backfill

Record the commits this repository already had before madelog arrived

Usage: madelog backfill [OPTIONS]

Options:
      --since <DATE|SHA>  The oldest commit to record: a sha, or a date like 2026-01-31
  -y, --yes               Do not ask before recording
  -h, --help              Print help

madelog hook

Hooks madelog installs into git. You do not run these by hand

Usage: madelog hook <COMMAND>

Commands:
  post-commit   Record the commit that was just made
  post-merge    Record the commit a merge or a pull left at HEAD
  post-rewrite  Record the commits a rebase or an amend produced
  auto          Decide what to do in whatever repository git is committing in
  help          Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help

madelog hook post-commit

Record the commit that was just made

Usage: madelog hook post-commit

Options:
  -h, --help  Print help

madelog hook post-merge

Record the commit a merge or a pull left at HEAD

Usage: madelog hook post-merge

Options:
  -h, --help  Print help

madelog hook post-rewrite

Record the commits a rebase or an amend produced

Usage: madelog hook post-rewrite

Options:
  -h, --help  Print help

madelog hook auto

Decide what to do in whatever repository git is committing in.

This is what the global hook calls. It records the commit if madelog is set up here, sets madelog up first if you asked for that at onboarding, and otherwise says so once and stays out of the way.

Usage: madelog hook auto [HOOK]

Arguments:
  [HOOK]
          Which git hook called this
          
          [default: post-commit]

Options:
  -h, --help
          Print help (see a summary with '-h')

madelog status

Show what madelog has recorded and how this repository is set up

Usage: madelog status [OPTIONS]

Options:
      --json  Print the status as JSON
  -h, --help  Print help

madelog capture

Show the AI sessions a commit would get, without recording anything

Usage: madelog capture [OPTIONS]

Options:
      --commit <SHA>  The commit to explain. HEAD when omitted; a short sha will do
      --record        Append the ai_session events instead of only showing them
      --all           With --record: every recorded commit that has no sessions yet
      --json          Print the sessions and the attribution as JSON
  -h, --help          Print help

madelog doctor

Check the setup, and repair what is safe to repair

Usage: madelog doctor [OPTIONS]

Options:
      --fix   Repair what is safe to repair: the hooks and the git exclude entry
  -h, --help  Print help

madelog open

Open the rendered page in your browser

Usage: madelog open [OPTIONS]

Options:
      --print  Print the path instead of opening it
  -h, --help   Print help

madelog log

Print the recorded events

Usage: madelog log [OPTIONS]

Options:
      --json  Print the events as JSON
  -h, --help  Print help

madelog verify

Recompute the hash chain and print the root

Usage: madelog verify

Options:
  -h, --help  Print help

madelog export

Write everything madelog has recorded as JSON

Usage: madelog export [PATH]

Arguments:
  [PATH]  Where to write the JSON. Prints to stdout when omitted

Options:
  -h, --help  Print help

madelog hide

Hide one AI session from the published page

Usage: madelog hide <EVENT_ID>

Arguments:
  <EVENT_ID>  The id of the ai_session event to hide

Options:
  -h, --help  Print help

madelog config

Read or change a configuration value

Usage: madelog config <COMMAND>

Commands:
  get   Print a configuration value
  set   Change a configuration value
  list  Print every key and its value
  help  Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help

madelog config get

Print a configuration value

Usage: madelog config get <KEY>

Arguments:
  <KEY>  

Options:
  -h, --help  Print help

madelog config set

Change a configuration value

Usage: madelog config set <KEY> <VALUE>

Arguments:
  <KEY>    
  <VALUE>  

Options:
  -h, --help  Print help

madelog config list

Print every key and its value

Usage: madelog config list

Options:
  -h, --help  Print help

madelog publish

Render the project page and publish it

Usage: madelog publish [OPTIONS]

Options:
      --local            Render the page to .madelog/site/index.html and stop there
      --server <SERVER>  The server to publish to
  -y, --yes              Skip the preview
  -h, --help             Print help

madelog unpublish

Take the published page down again

Usage: madelog unpublish [OPTIONS]

Options:
      --server <SERVER>  The server the page is on
  -h, --help             Print help

madelog analyze

Look for patterns in the log and record them

Usage: madelog analyze [OPTIONS]

Options:
      --json  Print the patterns and moments as JSON
  -h, --help  Print help

madelog summarize

Write weekly summaries

Usage: madelog summarize [OPTIONS]

Options:
      --week <WEEK>  Only rebuild one week, counted from the first commit
      --force        Write a new summary even for weeks that already have one
  -h, --help         Print help

madelog summary

Work with existing summaries

Usage: madelog summary <COMMAND>

Commands:
  edit  Edit a summary in $EDITOR
  help  Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help

madelog summary edit

Edit a summary in $EDITOR

Usage: madelog summary edit <EVENT_ID>

Arguments:
  <EVENT_ID>  

Options:
  -h, --help  Print help

madelog model

Manage the local language model

Usage: madelog model <COMMAND>

Commands:
  pull  Download the local model
  help  Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help

madelog model pull

Download the local model

Usage: madelog model pull

Options:
  -h, --help  Print help

madelog ask

Ask a question about this project's history

Usage: madelog ask [QUESTION]...

Arguments:
  [QUESTION]...  

Options:
  -h, --help  Print help