daybook

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: MIT

README

daybook

What you actually got done today — not just what you committed.

Daily work reports built from your Claude Code sessions and your git history.

Monday, 24 August 2026
6.4h active · 4 streams · 92 prompts · 17 commits +2,140/-431 · 3 repos

## Summary
Most of the day went to the CSV importer, which turned out to be two problems:
the parser, and a mapping UI that made the parser's failures unreadable. The
Postgres upgrade was opened, scoped, and put down again once the replica lag
turned out to be unrelated.

### Sun 21:10–Mon 15:42 · CSV import mapping          shipped
Get bulk contact import working end to end, including the column mapping step.

Streamed the parse instead of buffering it after a 40MB file exhausted memory
on staging. Then found by importing a real customer export that unmapped
columns were silently dropped rather than reported — fixed that, and reworked
the mapping table to show which columns had no destination.

- **Decided.** Import is idempotent per chunk rather than per file, so a
  half-finished run resumes instead of starting over.
- **Open.** Shipped to main, not yet run against a file over 100MB.

**Shipped** (3 exact, 5 inferred)
- api@4f2a91cd    Stream the CSV parse instead of buffering it     +312/-88
- web@8b30ee14    Show columns that map to nothing                 +204/-31

### 11:20–13:05 · Replica lag investigation           no ship
Work out why the read replica fell 90 seconds behind overnight.

Traced it to a nightly vacuum, not to the import work. No code change needed.

## Not off this machine
| repo | branch | unpushed | uncommitted |
| api  | main   |        2 |           7 |

Install

macOS / Linux

curl -fsSL https://github.com/humanikio/daybook/releases/latest/download/install.sh | sh

Windows (PowerShell)

irm https://github.com/humanikio/daybook/releases/latest/download/install.ps1 | iex

With Go

go install github.com/humanikio/daybook/cmd/daybook@latest

Every release binary is signed with cosign keyless signing and shipped with checksums. To verify before running:

sha256sum -c checksums.txt --ignore-missing

cosign verify-blob \
  --certificate-identity-regexp "^https://github.com/humanikio/daybook/" \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --signature daybook-darwin-arm64.sig daybook-darwin-arm64

Installs to ~/.local/bin — user-level, no sudo, because daybook reads your transcripts and your git identity and runs as you. Needs git; claude and gh are optional.

Quickstart

daybook init      # guided setup — points it at your repos, ~30 seconds
daybook scan      # read the last 24h, join against git, write the report
daybook day       # read it

That's the whole loop. scan takes about five seconds and is safe to run as often as you like.


Written to be handed to someone else

The top of every report is what shipped, grouped by capability rather than by commit — because fourteen commits that together let you write a SQL transform on an ingest hook are one thing that happened, not fourteen.

**You can now test an ingest transform against payloads that actually
arrived, choose which ones to run it against, and see how old each is.**

`readRecentPayloads.ts` reads live rows alongside stored test sends,
`collectSamples.ts` merges the two and accepts an explicit list of payload
ids, and the controller returns provenance per sample. The frontend adds
`PayloadPicker.tsx`, a multi-select modelled on the field mapping editor.

*Look at:*
- `src/ingest/services/collectSamples.ts`
- `src/app/sources/[sourceId]/transform/page.tsx`

`api@7d26888f` · `web@0949b796` on **main**

Plain language first, then the mechanism for whoever maintains it, then the files and the branch. Every commit appears in exactly one entry — a day with sixty commits does not get five bullet points.

Work with no user-facing surface still gets an entry, flagged Internal, so readers skip on the flag rather than on silence.

And a section for what nobody else can see yet — unpushed commits with their subjects, and uncommitted files, per branch. A count says something is missing; the subjects say what.

What it's for

Your commit log records what landed. It does not record what happened, and the gap runs in the direction that makes you look worse.

