From 65199cafa77b70fa4928c8ede49bae80cfb4c915 Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Thu, 8 Oct 2026 07:21:44 -0500 Subject: [PATCH] Add what-was-i-doing skill Reconstruct past activity from an artifact's mtime: day-in-repos.sh lists one day's commits and reflog entries (pulls, checkouts, clones: local events git log never shows) across every repo locate knows. Generated-by: Claude Opus 5.5 --- what-was-i-doing/SKILL.md | 75 ++++++++++++++++++++++++++++++++ what-was-i-doing/day-in-repos.sh | 52 ++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 what-was-i-doing/SKILL.md create mode 100755 what-was-i-doing/day-in-repos.sh diff --git a/what-was-i-doing/SKILL.md b/what-was-i-doing/SKILL.md new file mode 100644 index 0000000..7038f47 --- /dev/null +++ b/what-was-i-doing/SKILL.md @@ -0,0 +1,75 @@ +--- +name: what-was-i-doing +description: What was I doing on ? Reconstruct past activity on this machine — use when the operator asks what they were doing on a day, where a stray file / install / symlink came from, or "why is this here?"; when a timestamp (ls, stat, cache dir) is the only clue. Correlates file mtimes with git commits and reflogs across every repo `locate` finds. +--- + +# What was I doing? Timestamps as a diary + +The machine already keeps a diary; it's just scattered. A mystery artifact +(a stray `~/.bun`, an odd symlink, a cache dir) carries an mtime. Line that +time up against git activity across all repos, and the project usually +falls out within a few minutes. + +## 1. Pin the clue's timestamp to the minute + +```sh +ls -la --time-style=+'%F %H:%M' ~/.bun ~/.bun/* ~/.local/bin/bunx +``` + +Look at the artifact *and its neighbors*: the directory, its children, and +anything that points at it (symlink targets, `readlink`). The newest mtime +inside a cache says when it was last used. Caches also say *what* was +used: `ls ~/.bun/install/cache`, `~/.npm/_cacache`, `~/.cache/pip`. +A cache full of `@vitejs`, `@reduxjs`, `@tailwindcss` means a frontend +build. + +## 2. Sweep every repo for that day + +[day-in-repos.sh](day-in-repos.sh) lists commits *and reflog entries* for +one day across every repo in the `locate` database. Reflog is the important +half: pulls, checkouts, rebases, and amends are local-only, never show in +`git log`, and are often exactly what you did that day. + +```sh +.agents/skills/what-was-i-doing/day-in-repos.sh 2026-05-25 | grep -v heartbeat +.agents/skills/what-was-i-doing/day-in-repos.sh 2026-05-25 --author=dckc +``` + +- Extra args go to `git log`. `--author` cuts upstream and bot commits, but + reflog rows are never filtered. They're always yours. +- A commit shared by several clones/worktrees prints once, listing them all. +- Reflog begins at `clone: from ` and is pruned by `git gc` (default + 90 days, 30 for unreachable), so older days may be patchy. The mtime of + `.git/FETCH_HEAD` gives the last fetch even when the reflog doesn't. +- The `locate` DB is rebuilt nightly. Repos created today are missing; + `sudo updatedb` if that matters. +- Filter noise with `grep -v`. Bot heartbeats and dependabot bumps + flood some repos. + +## 3. Correlate, then confirm in the candidate repo + +Look for repo activity within minutes of the artifact's mtime. Then confirm +inside that repo: does it reference the tool (`git grep -i bun`, CI +workflows, lockfiles), and do its build outputs (`node_modules`, `dist`) +carry matching mtimes? + +Report it as a timeline table: time, event, source. Say which links +are evidence and which are inference ("probably linked by hand"). + +## Other diaries, when git is quiet + +- `journalctl --user --since ... --until ...`: user units, systemd-run. +- Shell history: `~/.bash_history` has timestamps only if `HISTTIMEFORMAT` + was set; `.tmp/*.script` typescripts (see the watchme skill). +- File mtimes broadly: `find ~ -xdev -newermt 2026-05-25 ! -newermt + 2026-05-26 -not -path '*/node_modules/*' -not -path '*/.cache/*'` + ([fselect](https://github.com/jhspetersson/fselect) does the same in SQL, + if installed). + +## Worked example + +`~/.local/bin/bunx` → `~/.bun/bin/bun` (1.3.14), both 2026-05-25 12:27. +The sweep showed `projects/pinchtab` reflog: pull 12:19, forced-update +12:35, checkout `v0.13.0` 12:36. `pinchtab/dashboard/` has a `bun.lock`, +CI runs `bun install`, and `dashboard/node_modules` was created at 12:28. +Conclusion: bun was installed to build pinchtab's dashboard for v0.13.0. diff --git a/what-was-i-doing/day-in-repos.sh b/what-was-i-doing/day-in-repos.sh new file mode 100755 index 0000000..0d214b5 --- /dev/null +++ b/what-was-i-doing/day-in-repos.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# List git activity on one day across every repo `locate` knows about. +# +# Usage: day-in-repos.sh YYYY-MM-DD [git-log-args...] +# +# Prints commits (by committer date) and reflog entries (pulls, checkouts, +# amends: local-only events that `git log` never shows), sorted by local +# time. A commit present in several clones/worktrees is printed once, with +# every repo it appears in. Extra args go to `git log`, e.g. --author=dckc +# to drop bot and upstream commits. +set -euo pipefail + +[[ $# -ge 1 && $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || { + sed -n '2,10p' "$0" + exit 2 +} +day=$1 +shift +next=$(date -d "$day + 1 day" +%F) + +locate -r '/\.git$' \ + | grep "^$HOME/" \ + | grep -v -e /node_modules/ -e /.cache/ -e /.cargo/ -e /go/pkg/ \ + | while read -r g; do + r=${g%/.git} + name=${r#"$HOME"/} + git -C "$r" log --all --since="$day 00:00" --until="$next 00:00" \ + --date=format:%H:%M --format="%cd %h $name %s" "$@" 2>/dev/null || true + git -C "$r" reflog --all --date=format:'%F %H:%M' \ + --format="%gd $name %gs" 2>/dev/null \ + | awk -F'\t' -v day="$day" ' + match($1, /\{[0-9-]+ [0-9:]+\}/) { + ts = substr($1, RSTART + 1, RLENGTH - 2) + if (substr(ts, 1, 10) == day) + printf "%s\treflog\t%s\t%s\n", substr(ts, 12), $2, $3 + }' || true + done \ + | awk -F'\t' ' + # group by time+hash (reflog rows by time+subject) + { key = ($2 == "reflog") ? $1 FS $4 : $1 FS $2 + if (!(key in repos)) { order[++n] = key; line[key] = $0 } + if (!((key, $3) in seen)) { + seen[key, $3] = 1 + repos[key] = repos[key] (repos[key] ? " " : "") $3 + } } + END { + for (i = 1; i <= n; i++) { + split(line[order[i]], f, FS) + printf "%s %-7s %s [%s]\n", f[1], f[2], f[4], repos[order[i]] + } + }' \ + | sort