feat: weekly usage digest CLI command - #82
Conversation
Verification ReportVerdict: PASS (with one bug found and fixed) Method: Cold-start via Steps
Bug fixed in this review
Observations for maintainer
|
There was a problem hiding this comment.
Pull request overview
Adds a new copilot-lens digest CLI subcommand that produces a “Wrapped-style” usage summary for a selected period (week by default, with --last-week / --month) with optional JSON output and Markdown export.
Changes:
- Introduces
getDigest(period)to aggregate session counts, active days, durations, tool usage, token totals, and “prior period” comparisons. - Adds an Ink-based TUI (
cli-digest.tsx) plus--save(writesdigest.md) and--jsonmodes. - Wires the new
digestsubcommand into the main CLI and adds argument-parsing tests.
Show a summary per file
| File | Description |
|---|---|
| src/digest.ts | New digest aggregation logic over sessions + token usage + CLI event scanning. |
| src/cli-digest.tsx | New Ink TUI and CLI entrypoint for copilot-lens digest, including --save and --json. |
| src/cli.ts | Adds digest subcommand routing and updates top-level help text. |
| src/tests/cli-digest.test.ts | Adds unit tests for parseDigestArgs. |
Copilot's findings
- Files reviewed: 4/4 changed files
- Comments generated: 7
| fs.writeFileSync(outPath, md, "utf-8"); | ||
| process.stderr.write(`Saved digest to ${outPath}\n`); |
There was a problem hiding this comment.
Fixed — wrapped writeFileSync in a try/catch. On error it now prints a clear message to stderr and sets process.exitCode = 1, while the TUI still renders.
| if (opts.save) { | ||
| const data = getDigest(opts.period); | ||
| const md = toMarkdown(data); |
There was a problem hiding this comment.
Fixed — DigestApp now accepts an optional precomputed prop. In --save mode the result from the first getDigest() call is passed directly as precomputed, so the TUI skips the second computation entirely.
| export function getDigest(period: DigestPeriod = "week"): DigestData { | ||
| const { cur, prior } = getBounds(period); | ||
| const allSessions = listSessions(); |
There was a problem hiding this comment.
Added 7 Vitest tests in src/__tests__/cli-digest.test.ts covering: required fields, totalDays for week/month periods, rangeLabel format, priorTokens shape, longestSession shape, and ISO date string validity.
| Commands: | ||
| (default) Start the web dashboard | ||
| tokens Show token usage in the terminal (Ink TUI) | ||
| digest Show a weekly usage summary in the terminal |
There was a problem hiding this comment.
Fixed — updated the help description in src/cli.ts from "weekly" to "period-based" to accurately reflect that --last-week and --month are also supported.
| const HELP = ` | ||
| Usage: copilot-lens digest [options] | ||
|
|
||
| Print a weekly usage summary to the terminal (Spotify Wrapped-style). |
There was a problem hiding this comment.
Fixed — updated the HELP string in src/cli-digest.tsx to say "period-based" instead of "weekly" so it matches the actual supported options.
|
Hey @pavanvamsi3 — all 7 Copilot reviewer comments have been addressed. Could you take another look when you get a chance? Thanks! |
Adds `copilot-lens digest` — a Spotify Wrapped-style terminal summary of AI usage for the current week, last week, or current month. - src/digest.ts: date-range aggregation over sessions and token data - src/cli-digest.tsx: Ink TUI showing active days, sessions, time, tokens (with ▲/▼ % vs prior period), top repo/hour/tool/model, and longest session; --save writes digest.md; --json for scripting - Wire into cli.ts under the `digest` subcommand - Tests for parseDigestArgs covering all flags and edge cases Closes #70 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
end is already set to 23:59:59.999, so Math.round(6.999...) already gives 7; adding 1 made week show 8, June show 31. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Read events.jsonl from end of file so large sessions reflect the most recent activity for tool counts and duration - Remove all-time topModel fallback — only show model from the selected period's token data to avoid stale/misleading values - Wrap fs.writeFileSync in try/catch; print clear error and set non-zero exitCode on failure without blocking TUI render - Pass pre-computed DigestData to DigestApp when --save is used to avoid calling getDigest() twice - Fix help text: "weekly" → "period-based" in cli.ts and cli-digest.tsx - Add 7 getDigest() tests covering all three periods, field shapes, date string format, and boundary invariants Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
d6f631b to
b895784
Compare
|
Merge conflicts resolved — rebased onto latest main. The branch is now clean and ready for re-review. |
Summary
Implements the
copilot-lens digestcommand from issue #70 — a Spotify Wrapped-style terminal summary of AI usage.Sample output:
Changes
src/digest.ts—getDigest(period)aggregates sessions fromlistSessions()filtered by date range; scans CLI event files for tool usage, accurate duration, and turn counts; pulls token totals fromgetTokenUsage().dailybuckets filtered to the range. No new data sources.src/cli-digest.tsx— Ink TUI mirroringcli-tokens.tsxstyle;--savewritesdigest.md;--jsonoutputs raw JSON for piping.src/cli.ts— wiresdigestsubcommand and updates help text.src/__tests__/cli-digest.test.ts— 8 tests covering allparseDigestArgscombinations.Test plan
copilot-lens digestrenders the weekly summarycopilot-lens digest --last-weekshows prior week labelcopilot-lens digest --monthshows current month labelcopilot-lens digest --jsonoutputs valid JSON with all fieldscopilot-lens digest --savewritesdigest.mdand also renders TUIcopilot-lens digest --helpshows usage textCloses #70
🤖 Generated with Claude Code