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
| Code | When |
|---|---|
| 0 | The command did its job. --help, -h, --version, -V and madelog help <command> also exit 0 and print to standard output |
| 1 | The 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 |
| 2 | Wrong 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
| Path | What |
|---|---|
.madelog/log.db | The event log, SQLite, append-only. log.db-wal and log.db-shm sit next to it |
.madelog/config.toml | Settings; see Configuration |
.madelog/intent.md | Your answers from madelog init as Markdown, a copy for you; the page reads the intent event |
.madelog/site/index.html | The rendered page, written by every madelog publish |
.madelog/bin/madelog | The binary, in a per-project install only |
.git/hooks/post-commit | Two lines under # madelog-cli:post-commit |
.git/hooks/post-merge | Two lines under # madelog-cli:post-merge |
.git/hooks/post-rewrite | Two lines under # madelog-cli:post-rewrite |
.git/info/exclude | One line, .madelog/ |
~/.config/madelog/device.key | The 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
intentevent,initwith none of--what,--for-whomor--toolsasks nothing, appends nothing and leavesintent.mdalone; it printsmadelog is already recording in /Users/ana/projects/ledger/andNothing changed. Pass --what, --for-whom or --tools to record a new intent., exit 0. Give any of those three and a newintentevent is appended with the answers merged over the newest one: the flags you passed win, the ones you left out carry over,record_ai_sessionsincluded unless--record-ai-sessionsor--no-record-ai-sessionssays otherwise.intent.mdis rewritten to match. The old intent stays in the chain, and the hook, the page andmadelog exportall 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
initagain, ormadelog doctor --fix, to add them back. core.hooksPathset. 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 forpost-mergeandpost-rewrite, unless the binary runs from<repo>/.madelog/bin/, in which case its full path is written, quoted when it has spaces. SeeMADELOG_EXEin 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 bygit initandmadelog 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 logandmadelog verify.--yesand--projectdo not change that — nothing is appended andintent.mdis left alone. --yesanswers yes and then runsinitwith--yes, so the intent is empty.--projectdoes the same and is what the per-project installer runs. An interactive yes runsinitwith its questions.- The box-drawing banner needs a terminal,
TERMother thandumb, and a UTF-8 locale (Windows Terminal on Windows). Everything else gets the ASCII banner shown above. - Every repository. Answering
ytoRecord every repository you commit in? [y/N]asks two more questions —Set madelog up in a new repository without asking? [Y/n]andRecord the AI sessions behind those commits? [Y/n]— writes both answers to~/.config/madelog/config.tomlasauto_initandrecord_ai_sessions, installspost-commit,post-mergeandpost-rewritein~/.config/madelog/hooks/, and sets git's globalcore.hooksPathto that directory. Acore.hooksPaththat was already set is chained: madelog's script runs first and then calls the hook of the same name in the old directory, passingpost-rewritethe same standard input. Acore.hooksPaththat is already madelog's own directory is left alone. Re-runningonboardafterwards printsEvery repository: on.and asks nothing. --yesand--projectnever 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. --atnames 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 bymadelog logwith(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;nprintsNothing changed.and appends nothing.--since <date|sha>. The oldest commit to record, inclusive. AYYYY-MM-DDdate 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:
- 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 oneai_sessionevent per session. See AI sessions. - Patterns. Runs the four rules over the log and appends a
patternevent for anything not already recorded. - 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.
- 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.rsOn 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
commitevent 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 statussays 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 --localrenders the page. - Binary not found. With the hook line
madelog hook post-commit || trueand nomadelogon the PATH git uses, the shell prints.git/hooks/post-commit: line 5: madelog: command not foundand 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 mainEvent 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 || trueThree outcomes, in order:
- The repository has a
.madelog/. Does exactly what the hook of that name does. - It does not, and
auto_initis on. Runsinitnon-interactively, withrecord_ai_sessionstaken from~/.config/madelog/config.toml, then does the hook. One line on standard error:madelog: recording /Users/ana/projects/other from now on. - Neither. Prints
madelog: run `madelog init` here to record this projecton 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.htmlLine 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
commitevent: 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 carriedcommitted_at. -
git — commits on the first-parent line from
HEADthat the log does not have, with the hint to runmadelog 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;
offwhenllm.providerisnone. -
server —
server.url. -
published — the page's address and when it was last sent, or
not published. When.madelog/site/index.htmlis 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 reworkedThis 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.HEADwhen omitted. A commit this repository does not have exits 1 and says so. -
--json.{commit, message, window: {since, until}, sessions: [...], would_record: [...]}.sessionsis what the adapters found, withwrites_recordedand how many files each one wrote in the window;would_recordis theai_sessionpayloads 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 theai_sessionevents 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 prints55e37d5 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 runmadelog backfillfirst, 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--allon 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 statuswill saypage older than logafterwards andmadelog openrenders 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 brokenThree verdicts, and only one of them sets the exit code:
| Verdict | Meaning |
|---|---|
ok | Nothing to do |
warn | Something optional is missing and madelog carries on with less. Exit code unaffected |
FAIL | madelog's own setup is broken. Exit 1 |
The checks, in order:
- log —
.madelog/log.dbopens andmadelog verifywould pass. Missing, unopenable or broken is aFAIL. - 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. - git exclude —
.madelog/is a line in.git/info/exclude. Missing is aFAIL; without it git offers to commit your log. - device key —
~/.config/madelog/device.keyexists and is mode 0600 (on Windows there is no mode to check). Missing or loose is aFAIL. - 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 aFAIL: a machine without Cursor on it is a perfectly healthy machine. - ai sessions — whether the sessions behind your commits are being recorded here.
okwhen they are,warnwith the reason when they are not. - ollama — the configured host answers and the configured model is pulled. Neither is a
warn;llm.provider = noneis anok. - server —
GET <server.url>/healthzanswers 200 within 2 seconds. Anything else is awarn: 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 brokenReinstalling 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.htmlThe 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 --localwould, 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 --localafter 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 fe97dbc626e14dc52a58c6f49352bf0467bed76c7ae4dd4aadc02729ae4f9265On 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
noneconfig 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:
- 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. - Run
analyzeandsummarizeexactly as the commands do, output included. With fewer than 15 events printwarning: 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. - Open the preview, unless
--yesis given or standard output is not a terminal.Entercontinues;qorEscstops withpublish 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. - Render the page to
.madelog/site/index.htmland print its path. With--local, printnot published. Run `madelog publish` without --local to put it online.and stop, exit 0. - 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. - Register the device (
POST /v1/devices) whenserver.device_idis empty, signroot + "\n" + published_ts + "\n" + slug(slug empty on a first publish) andPOST /v1/pages. On 404 (the server no longer knows the device id) register again and retry once. - Save
server.device_idandserver.slug, render once more with the server's confirmation in the badge, and upload again to the same slug. That is whypageis 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.urlempty 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 versionExit 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 versionmadelog 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 helpmadelog 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 helpmadelog 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 helpmadelog 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 helpmadelog 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 helpmadelog hook post-commit
Record the commit that was just made
Usage: madelog hook post-commit
Options:
-h, --help Print helpmadelog hook post-merge
Record the commit a merge or a pull left at HEAD
Usage: madelog hook post-merge
Options:
-h, --help Print helpmadelog hook post-rewrite
Record the commits a rebase or an amend produced
Usage: madelog hook post-rewrite
Options:
-h, --help Print helpmadelog 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 helpmadelog 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 helpmadelog 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 helpmadelog open
Open the rendered page in your browser
Usage: madelog open [OPTIONS]
Options:
--print Print the path instead of opening it
-h, --help Print helpmadelog log
Print the recorded events
Usage: madelog log [OPTIONS]
Options:
--json Print the events as JSON
-h, --help Print helpmadelog verify
Recompute the hash chain and print the root
Usage: madelog verify
Options:
-h, --help Print helpmadelog 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 helpmadelog 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 helpmadelog 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 helpmadelog config get
Print a configuration value
Usage: madelog config get <KEY>
Arguments:
<KEY>
Options:
-h, --help Print helpmadelog config set
Change a configuration value
Usage: madelog config set <KEY> <VALUE>
Arguments:
<KEY>
<VALUE>
Options:
-h, --help Print helpmadelog config list
Print every key and its value
Usage: madelog config list
Options:
-h, --help Print helpmadelog 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 helpmadelog unpublish
Take the published page down again
Usage: madelog unpublish [OPTIONS]
Options:
--server <SERVER> The server the page is on
-h, --help Print helpmadelog 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 helpmadelog 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 helpmadelog 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 helpmadelog summary edit
Edit a summary in $EDITOR
Usage: madelog summary edit <EVENT_ID>
Arguments:
<EVENT_ID>
Options:
-h, --help Print helpmadelog 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 helpmadelog model pull
Download the local model
Usage: madelog model pull
Options:
-h, --help Print helpmadelog ask
Ask a question about this project's history
Usage: madelog ask [QUESTION]...
Arguments:
[QUESTION]...
Options:
-h, --help Print help