Measured over one real week: commits per hour swung 13× between days. The heaviest day — twelve hours, 143 prompts — produced six commits, because the day's output was an architecture decision rather than code. The next day, the same threads executing, produced 34. Work also lands a day after it happens, so a commit graph lags reality and inverts exactly when the thinking was hardest.

daybook reads both sides and says which is which.

How people use it

End of day — "what did I actually do?"

daybook scan && daybook day

Every stream of work, in the order it ran, with the commits attributed to it and the ones that never left your machine.

Standup, without trying to remember

daybook day yesterday

The Summary section is written to be readable aloud.

Catching up after you install it

daybook backfill 2w        # build the fortnight before you had this
daybook backfill 30 --narrate
daybook backfill --from 2026-08-01 --to 2026-08-14

Everything it needs for last month is already on disk. It tells you how far back your transcripts actually go, and days with nothing are skipped rather than written as empty files.

Weekly review, or an invoice line

daybook week

A per-day table plus every stream that spanned more than one day. Because the shape of a week is exactly what a weekly total hides.

Finding work you dropped

daybook open

Everything you did that hasn't finished proving itself — shipped-but-untested, blocked, unverified in prod — oldest first. Items past 14 days get flagged. This is the list nobody keeps by hand and everybody needs.

Proving where the time went

Contractors, agencies, and anyone billing by project: the report groups by repo or by business (business: in config), and every figure traces to a commit or a timestamp. Nothing is estimated.

A day with no commits at all

Research, ops runs, a client call, a data room. Those days look empty in git and are fully recorded here — that's most of the point.

Pointing it somewhere new

daybook watch ~/clientwork --depth 3
daybook watch                        # what am I watching?
daybook schedule 22:00 --days mon,tue,wed,thu,fri
daybook config set narrate.enabled true

Unattended

daybook service install

Report waiting for you every morning. See docs/schedule.md.


Commands

daybook init            guided setup
daybook scan            read the window, join against git, write the report
daybook day [date]      print a report — date, today, or yesterday
daybook week [date]     rollup for the week containing date
daybook backfill [7|2w] build the days from before you installed it
daybook narrate [date]  add prose and reconcile the open ledger
daybook open            work that has not finished proving itself
daybook close <id>      close a ledger item by hand
daybook reopen <id>     undo a close
daybook serve           run the scheduler in the foreground
daybook service …       install | uninstall | start | stop | restart | status
daybook watch [<path>]  add a repo root, or list what is watched
daybook unwatch <path>  stop watching a path
daybook schedule [time] show or change when the daily run happens
daybook config [set …]  show the config, or change one value
daybook verify          check config, sources, repos, parse health
daybook version

Flags: --config PATH, --window 48h, --stdout, --narrate.


How it works

Discovery. Any session that received a prompt in the last 24 hours. How long it has been open is irrelevant — over half of real sessions span multiple days and some run a week, so the stream is the unit and the day is a view over streams.

Extraction. Your prompts and the assistant's replies. In a 24-hour window 73% of the text is on the assistant's side — that's where "found three bugs by running it" lives. A record built from prompts alone throws away three quarters of itself.

The join. Commits from git log, matched to streams in two tiers, and the report always prints the split rather than one clean number:

  • exact — the stream touched a file this commit changed. Provable.
  • inferred — same repo, and the stream was live nearest the commit time.

On real data that lands around 40% exact. A commit no stream can claim is listed as unattributed rather than guessed. Once attributed it's pinned and never re-judged, so today's run can't reshuffle yesterday's report.

Ship state. Four states, because done / not done can't express the one that matters most:

state meaning
shipped on the remote
local committed, never pushed — at risk
open active, changes still in the tree
stale silent for stale_after, never shipped

No git fetch needed: git push updates the local tracking ref, so the unpushed count is already right for anything sent from this machine.


Prose summaries (optional)

daybook scan --narrate                     # this run only
daybook config set narrate.enabled true    # every run, including the nightly
daybook narrate 2026-08-24                 # after the fact

