Metadata-Version: 2.3
Name: daily-worklog
Version: 0.1.0
Summary: Plain-markdown work-log helper CLI
Author: Vu LE
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Dist: typer==0.27.3
Requires-Python: ==3.14.*
Project-URL: Repository, https://github.com/ldkv/daily-worklog
Project-URL: Documentation, https://github.com/ldkv/daily-worklog/blob/main/README.md
Project-URL: Changelog, https://github.com/ldkv/daily-worklog/releases
Description-Content-Type: text/markdown

# daily-worklog

A plain-markdown, git-backed engineering log. One note per day is the only thing you write; every cadence (standup, sprint review, retro, annual review, CV) is a _read_ over that same stream. No app required - `grep`, `git`, and one small Python CLI (`note`).

## Layout

This repo is the app; your notes live in a separate folder (the _root_, `~/worklog` by default):

```
~/worklog/
├── daily/
│   └── YYYY-MM-DD.md     # your daily notes
├── weekly/
│   └── YYYY-Www.md       # auto-generated sprint/week rollups
├── retro/
│   └── YYYY-Www.md       # auto-generated standalone retro docs
└── highlights/
    └── YYYY[-Qn|-Hn].md  # auto-generated wins per period → feeds review + CV
```

```
daily-worklog/            # this repo
├── src/worklog/
│   ├── cli.py            # commands
│   ├── core.py           # logic
│   └── _TEMPLATE.md      # per-day template for new notes
└── tests/
```

## The one rule

Capture at the **daily** grain, roll **up**. Don't keep separate notes per ceremony — you'll reconstruct from memory and lose to recency bias. Two habits make the whole thing pay off:

- **Separate facts from friction.** `## Done`/`## Wins` answer _what shipped_ (standup, review, highlights). `## Friction` answers _how the work went_ (retro). Logging friction in the moment is what makes retros concrete instead of vibes.
- **Log impact, not activity.** Not "refactored the scheduling API" but "collapsed the SSE ack/PATCH round-trip, removing a class of idempotency bugs." Capture the number/consequence and a PR/ticket link _now_ — you won't recall it in eleven months.

## How each section feeds each cadence

| Section       | Standup | Sprint review | Retro | Review / CV |
| ------------- | :-----: | :-----------: | :---: | :---------: |
| `## Done`     |    ●    |       ●       |       |             |
| `## Blockers` |    ●    |               |   ●   |             |
| `## Wins`     |         |       ●       |       |      ●      |
| `## Friction` |         |               |   ●   |             |

`## Wins` lines carry `[impact:: …] [proof:: …] #win`. At review time you don't reconstruct the year from memory: `note highlights` collects every win of the period, grouped by month, and that file _is_ your self-review draft. So write each win the way you'd want to read it then — outcome + number + scope, never "worked on X" — and when you learn the metric later (incident count avoided, latency delta, review-cycle time), add it to the original line in that day's note.

## Install

Requires [uv](https://docs.astral.sh/uv/).

```bash
uv tool install daily-worklog # puts `note` on your PATH; -e picks up code edits live
note init                     # asks where to keep notes [~/worklog]
                              # (or: note init --worklog-path ~/somewhere/else)
```

`note init` creates `daily/` (never touching existing files) and records the root in `~/.config/worklog/config.toml` (`$XDG_CONFIG_HOME` is honoured):

```toml
root = "/home/you/worklog"
```

Root lookup: `$WORKLOG_ROOT` → `root` in the config file → `~/worklog`. If that folder doesn't exist, `note` exits with an error asking you to run `note init`; it never writes anywhere else. `python -m worklog` works too.

New notes are created from the template bundled with the app (`src/worklog/_TEMPLATE.md`); it isn't customisable per root yet. Appending to a section today's note doesn't have (e.g. you deleted the heading) is an error.

## Usage

```bash
note                  # create + open today's note ($EDITOR, default vi)
note done    "text"   # append under ## Done
note win     "text"   # append under ## Wins     (tags #win)
note improve "text"   # append under ## Friction (tags #friction); alias: friction
note well    "text"   # append under ## Retro    (tags #well)
note try     "text"   # append under ## Retro    (tags #try)
note blocker "text"   # append under ## Blockers
note plan    "text"   # append under ## Plan
note jot     "text"   # append under ## Notes
note week             # build this ISO week's rollup + retro agenda (weekly/)
note retro            # build this ISO week's standalone retro doc (retro/)
note highlights [P]   # collect wins for period P, by month (highlights/)
                      #   P = YYYY | YYYY-Qn | YYYY-Hn, default: this year
note init             # create a root and record it in the config file
                      #   (--worklog-path PATH skips the prompt)
note help             # list commands (same as --help)
```

Append commands never open an editor and add the tag for you — don't type it. Quotes are optional, and text may start with `-` (`note win -50% p99 latency`).

If the rollup already exists, `note week` / `note retro` / `note highlights` rebuild it in memory and compare: unchanged → it just opens; changed → it prints a diff and asks `overwrite? [y/N]` (any hand edits show up as removed lines). Answering no — or running without a terminal — keeps the existing file. `--force` / `-f` overwrites without asking.

Daily ritual: `note`, fill `## Done` first thing (yesterday's, for standup), top up `## Wins`/`## Friction` as the day goes. End of sprint: `note week` and skim. Review time: `note highlights 2026` (or `2026-H2`, …). Put the root under git and commit on whatever cadence suits you — it's just text, so `git` is your full history and backup.

### Pure-grep alternatives (no script needed)

```bash
rg '#win'      daily/                # every win, ever
rg '#friction' daily/ -A0            # retro fuel
rg '\[impact::' daily/               # everything with a measured outcome
```

## Development

Check [Taskfile.yml](Taskfile.yml) for dev tasks.

## TODO

Deferred ideas, not yet planned:

- **Custom daily template**: let `<root>/daily/_TEMPLATE.md` override the bundled one (today the bundled template is always used).
- **Auto-format notes**: tidy a note after each append / editor session: trailing whitespace, extra blank lines, `*`/`+` bullets → `-`. A full formatter (mdformat needs `mdformat-frontmatter`) is the heavier option. Editor sessions need a blocking `$EDITOR` (e.g. `code --wait`).