A plain daybook scan never narrates — it is cheap, offline and idempotent, and narration is neither. Adds what git structurally cannot: what you were trying to do, what actually happened, decisions no commit records, and what's still unproven.

Two providers. cli (default) spawns the claude you're already signed in with — no key, no setup — and runs it with no tools under dontAsk, so the step cannot touch your filesystem. api uses the Anthropic API instead if you'd rather not spend that quota (≈$1/day). Neither passes a key through daybook.

Every sha and path in the model's output must appear in its input, or the narration is discarded and the deterministic report stands alone. A record about what you did is worthless if it can invent a commit.

Full detail: docs/narration.md.


Privacy

  • Nothing leaves your machine. No telemetry, no sync, no network calls.
  • Redaction runs before anything is written — AWS keys, bearer tokens, GitHub tokens, private keys. Add your own under privacy.redact, or set keep_raw_prompts: false to store no prompt text at all.
  • Output is 0600. Keep the output directory private — it holds your prompt history. Don't put it inside a public repo.

docs/privacy.md

Caveats

This parses an undocumented format. ~/.claude/projects/*.jsonl is internal to Claude Code and carries no compatibility guarantee — one reference corpus spanned 27 CLI versions. Parsing fails soft per line rather than per file, and daybook verify reports the parse-failure rate so breakage is visible rather than silent. It will break eventually; please open an issue.

Stream titles come from Claude and describe where a session started, not what it's doing now. A session kept open for a week keeps its original name. Narration reads what actually happened instead of trusting the title.

Docs

setup · narration · schedule · privacy · record format · troubleshooting

Licence

MIT. See LICENSE.

A note on names

daybook is an independent open-source project. It is not built, endorsed, sponsored by, or affiliated with Anthropic. "Claude" and "Claude Code" are trademarks of Anthropic, referred to here only to describe what this tool reads.

The transcript reader is one adapter behind an interface — other coding agents can be added without touching the join or the renderer. Today there is one, and it reads Claude Code.

Directories

Path Synopsis
cmd
daybook command
Command daybook reports what you actually worked on each day, read from your Claude Code transcripts and joined against what genuinely shipped.
Command daybook reports what you actually worked on each day, read from your Claude Code transcripts and joined against what genuinely shipped.
internal
config
Package config loads ~/.daybook/config.yaml.
Package config loads ~/.daybook/config.yaml.
derive
Package derive is the join: streams on one side, commits on the other, and the rules that decide how far each piece of work has got.
Package derive is the join: streams on one side, commits on the other, and the rules that decide how far each piece of work has got.
ledger
Package ledger keeps the running list of work that has not finished proving itself.
Package ledger keeps the running list of work that has not finished proving itself.
model
Package model is the single definition of daybook's schema.
Package model is the single definition of daybook's schema.
narrate
Package narrate turns the derived facts into prose.
Package narrate turns the derived facts into prose.
render
Package render turns a day into something to read, and into the facts it was read from.
Package render turns a day into something to read, and into the facts it was read from.
schedule
Package schedule decides when the next run is due.
Package schedule decides when the next run is due.
source
Package source is the adapter seam.
Package source is the adapter seam.
source/claudecode
Package claudecode reads Claude Code's session transcripts.
Package claudecode reads Claude Code's session transcripts.
svc
Package svc runs daybook as a native OS service — launchd on macOS, systemd on Linux, a logon task on Windows — and drives install/uninstall/start/stop.
Package svc runs daybook as a native OS service — launchd on macOS, systemd on Linux, a logon task on Windows — and drives install/uninstall/start/stop.
tui
Package tui is the small amount of interactivity daybook needs: a list you move through with the arrow keys.
Package tui is the small amount of interactivity daybook needs: a list you move through with the arrow keys.
vcs
Package vcs reads git — repository discovery, commit history, and how far each piece of work has travelled.
Package vcs reads git — repository discovery, commit history, and how far each piece of work has travelled.
wizard
Package wizard is the guided first-run setup.
Package wizard is the guided first-run setup.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL