From 6592d528db97670f73ba47597af03f5e26db1108 Mon Sep 17 00:00:00 2001 From: Patrick Honkonen Date: Fri, 1 May 2026 11:37:34 -0400 Subject: [PATCH 1/8] feat: Add daily-recap plugin Generates polished, interactive HTML recaps of a person's daily work. Initial release ships with the engineering-recap skill, which combines Claude Code session activity with GitHub events into a standup-ready, colleague-shareable artifact tuned to the Bitwarden brand palette (Bitwarden Blue, Teal, Inter font, brand shield). Session extraction is delegated to claude-retrospective:extracting-session-data to avoid duplicating retrieval logic. --- .claude-plugin/marketplace.json | 6 + README.md | 3 +- .../daily-recap/.claude-plugin/plugin.json | 19 + plugins/daily-recap/CHANGELOG.md | 17 + plugins/daily-recap/README.md | 46 + .../skills/engineering-recap/SKILL.md | 88 ++ .../engineering-recap/assets/template.html | 1219 +++++++++++++++++ .../references/render-guide.md | 92 ++ .../scripts/gather-gh-events.sh | 65 + 9 files changed, 1554 insertions(+), 1 deletion(-) create mode 100644 plugins/daily-recap/.claude-plugin/plugin.json create mode 100644 plugins/daily-recap/CHANGELOG.md create mode 100644 plugins/daily-recap/README.md create mode 100644 plugins/daily-recap/skills/engineering-recap/SKILL.md create mode 100644 plugins/daily-recap/skills/engineering-recap/assets/template.html create mode 100644 plugins/daily-recap/skills/engineering-recap/references/render-guide.md create mode 100755 plugins/daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index c9dfb91..9aba2fd 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -16,6 +16,12 @@ "version": "1.1.1", "description": "Comprehensive analysis of Claude Code sessions to identify successful patterns, problematic areas, and opportunities for improvement." }, + { + "name": "daily-recap", + "source": "./plugins/daily-recap", + "version": "1.0.0", + "description": "Generate polished, interactive HTML recaps of a person's daily work. Pulls activity from the relevant systems, shapes it into a standup-ready, colleague-shareable artifact, and applies Bitwarden brand styling." + }, { "name": "claude-config-validator", "source": "./plugins/claude-config-validator", diff --git a/README.md b/README.md index 0ffa8f7..1f0681d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A curated collection of plugins for AI-assisted development at Bitwarden. Enable | Plugin | Version | Description | | ------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------- | -| [bitwarden-tech-lead](plugins/bitwarden-tech-lead/) | 2.0.0 | Software architect for technical planning, architecture reviews, and implementation phasing | +| [bitwarden-tech-lead](plugins/bitwarden-tech-lead/) | 2.0.0 | Software architect for technical planning, architecture reviews, and implementation phasing | | [bitwarden-atlassian-tools](plugins/bitwarden-atlassian-tools/) | 2.2.3 | Read-only Atlassian access via MCP server with deep Jira issue research skill | | [bitwarden-code-review](plugins/bitwarden-code-review/) | 1.10.0 | Autonomous code review agent following Bitwarden engineering standards with GitHub integration | | [bitwarden-delivery-tools](plugins/bitwarden-delivery-tools/) | 1.0.0 | Generic delivery workflow skills for committing, PR creation, preflight checks, and change labeling | @@ -17,6 +17,7 @@ A curated collection of plugins for AI-assisted development at Bitwarden. Enable | [bitwarden-software-engineer](plugins/bitwarden-software-engineer/) | 0.4.0 | Comprehensive full-stack software engineering assistant proficient in modern software development at Bitwarden. | | [claude-config-validator](plugins/claude-config-validator/) | 1.1.1 | Validates Claude Code configuration files for security, structure, and quality | | [claude-retrospective](plugins/claude-retrospective/) | 1.1.1 | Analyze Claude Code sessions to identify successful patterns and improvement opportunities | +| [daily-recap](plugins/daily-recap/) | 1.0.0 | Generate polished, interactive HTML recaps of a person's daily work with Bitwarden brand styling | ## Usage diff --git a/plugins/daily-recap/.claude-plugin/plugin.json b/plugins/daily-recap/.claude-plugin/plugin.json new file mode 100644 index 0000000..e5b55b9 --- /dev/null +++ b/plugins/daily-recap/.claude-plugin/plugin.json @@ -0,0 +1,19 @@ +{ + "name": "daily-recap", + "version": "1.0.0", + "description": "Generate polished, interactive HTML recaps of a person's daily work. Pulls activity from the relevant systems, shapes it into a standup-ready, colleague-shareable artifact, and applies Bitwarden brand styling.", + "author": { + "name": "Bitwarden", + "url": "https://github.com/bitwarden" + }, + "homepage": "https://github.com/bitwarden/ai-plugins/tree/main/plugins/daily-recap", + "repository": "https://github.com/bitwarden/ai-plugins", + "keywords": [ + "daily-recap", + "standup", + "summary", + "retrospective", + "activity-tracking", + "interactive-html" + ] +} diff --git a/plugins/daily-recap/CHANGELOG.md b/plugins/daily-recap/CHANGELOG.md new file mode 100644 index 0000000..1e46802 --- /dev/null +++ b/plugins/daily-recap/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +All notable changes to the Daily Recap Plugin will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] - 2026-05-01 + +### Added + +- Initial release with `engineering-recap` skill — generates an interactive HTML recap of the user's engineering work for a given day +- 7am Eastern day-boundary handling (late-night work folds into the prior workday) +- Bundled HTML template tuned to the Bitwarden brand palette (Bitwarden Blue, Teal, Inter font, brand shield) +- Bundled `gather-gh-events.sh` script that pulls GitHub events scoped to the user's workday window +- Bundled `render-guide.md` reference covering placeholder map and HTML injection recipes +- Cross-plugin integration with `claude-retrospective:extracting-session-data` for session extraction diff --git a/plugins/daily-recap/README.md b/plugins/daily-recap/README.md new file mode 100644 index 0000000..ac51ff2 --- /dev/null +++ b/plugins/daily-recap/README.md @@ -0,0 +1,46 @@ +# Daily Recap + +Generate polished, interactive HTML recaps of a person's daily work. Pulls activity from the relevant systems, shapes it into a standup-ready, colleague-shareable artifact, and applies Bitwarden brand styling. + +## Skills + +| Skill | Purpose | +| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `engineering-recap` | Generates a recap of the user's engineering work — Claude Code session activity combined with GitHub events (PRs, reviews, comments, pushes, branch ops, repo creates, sweeps). Produces an interactive HTML page with a copy-ready standup card, project workstreams, GitHub timeline, and theme block. | + +## Usage + +The `engineering-recap` skill triggers on retrospective queries about the user's own coding work — phrases like: + +- _"what did I work on yesterday?"_ +- _"recap please"_ +- _"standup prep"_ +- _"summarize my work this morning"_ +- _"create me a daily recap for april 28 to show colleagues"_ + +The output is saved to `~/Documents/daily-recap/recap-{YYYY-MM-DD}.html` and opened in the default browser. + +## Day boundary + +The skill treats **7am Eastern** as the day boundary, not midnight UTC. Late-night work folds into the prior calendar day. A "Today / Fresh" banner appears only when there is post-7am-Eastern activity on the current day. + +## Dependencies + +- `claude-retrospective` — session extraction is delegated to `claude-retrospective:extracting-session-data`. Install this plugin first. +- `gh` CLI authenticated against GitHub — required for the events feed and PR title enrichment. +- `jq` — required by bundled scripts. + +## Files + +``` +daily-recap/ +├── .claude-plugin/plugin.json +├── CHANGELOG.md +├── README.md +└── skills/ + └── engineering-recap/ + ├── SKILL.md + ├── assets/template.html — Bitwarden-branded HTML scaffold + ├── scripts/gather-gh-events.sh — Events feed window helper + └── references/render-guide.md — Placeholder map + HTML recipes +``` diff --git a/plugins/daily-recap/skills/engineering-recap/SKILL.md b/plugins/daily-recap/skills/engineering-recap/SKILL.md new file mode 100644 index 0000000..41fa0be --- /dev/null +++ b/plugins/daily-recap/skills/engineering-recap/SKILL.md @@ -0,0 +1,88 @@ +--- +name: engineering-recap +description: Generates the user's engineering daily recap as an interactive HTML deliverable combining Claude Code sessions with GitHub events. **YOUR FIRST ACTION** for any retrospective query about the user's own coding work MUST be to invoke this skill — do NOT gather context first or respond with an inline summary. Trigger phrases include time words ("yesterday", "this morning", "last night", "this week", "before lunch", any past date); activity questions ("what did I work on/ship/merge/push", "what was I doing"); single-word retrospectives ("recap", "summary", "standup", "1:1 prep"); deliverable verbs ("throw together", "pull together", "summarize", "analyze sessions"); audience cues ("show colleagues", "for my manager"); format mentions ("html page", "interactive recap"). The user expects the HTML artifact every time, not a chat summary. SKIP only for specific PR/commit/ticket lookups, someone else's activity, meeting recaps, or repo-level overviews. +--- + +# Engineering Recap + +Generate a polished, interactive HTML recap of the user's engineering work for standup, 1:1s, or sharing with colleagues. + +## Day boundary: 7am Eastern + +The user works late, especially during Stanley Cup season. **Window for "yesterday" = (yesterday 7am Eastern) → (today 7am Eastern)** — UTC `11:00Z→11:00Z` during EDT, `12:00Z→12:00Z` during EST. Late-night work folds into the prior day. The "Today/Fresh" banner only shows events from 7am Eastern onward. + +## Workflow + +### 1. Gather data (in parallel) + +These are independent — run in parallel: + +**(a) GitHub events** — bundled script handles the EDT/EST window: + +```bash +${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/scripts/gather-gh-events.sh YYYY-MM-DD > /tmp/recap-events.json +``` + +**(b) Claude Code sessions** — delegate to the `claude-retrospective:extracting-session-data` skill (which handles the project-id path mangling, noise-directory exclusion, and content vs mtime quirks). Use its `filter-sessions.sh --since` and `extract-data.sh --type user-prompts --session ID` to pull the data; do not roll your own `find` / `jq` over the JSONL. + +### 2. Capture all GitHub event types — not just PR creation + +`PullRequestEvent` (opened/closed/merged/labeled), `PullRequestReviewEvent` (approved/commented), `PullRequestReviewCommentEvent` (inline diff comments — capture body + path), `IssueCommentEvent`, `PushEvent` (branch + head SHA), `CreateEvent` (branches **and brand-new repositories** — check `ref_type`), `DeleteEvent` (post-merge cleanup). + +**Sweep detection:** 3+ approvals in a 5-minute window across different repos with similar titles → surface as a single "cross-repo sweep" stream, not N separate items. + +### 3. Enrich PR titles in one batched call + +Don't loop `gh pr view`. Build a single GraphQL query with aliases for each PR: + +```bash +gh api graphql -f query='{ a: repository(owner:"bitwarden",name:"android"){pullRequest(number:6851){title author{login} state}} b: repository(...) }' +``` + +For tiny PR sets (<5), parallel `gh pr view` calls are fine. + +### 4. Summarize sessions + +For each session in scope, ask `claude-retrospective:extracting-session-data` for the user prompts, tool usage, and statistics. Filter to entries where `.timestamp` falls inside the window — sessions can span multiple days. + +**When to dispatch parallel servitors:** Only when there are 3+ projects each with 3+ substantive sessions. For typical days (≤2 projects, or many small sessions), inline summarization is faster and cheaper. + +### 5. Synthesize themed streams + +Group by feature/theme — **not one card per session**. Two sessions on the same PR = one stream. A typical day produces 3–8 streams across 1–4 projects. Each stream: title (the theme, not the session ID), status (`completed`/`open`/`deferred`), 3–8 specific bullets (file paths, commit SHAs, PR numbers + titles). + +Cross-reference: branch creates / pushes that match worktree work → tag with `Session: {title}`. Approvals don't usually map to a session. + +### 6. Render the HTML + +Copy the template to the recap output, then fill the `{{...}}` placeholders: + +```bash +cp ${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/assets/template.html ~/Documents/daily-recap/recap-{YYYY-MM-DD}.html +``` + +CSS is tuned to the Bitwarden brand palette — don't regenerate it. `${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/references/render-guide.md` has the full placeholder map and HTML recipes for the more complex injection points (project sections, timeline events, today banner). + +PR refs use `#NNNN`. Always include PR titles (a bare `#6849` is useless). Late-night events (00:00Z–7am Eastern today) get a `🌙 After Midnight` divider in the timeline view, _not_ the Today banner — the Today banner is only for post-7am events on the current calendar day. + +### 7. Open in browser + +```bash +open ~/Documents/daily-recap/recap-{YYYY-MM-DD}.html +``` + +Summarize to the user: stats, headline theme, and that the standup card has a Copy button. + +## Style + +Bitwarden brand palette + Inter font (already in template). Keep prose colleague-presentable. If the user requests a non-default tone (e.g. "neutral", "for sharing externally"), adjust the prose and footer accordingly without touching the CSS. + +## Bundled resources + +- `assets/template.html` — HTML scaffold with `{{...}}` placeholders. +- `scripts/gather-gh-events.sh` — pulls events feed with the 7am Eastern window applied. +- `references/render-guide.md` — placeholder map + HTML recipes (read only when you need a specific injection shape). + +## Plugin dependency + +This skill expects the `claude-retrospective` plugin to be installed for session extraction. Specifically: `claude-retrospective:extracting-session-data`. diff --git a/plugins/daily-recap/skills/engineering-recap/assets/template.html b/plugins/daily-recap/skills/engineering-recap/assets/template.html new file mode 100644 index 0000000..de16e17 --- /dev/null +++ b/plugins/daily-recap/skills/engineering-recap/assets/template.html @@ -0,0 +1,1219 @@ + + + + + + Daily Recap — {{DATE}} + + + + + + +
+
+
+ +
+ Bitwarden·Engineering Daily Recap +
+
+
Daily Recap · Interactive
+

Engineering Log {{DATE}}

+

{{SUBTITLE}}

+ +
+
+
{{STAT_REPOS}}
+
Repos Touched
+
+
+
{{STAT_SESSIONS}}
+
Sessions
+
+
+
{{STAT_PRS_OPENED}}
+
PRs Opened
+
+
+
{{STAT_PRS_APPROVED}}
+
PRs Approved
+
+
+
{{STAT_GH_EVENTS}}
+
GH Events
+
+
+
+ + {{TODAY_BANNER}} + +
+
+
Standup Recap · 30s read
+
+ Yesterday · {{DATE}} + +
+
+
+
+

What I shipped

+
    + {{STANDUP_SHIPPED}} +
+
+ +
+
+ +
+
+ + {{PROJECT_CHIPS}} +
+
+
+ + + + +
+
+
+ + +
+ +
+ +
+ {{PROJECT_SECTIONS}} +
+ +
+
+ {{STAT_GH_EVENTS}} GitHub events in window. Cross-references + to in-session work shown with the ⟶ marker. Overnight events + sit at the bottom (newest last). +
+
{{TIMELINE_EVENTS}}
+
+ +
+

Theme of the Day

+ {{THEME_PARAGRAPHS}} +
+ Open threads: {{OPEN_THREADS}} +
+
+ +
+
+ Bitwarden — Engineering Daily Recap +
+ Generated from Claude Code session archives & GitHub events + · {{GENERATED_AT}} +
+
+ + + + diff --git a/plugins/daily-recap/skills/engineering-recap/references/render-guide.md b/plugins/daily-recap/skills/engineering-recap/references/render-guide.md new file mode 100644 index 0000000..01b4de2 --- /dev/null +++ b/plugins/daily-recap/skills/engineering-recap/references/render-guide.md @@ -0,0 +1,92 @@ +# Render Guide — daily-recap template + +The template at `assets/template.html` uses `{{...}}` placeholders. Most are self-explanatory; this guide covers the HTML shapes you need to inject for `{{PROJECT_SECTIONS}}`, `{{TIMELINE_EVENTS}}`, and `{{TODAY_BANNER}}`. CSS is already tuned to the Bitwarden brand palette — don't regenerate. + +## Placeholders + +Self-explanatory: `{{DATE}}`, `{{SUBTITLE}}`, `{{STAT_*}}`, `{{STANDUP_SHIPPED}}`, `{{STANDUP_NEXT}}`, `{{THEME_PARAGRAPHS}}`, `{{OPEN_THREADS}}`, `{{GENERATED_AT}}`. The interesting ones below. + +`{{PROJECT_CHIPS}}` — one per project: `` + +`{{TODAY_BANNER}}` — empty string if no post-7am-Eastern events. Otherwise: + +```html +
+
+
+ Since the recap · Fresh today · {today date} +
+
    +
  • + {HH:MMZ}{Tag}{event} +
  • +
+
+
+``` + +Tags: `New Repo`, `Sweep`, `Merged`, `Approval`. + +## Stream card + +```html +
+
+
+ Stream title +
+ ● Status +
+
+
    +
  • + Bullet with file paths, + #1234 +
  • +
+
+
+``` + +Status semantics: `completed` = work landed (PR merged, decision made, fix shipped). `open` = WIP, not pushed/merged, pending review. `deferred` = intentionally postponed. + +## Project section + +```html +
+
+
{emoji}
+
{org/repo or theme}
+
{N sessions · M streams}
+
+ +
+``` + +## Timeline event + +```html +
+
+ {HH:MM:SSZ}{Label} +
+
{repo} · {body}
+ +
{body excerpt}
+ + +
+``` + +For pre-7am-Eastern "today" events that belong to yesterday, insert this divider in the timeline before them: + +```html +
+ 🌙 After Midnight · Late-Night Tail (still yesterday's workday) +
+``` diff --git a/plugins/daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh b/plugins/daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh new file mode 100755 index 0000000..624f220 --- /dev/null +++ b/plugins/daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# Pull GitHub events for the user and filter to the 7am-Eastern workday window. +# +# Usage: +# gather-gh-events.sh [date] +# date: yesterday's date in YYYY-MM-DD form (Eastern). Defaults to yesterday. +# +# Output: JSON array of events with summary fields, written to stdout. +# Side effects: caches raw events at /tmp/gh-events-raw-${date}.json +# +# Requires: gh, jq, GNU or BSD date + +set -euo pipefail + +DATE="${1:-$(date -u -v-1d +%Y-%m-%d 2>/dev/null || date -u -d 'yesterday' +%Y-%m-%d)}" +LOGIN="$(gh api user --jq .login)" + +# Determine if the target date is during EDT (March–November) or EST (November–March). +# Approximation: months 3–11 EDT (UTC-4), months 12,1,2 EST (UTC-5). +# This is good enough for daily-recap purposes; refine if DST exact dates matter. +MONTH=$(echo "$DATE" | cut -d- -f2) +if [[ "$MONTH" -ge 3 && "$MONTH" -le 11 ]]; then + OFFSET_HOURS=11 # 7am EDT = 11:00Z + TZ_LABEL="EDT" +else + OFFSET_HOURS=12 # 7am EST = 12:00Z + TZ_LABEL="EST" +fi + +START="${DATE}T$(printf '%02d' $OFFSET_HOURS):00:00Z" +# End = next day at the same offset +NEXT_DATE=$(date -u -j -v+1d -f "%Y-%m-%d" "$DATE" +%Y-%m-%d 2>/dev/null \ + || date -u -d "$DATE + 1 day" +%Y-%m-%d) +END="${NEXT_DATE}T$(printf '%02d' $OFFSET_HOURS):00:00Z" + +echo "# Window: $START → $END (7am $TZ_LABEL boundary)" >&2 + +CACHE="/tmp/gh-events-raw-${DATE}.json" +gh api "users/${LOGIN}/events?per_page=100" > "$CACHE" + +# Filter to window and emit a compact summary +jq --arg start "$START" --arg end "$END" ' + [.[] + | select(.created_at >= $start and .created_at < $end) + | { + time: .created_at, + type, + repo: .repo.name, + action: (.payload.action // null), + pr: (.payload.pull_request.number // .payload.issue.number // null), + pr_title: (.payload.pull_request.title // .payload.issue.title // null), + pr_author: (.payload.pull_request.user.login // .payload.issue.user.login // null), + pr_state: (.payload.pull_request.state // null), + pr_merged: (.payload.pull_request.merged // null), + pr_draft: (.payload.pull_request.draft // null), + review_state: (.payload.review.state // null), + comment_body: (.payload.comment.body // null) | (if . then .[0:300] else null end), + comment_path: (.payload.comment.path // null), + ref: (.payload.ref // null), + ref_type: (.payload.ref_type // null), + head_sha: (.payload.head[0:9] // null), + commit_msgs: ([.payload.commits[]? | .message | split("\n")[0]]) + } + ] +' "$CACHE" From 5e72becbd761812af11603905a259828e8500d17 Mon Sep 17 00:00:00 2001 From: Patrick Honkonen Date: Fri, 1 May 2026 11:56:33 -0400 Subject: [PATCH 2/8] Add hydrated engineering-recap sample for review and styling delta tracking --- plugins/daily-recap/README.md | 6 + .../examples/engineering-recap-sample.html | 1941 +++++++++++++++++ 2 files changed, 1947 insertions(+) create mode 100644 plugins/daily-recap/examples/engineering-recap-sample.html diff --git a/plugins/daily-recap/README.md b/plugins/daily-recap/README.md index ac51ff2..6e5edf7 100644 --- a/plugins/daily-recap/README.md +++ b/plugins/daily-recap/README.md @@ -37,6 +37,8 @@ daily-recap/ ├── .claude-plugin/plugin.json ├── CHANGELOG.md ├── README.md +├── examples/ +│ └── engineering-recap-sample.html — Hydrated example with fake data └── skills/ └── engineering-recap/ ├── SKILL.md @@ -44,3 +46,7 @@ daily-recap/ ├── scripts/gather-gh-events.sh — Events feed window helper └── references/render-guide.md — Placeholder map + HTML recipes ``` + +## Example + +Open [`examples/engineering-recap-sample.html`](examples/engineering-recap-sample.html) (one sample per skill) for a hydrated view of the produced report. The file uses fake data (persona "Alex Carter", date 2026-05-04) and exercises every section — stats, today banner, standup card with copy button, project chips and filters, collapsible streams across 5 projects, full GitHub timeline with cross-references and an after-midnight tail, and the theme block. diff --git a/plugins/daily-recap/examples/engineering-recap-sample.html b/plugins/daily-recap/examples/engineering-recap-sample.html new file mode 100644 index 0000000..cf346ef --- /dev/null +++ b/plugins/daily-recap/examples/engineering-recap-sample.html @@ -0,0 +1,1941 @@ + + + + + + Daily Recap — 2026-05-04 + + + + + + +
+
+
+ +
+ Bitwarden·Engineering Daily Recap +
+
+
Daily Recap · Interactive
+

Engineering Log 2026-05-04

+

+ A coordinated cross-platform notification-preferences day — + server endpoint scaffolded, web vault settings panel built + to spec, mobile push opt-in shipped, and an org-wide + accessibility audit sweep approved across five tooling + repos. +

+ +
+
+
6
+
Repos Touched
+
+
+
8
+
Sessions
+
+
+
3
+
PRs Opened
+
+
+
7
+
PRs Approved
+
+
+
22
+
GH Events
+
+
+
+ +
+
+
+ Since the recap · Fresh today · 2026-05-05 +
+
    +
  • + 12:14ZNew RepoCreated + private repo + AlexCarter/notification-prefs-spike + for prototyping the GraphQL gateway shape +
  • +
  • + 11:47ZPushed CI hot-fix to + release/2026.05 on + bitwarden/server + · head 9f3d27b1a + — migration timeout repro from yesterday's red + build +
  • +
+
+
+ +
+
+
Standup Recap · 30s read
+
+ Yesterday · 2026-05-04 + +
+
+
+
+

What I shipped

+
    +
  • + Wired up new + GET/PUT /api/notification-preferences + endpoint on server PR #5621 — + controller, service, and migration all in place +
  • +
  • + Built the web vault notification settings panel + to spec on clients PR #20455 — + channels, frequency, quiet-hours all functional +
  • +
  • + mobile PR #2780 merged — + push-notification opt-in now wired through + PushNotificationService.swift +
  • +
  • + Approved 7 PRs across 6 repos — + incl. the 5-PR PM-90123 accessibility audit + sweep at 09:43–09:47Z (theMickster) plus android + #6921 and ios #2614 +
  • +
  • + ai-plugins #112 merged — typo + fix in the retrospecting skill + description +
  • +
+
+ +
+
+ +
+
+ + + + + + +
+
+
+ + + + +
+
+
+ + +
+ +
+ +
+ +
+
+
⚙️
+
bitwarden/server
+
3 sessions · 2 streams
+
+ +
+
+
+ Notification preferences endpoint · PR + #5621 +
+ ◐ Open +
+
+
    +
  • + New + NotificationPreferencesController.cs + with + GET /api/notification-preferences + and + PUT /api/notification-preferences + — channel toggles + per-event-type opt-in. +
  • +
  • + Service layer in + Core/Services/NotificationPreferencesService.cs; encryption-at-rest preserved (preferences + are zero-knowledge per Bitwarden P03). +
  • +
  • + EF Core migration + 20260504_AddNotificationPreferences.cs + — additive, no destructive changes. +
  • +
  • + Unit + integration tests at + Test.Server/.../NotificationPreferencesControllerTests.cs + (14 cases, all passing locally). +
  • +
  • + PR + #5621 opened + at 16:22Z; CI hit a migration timeout — fix + pushed this morning. +
  • +
+
+
+ +
+
+
+ Code review on aj-rosado's #6921 schema + cleanup +
+ ● Completed +
+
+
    +
  • + Approved + #6921 after + running the local code-review skill — + flagged one nullable column rename as + needing a backfill plan; resolved before + approval. +
  • +
  • + Suggested follow-up: extract the deprecated + Notifications table cleanup + into its own PR. +
  • +
+
+
+
+ + +
+
+
💻
+
bitwarden/clients
+
2 sessions · 1 stream
+
+ +
+
+
+ Web vault notification settings panel · PR + #20455 +
+ ◐ Open +
+
+
    +
  • + New Angular component + notification-preferences.component.ts + + template + .scss styled to + match the design spec from Figma. +
  • +
  • + Channels (email, push, in-app) toggleable + per event type with frequency dropdown and + quiet-hours range picker. +
  • +
  • + Hooked into existing + SettingsService; observable + wiring matches the rest of the + security-settings page. +
  • +
  • + Tests at + libs/.../notification-preferences.component.spec.ts + — 11 cases. Quiet-hours timezone edge case + still failing locally; will resolve today. +
  • +
  • + PR + #20455 opened + at 17:08Z, draft status. +
  • +
+
+
+
+ + +
+
+
📱
+
bitwarden/mobile
+
1 session · 1 stream
+
+ +
+
+
+ Push notification opt-in · PR #2780 + merged +
+ ● Completed +
+
+
    +
  • + Wired up + PushNotificationService.swift + against APNs with the new opt-in flow per + spec. +
  • +
  • + New + NotificationOptInView.swift + presented after first unlock; deferrable and + resurfaceable from settings. +
  • +
  • + Reviewed by @KatherineInCode and @vgrassia; + #2780 merged + at 15:51Z; branch + vault/PM-90120_push-optin + auto-deleted. +
  • +
  • + Backend dependency note: Android wiring will + land separately once the server endpoint + (#5621) merges. +
  • +
+
+
+
+ + +
+
+
📦
+
+ Org-wide accessibility audit rollout +
+
+ 5 PRs approved across 5 repos +
+
+ +
+
+
+ PM-90123 accessibility audit · 5 cross-repo + approvals +
+ ● Completed +
+
+ +
+
+
+ + +
+
+
🧪
+
ai-plugins meta
+
1 session · 1 stream
+
+ +
+
+
+ ai-plugins #112 · retrospecting skill + description tweak +
+ ● Completed +
+
+
    +
  • + Fixed a typo in the + retrospecting skill's + description (frontmatter). +
  • +
  • + #112 merged + at 14:02Z; branch deleted. +
  • +
+
+
+
+
+ +
+
+ 22 GitHub events in window. Cross-references to in-session + work shown with the ⟶ marker. Overnight events sit at the + bottom (newest last). +
+
+
+
+ 09:43:11ZApproved +
+
+ bitwarden/accessibility-audit-toolkit + · #42 PM-90123 audit + script (theMickster) +
+
+
+
+ 09:44:38ZApproved +
+
+ bitwarden/design-system · + #318 PM-90123 audit + script +
+
+
+
+ 09:45:07ZApproved · Sweep +
+
+ 5× cross-repo PM-90123 accessibility audit script + (theMickster) — marketing, + help-center, + brand-assets approvals continued +
+ +
+
+
+ 09:46:22ZIssue Comment +
+
+ bitwarden/design-system · + On #318 +
+
+ "❓ Will the audit script run in CI or only on + demand?" +
+
+
+
+ 11:18:02ZPush +
+
+ bitwarden/server · + vault/PM-90121_notification-preferences + (3a4f8c012) +
+ +
+
+
+ 13:42:17ZPush +
+
+ bitwarden/clients · + vault/PM-90122_web-notif-settings + (7d2b9e445) +
+ +
+
+
+ 14:02:48ZPR Merged +
+
+ bitwarden/ai-plugins · + #112 typo fix in + retrospecting skill description +
+ +
+
+
+ 14:02:50ZBranch Deleted +
+
+ bitwarden/ai-plugins · + Auto-deleted + fix/retrospecting-typo after merge +
+
+
+
+ 14:35:12ZApproved +
+
+ bitwarden/server · + #6921 Schema cleanup + for deprecated Notifications table (aj-rosado) +
+
+
+
+ 14:55:04ZApproved +
+
+ bitwarden/ios · + #2614 Settings + deep-link refactor (KatherineInCode) +
+
+
+
+ 15:51:33ZPR Merged +
+
+ bitwarden/mobile · + #2780 Push + notification opt-in +
+ +
+
+
+ 15:51:35ZBranch Deleted +
+
+ bitwarden/mobile · + Auto-deleted + vault/PM-90120_push-optin after merge +
+
+
+
+ 16:14:08ZBranch +
+
+ bitwarden/server · Created + vault/PM-90121_notification-preferences +
+
+
+
+ 16:22:51ZPR Opened +
+
+ bitwarden/server · + #5621 [PM-90121] + feat: Add notification preferences endpoint +
+ +
+
+
+ 17:01:24ZBranch +
+
+ bitwarden/clients · + Created + vault/PM-90122_web-notif-settings +
+
+
+
+ 17:08:12ZPR Opened +
+
+ bitwarden/clients · + #20455 [PM-90122] + feat: Add notification settings panel to web vault +
+ +
+
+
+ 19:04:30ZReview Comment +
+
+ bitwarden/server · On + #5621 +
+
+ "🌱 Could the migration be split so the column add + and backfill ship in separate releases?" +
+
+ + +
+ 🌙 After Midnight · Late-Night Tail (still yesterday's + workday) +
+ +
+
+ 02:14:55ZReview Comment +
+
+ bitwarden/server · On + #5621 +
+
+ "Good call — split into a follow-up. I'll open a + tracking issue tomorrow." +
+
+
+
+ 03:22:18ZPush +
+
+ bitwarden/server · + vault/PM-90121_notification-preferences + (9b1e44732) — column-add isolated from + backfill per review +
+
+
+
+ 06:18:42ZApproved +
+
+ bitwarden/template · + #201 Renovate + lock-file maintenance · since merged +
+
+
+
+ +
+

Theme of the Day

+

+ Yesterday's character was + cross-platform coordination on the new + notification preferences feature. Server endpoint scaffolded + with migration and tests, web vault settings panel built + end-to-end, and the iOS push opt-in flow shipped — all wired + against the same PM-90121 design spec. Three feature PRs + raised in a single afternoon, with the iOS piece already + merged. +

+

+ The day balanced feature work with substantial review load: + 7 approvals across 6 repos, dominated by the 5-PR PM-90123 + accessibility audit sweep that rolled out across the org's + design and content tooling. A reviewer comment on the server + PR caught an opportunity to split the migration — a + follow-up captured in the open threads below. +

+

+ The late-night tail (a review reply, a follow-up push, and a + Renovate approval before dawn) folded into yesterday's + window per the 7am Eastern boundary, keeping the standup + card focused on a single coherent narrative. +

+
+ Open threads: Get server #5621 CI green + (migration timeout fix pushed this morning) · open follow-up + tracking issue for the column-add / backfill split · resolve + quiet-hours timezone test on clients #20455 · request review + from @aj-rosado on the web settings panel · spike GraphQL + gateway shape in the new notification-prefs-spike repo · 1:1 + with manager at 15:30 +
+
+ +
+
+ Bitwarden — Engineering Daily Recap +
+ Generated from Claude Code session archives & GitHub events + · 2026-05-05 (sample · fake data for plugin demo) +
+
+ + + + From a69713f701d1d148399ebe0cd8adf9976a9e655b Mon Sep 17 00:00:00 2001 From: Patrick Honkonen Date: Fri, 1 May 2026 12:02:11 -0400 Subject: [PATCH 3/8] Refine engineering-recap sample: add late-night stream and fake teammate handles --- .../examples/engineering-recap-sample.html | 69 ++++++++++++++++--- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/plugins/daily-recap/examples/engineering-recap-sample.html b/plugins/daily-recap/examples/engineering-recap-sample.html index cf346ef..ed5af75 100644 --- a/plugins/daily-recap/examples/engineering-recap-sample.html +++ b/plugins/daily-recap/examples/engineering-recap-sample.html @@ -1040,7 +1040,7 @@

What I shipped

  • Approved 7 PRs across 6 repos — incl. the 5-PR PM-90123 accessibility audit - sweep at 09:43–09:47Z (theMickster) plus android + sweep at 09:43–09:47Z (morgan-l) plus android #6921 and ios #2614
  • @@ -1060,7 +1060,7 @@

    Today / Blockers

  • Wire clients #20455 against the live server endpoint and request review from - @aj-rosado + @jordan-h
  • Spike GraphQL gateway shape in @@ -1203,7 +1203,7 @@

    Today / Blockers

    Code review on aj-rosado's #6921 schema + >Code review on jordan-h's #6921 schema cleanup
    @@ -1229,6 +1229,53 @@

    Today / Blockers

    + +
    +
    +
    + + 🌙 Late-Night Push (post-midnight tail of + the workday) +
    + ● Completed +
    +
    +
      +
    • + 02:14Z — Replied on the + #5621 review + thread: + "Good call — split into a follow-up. + I'll open a tracking issue + tomorrow." +
    • +
    • + 03:22Z — Pushed + 9b1e44732 to + vault/PM-90121_notification-preferences + splitting the migration: column-add isolated + from backfill per reviewer feedback. +
    • +
    • + 06:18Z — Approved + bitwarden/template#201 + Renovate lock-file maintenance (since + merged) — small adjacent cleanup before + signing off. +
    • +
    +
    +
    @@ -1325,7 +1372,7 @@

    Today / Blockers

    resurfaceable from settings.
  • - Reviewed by @KatherineInCode and @vgrassia; + Reviewed by @kim-w and @sam-r; #2780 merged at 15:51Z; branch vault/PM-90120_push-optin @@ -1369,8 +1416,8 @@

    Today / Blockers

    @@ -1485,7 +1532,7 @@

    Today / Blockers

    5× cross-repo PM-90123 accessibility audit script - (theMickster) — marketing, + (morgan-l) — marketing, help-center, brand-assets approvals continued
    @@ -1572,7 +1619,7 @@

    Today / Blockers

    bitwarden/server · #6921 Schema cleanup - for deprecated Notifications table (aj-rosado) + for deprecated Notifications table (jordan-h)
    @@ -1583,7 +1630,7 @@

    Today / Blockers

    bitwarden/ios · #2614 Settings - deep-link refactor (KatherineInCode) + deep-link refactor (kim-w)
    @@ -1768,7 +1815,7 @@

    Theme of the Day

    (migration timeout fix pushed this morning) · open follow-up tracking issue for the column-add / backfill split · resolve quiet-hours timezone test on clients #20455 · request review - from @aj-rosado on the web settings panel · spike GraphQL + from @jordan-h on the web settings panel · spike GraphQL gateway shape in the new notification-prefs-spike repo · 1:1 with manager at 15:30
    From 6790e8d5e5bc8ff680470d6e73571071d9009ed1 Mon Sep 17 00:00:00 2001 From: Patrick Honkonen Date: Fri, 1 May 2026 12:07:58 -0400 Subject: [PATCH 4/8] Make day-boundary timezone-aware: default 7am local with DAILY_RECAP_CUTOFF_HOUR / TZ overrides --- plugins/daily-recap/CHANGELOG.md | 2 +- plugins/daily-recap/README.md | 7 ++- .../examples/engineering-recap-sample.html | 4 +- .../skills/engineering-recap/SKILL.md | 14 +++-- .../references/render-guide.md | 4 +- .../scripts/gather-gh-events.sh | 55 ++++++++++++------- 6 files changed, 54 insertions(+), 32 deletions(-) diff --git a/plugins/daily-recap/CHANGELOG.md b/plugins/daily-recap/CHANGELOG.md index 1e46802..0bee2ef 100644 --- a/plugins/daily-recap/CHANGELOG.md +++ b/plugins/daily-recap/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial release with `engineering-recap` skill — generates an interactive HTML recap of the user's engineering work for a given day -- 7am Eastern day-boundary handling (late-night work folds into the prior workday) +- Local-timezone day-boundary handling (late-night work folds into the prior workday); cutoff hour and timezone are configurable via the `DAILY_RECAP_CUTOFF_HOUR` and `TZ` env vars - Bundled HTML template tuned to the Bitwarden brand palette (Bitwarden Blue, Teal, Inter font, brand shield) - Bundled `gather-gh-events.sh` script that pulls GitHub events scoped to the user's workday window - Bundled `render-guide.md` reference covering placeholder map and HTML injection recipes diff --git a/plugins/daily-recap/README.md b/plugins/daily-recap/README.md index 6e5edf7..220916d 100644 --- a/plugins/daily-recap/README.md +++ b/plugins/daily-recap/README.md @@ -22,7 +22,12 @@ The output is saved to `~/Documents/daily-recap/recap-{YYYY-MM-DD}.html` and ope ## Day boundary -The skill treats **7am Eastern** as the day boundary, not midnight UTC. Late-night work folds into the prior calendar day. A "Today / Fresh" banner appears only when there is post-7am-Eastern activity on the current day. +The skill treats **7am in the user's local timezone** as the day boundary, not midnight UTC. Late-night work folds into the prior calendar day. A "Today / Fresh" banner appears only when there is activity past today's cutoff hour. + +Both knobs are env-var configurable: + +- `DAILY_RECAP_CUTOFF_HOUR` (default `7`) — the hour-of-day cutoff. Set to `5` for early-morning crews, `9` for late risers. +- `TZ` (standard env var) — override the timezone, e.g. `TZ=America/Los_Angeles` when generating a recap for someone else. ## Dependencies diff --git a/plugins/daily-recap/examples/engineering-recap-sample.html b/plugins/daily-recap/examples/engineering-recap-sample.html index ed5af75..c689416 100644 --- a/plugins/daily-recap/examples/engineering-recap-sample.html +++ b/plugins/daily-recap/examples/engineering-recap-sample.html @@ -1807,8 +1807,8 @@

    Theme of the Day

    The late-night tail (a review reply, a follow-up push, and a Renovate approval before dawn) folded into yesterday's - window per the 7am Eastern boundary, keeping the standup - card focused on a single coherent narrative. + window per the 7am-local cutoff, keeping the standup card + focused on a single coherent narrative.

    Open threads: Get server #5621 CI green diff --git a/plugins/daily-recap/skills/engineering-recap/SKILL.md b/plugins/daily-recap/skills/engineering-recap/SKILL.md index 41fa0be..dd1a8ce 100644 --- a/plugins/daily-recap/skills/engineering-recap/SKILL.md +++ b/plugins/daily-recap/skills/engineering-recap/SKILL.md @@ -7,9 +7,13 @@ description: Generates the user's engineering daily recap as an interactive HTML Generate a polished, interactive HTML recap of the user's engineering work for standup, 1:1s, or sharing with colleagues. -## Day boundary: 7am Eastern +## Day boundary: 7am local time -The user works late, especially during Stanley Cup season. **Window for "yesterday" = (yesterday 7am Eastern) → (today 7am Eastern)** — UTC `11:00Z→11:00Z` during EDT, `12:00Z→12:00Z` during EST. Late-night work folds into the prior day. The "Today/Fresh" banner only shows events from 7am Eastern onward. +Many engineers work past midnight. **Window for "yesterday" = (yesterday 7am local) → (today 7am local)**. Late-night work folds into the prior workday. The "Today/Fresh" banner only shows events from 7am local onward. + +The cutoff defaults to 07:00 in the system timezone (DST-safe). Override the hour with `DAILY_RECAP_CUTOFF_HOUR` (e.g. `5` for early-morning crews). Override the timezone with the standard `TZ` env var (e.g. `TZ=America/Los_Angeles`) — useful when generating a recap for someone else. + +When in doubt, look for a clustering gap. A clear 4+ hour quiet window after the early-morning activity is the natural boundary. ## Workflow @@ -17,7 +21,7 @@ The user works late, especially during Stanley Cup season. **Window for "yesterd These are independent — run in parallel: -**(a) GitHub events** — bundled script handles the EDT/EST window: +**(a) GitHub events** — bundled script computes the local-time window and converts to UTC: ```bash ${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/scripts/gather-gh-events.sh YYYY-MM-DD > /tmp/recap-events.json @@ -63,7 +67,7 @@ cp ${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/assets/template.html ~/Documen CSS is tuned to the Bitwarden brand palette — don't regenerate it. `${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/references/render-guide.md` has the full placeholder map and HTML recipes for the more complex injection points (project sections, timeline events, today banner). -PR refs use `#NNNN`. Always include PR titles (a bare `#6849` is useless). Late-night events (00:00Z–7am Eastern today) get a `🌙 After Midnight` divider in the timeline view, _not_ the Today banner — the Today banner is only for post-7am events on the current calendar day. +PR refs use `#NNNN`. Always include PR titles (a bare `#6849` is useless). Late-night events (after midnight local but before today's cutoff hour) get a `🌙 After Midnight` divider in the timeline view, _not_ the Today banner — the Today banner is only for events past today's cutoff hour on the current calendar day. ### 7. Open in browser @@ -80,7 +84,7 @@ Bitwarden brand palette + Inter font (already in template). Keep prose colleague ## Bundled resources - `assets/template.html` — HTML scaffold with `{{...}}` placeholders. -- `scripts/gather-gh-events.sh` — pulls events feed with the 7am Eastern window applied. +- `scripts/gather-gh-events.sh` — pulls events feed with the local-time workday window applied. Honors `DAILY_RECAP_CUTOFF_HOUR` and `TZ` env vars. - `references/render-guide.md` — placeholder map + HTML recipes (read only when you need a specific injection shape). ## Plugin dependency diff --git a/plugins/daily-recap/skills/engineering-recap/references/render-guide.md b/plugins/daily-recap/skills/engineering-recap/references/render-guide.md index 01b4de2..c05ad4f 100644 --- a/plugins/daily-recap/skills/engineering-recap/references/render-guide.md +++ b/plugins/daily-recap/skills/engineering-recap/references/render-guide.md @@ -8,7 +8,7 @@ Self-explanatory: `{{DATE}}`, `{{SUBTITLE}}`, `{{STAT_*}}`, `{{STANDUP_SHIPPED}} `{{PROJECT_CHIPS}}` — one per project: `` -`{{TODAY_BANNER}}` — empty string if no post-7am-Eastern events. Otherwise: +`{{TODAY_BANNER}}` — empty string if no events past today's cutoff hour (local time). Otherwise: ```html
    @@ -80,7 +80,7 @@ Status semantics: `completed` = work landed (PR merged, decision made, fix shipp
    ``` -For pre-7am-Eastern "today" events that belong to yesterday, insert this divider in the timeline before them: +For "today" events that fall before today's cutoff hour (local time) — those belong to yesterday's workday — insert this divider in the timeline before them: ```html
    /dev/null; then + return 0 + fi + local epoch + epoch=$(date -j -f "%Y-%m-%d %H:%M:%S" "$local_dt" "+%s" 2>/dev/null) || return 1 + date -u -r "$epoch" "+%Y-%m-%dT%H:%M:%SZ" +} + +# Add one day to a YYYY-MM-DD string. Portable across BSD/GNU date. +next_day() { + local d="$1" + date -j -v+1d -f "%Y-%m-%d" "$d" "+%Y-%m-%d" 2>/dev/null \ + || date -d "$d + 1 day" "+%Y-%m-%d" +} -START="${DATE}T$(printf '%02d' $OFFSET_HOURS):00:00Z" -# End = next day at the same offset -NEXT_DATE=$(date -u -j -v+1d -f "%Y-%m-%d" "$DATE" +%Y-%m-%d 2>/dev/null \ - || date -u -d "$DATE + 1 day" +%Y-%m-%d) -END="${NEXT_DATE}T$(printf '%02d' $OFFSET_HOURS):00:00Z" +NEXT_DATE=$(next_day "$DATE") +START=$(local_to_utc "${DATE} $(printf '%02d' "$CUTOFF_HOUR"):00:00") +END=$(local_to_utc "${NEXT_DATE} $(printf '%02d' "$CUTOFF_HOUR"):00:00") +TZ_LABEL=$(date "+%Z") -echo "# Window: $START → $END (7am $TZ_LABEL boundary)" >&2 +echo "# Window: $START → $END (${CUTOFF_HOUR}am $TZ_LABEL boundary)" >&2 CACHE="/tmp/gh-events-raw-${DATE}.json" gh api "users/${LOGIN}/events?per_page=100" > "$CACHE" From 33bb146ad61abcef742f92c227a3a3870387bb3f Mon Sep 17 00:00:00 2001 From: Patrick Honkonen Date: Fri, 1 May 2026 12:22:34 -0400 Subject: [PATCH 5/8] Use ${CLAUDE_PLUGIN_DATA}/recaps/{type}-recap-{date}.html for output path --- plugins/daily-recap/CHANGELOG.md | 1 + plugins/daily-recap/README.md | 2 +- plugins/daily-recap/skills/engineering-recap/SKILL.md | 10 ++++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/daily-recap/CHANGELOG.md b/plugins/daily-recap/CHANGELOG.md index 0bee2ef..fdacc1b 100644 --- a/plugins/daily-recap/CHANGELOG.md +++ b/plugins/daily-recap/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial release with `engineering-recap` skill — generates an interactive HTML recap of the user's engineering work for a given day +- Output written to `${CLAUDE_PLUGIN_DATA}/recaps/engineering-recap-{YYYY-MM-DD}.html` (persistent per-plugin storage; survives plugin updates). Filename pattern uses a `{recap-type}-recap-` prefix to leave room for sibling recap skills - Local-timezone day-boundary handling (late-night work folds into the prior workday); cutoff hour and timezone are configurable via the `DAILY_RECAP_CUTOFF_HOUR` and `TZ` env vars - Bundled HTML template tuned to the Bitwarden brand palette (Bitwarden Blue, Teal, Inter font, brand shield) - Bundled `gather-gh-events.sh` script that pulls GitHub events scoped to the user's workday window diff --git a/plugins/daily-recap/README.md b/plugins/daily-recap/README.md index 220916d..b9216eb 100644 --- a/plugins/daily-recap/README.md +++ b/plugins/daily-recap/README.md @@ -18,7 +18,7 @@ The `engineering-recap` skill triggers on retrospective queries about the user's - _"summarize my work this morning"_ - _"create me a daily recap for april 28 to show colleagues"_ -The output is saved to `~/Documents/daily-recap/recap-{YYYY-MM-DD}.html` and opened in the default browser. +The output is saved to `${CLAUDE_PLUGIN_DATA}/recaps/engineering-recap-{YYYY-MM-DD}.html` and opened in the default browser. `${CLAUDE_PLUGIN_DATA}` is the per-plugin persistent directory provided by Claude Code (resolves to `~/.claude/plugins/data/{plugin-id}/`); recaps survive plugin updates and are not tied to a hardcoded user path. The `{recap-type}-recap-` filename pattern keeps the `recaps/` directory tidy as new recap skills are added to this plugin (e.g. `design-recap-`, `management-recap-`). ## Day boundary diff --git a/plugins/daily-recap/skills/engineering-recap/SKILL.md b/plugins/daily-recap/skills/engineering-recap/SKILL.md index dd1a8ce..064fc33 100644 --- a/plugins/daily-recap/skills/engineering-recap/SKILL.md +++ b/plugins/daily-recap/skills/engineering-recap/SKILL.md @@ -59,20 +59,22 @@ Cross-reference: branch creates / pushes that match worktree work → tag with ` ### 6. Render the HTML -Copy the template to the recap output, then fill the `{{...}}` placeholders: +Output goes to `${CLAUDE_PLUGIN_DATA}/recaps/engineering-recap-{YYYY-MM-DD}.html` — `${CLAUDE_PLUGIN_DATA}` is a persistent per-plugin directory provided by Claude Code (resolves to `~/.claude/plugins/data/{plugin-id}/`) and survives plugin updates. The `{recap-type}-recap-` filename convention leaves room for sibling recap types in this plugin (design, management, etc.) to share the same `recaps/` directory. ```bash -cp ${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/assets/template.html ~/Documents/daily-recap/recap-{YYYY-MM-DD}.html +mkdir -p "${CLAUDE_PLUGIN_DATA}/recaps" +cp "${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/assets/template.html" \ + "${CLAUDE_PLUGIN_DATA}/recaps/engineering-recap-{YYYY-MM-DD}.html" ``` -CSS is tuned to the Bitwarden brand palette — don't regenerate it. `${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/references/render-guide.md` has the full placeholder map and HTML recipes for the more complex injection points (project sections, timeline events, today banner). +Then fill the `{{...}}` placeholders. CSS is tuned to the Bitwarden brand palette — don't regenerate it. `${CLAUDE_PLUGIN_ROOT}/skills/engineering-recap/references/render-guide.md` has the full placeholder map and HTML recipes for the more complex injection points (project sections, timeline events, today banner). PR refs use `#NNNN`. Always include PR titles (a bare `#6849` is useless). Late-night events (after midnight local but before today's cutoff hour) get a `🌙 After Midnight` divider in the timeline view, _not_ the Today banner — the Today banner is only for events past today's cutoff hour on the current calendar day. ### 7. Open in browser ```bash -open ~/Documents/daily-recap/recap-{YYYY-MM-DD}.html +open "${CLAUDE_PLUGIN_DATA}/recaps/engineering-recap-{YYYY-MM-DD}.html" ``` Summarize to the user: stats, headline theme, and that the standup card has a Copy button. From 07beac0a4843d8672a9eab7d966529d4f128456d Mon Sep 17 00:00:00 2001 From: Patrick Honkonen Date: Fri, 1 May 2026 12:25:29 -0400 Subject: [PATCH 6/8] Rename plugin to bitwarden-daily-recap to follow Bitwarden plugin naming convention --- .../.claude-plugin/plugin.json | 0 plugins/{daily-recap => bitwarden-daily-recap}/CHANGELOG.md | 0 plugins/{daily-recap => bitwarden-daily-recap}/README.md | 0 .../examples/engineering-recap-sample.html | 0 .../skills/engineering-recap/SKILL.md | 0 .../skills/engineering-recap/assets/template.html | 0 .../skills/engineering-recap/references/render-guide.md | 0 .../skills/engineering-recap/scripts/gather-gh-events.sh | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{daily-recap => bitwarden-daily-recap}/.claude-plugin/plugin.json (100%) rename plugins/{daily-recap => bitwarden-daily-recap}/CHANGELOG.md (100%) rename plugins/{daily-recap => bitwarden-daily-recap}/README.md (100%) rename plugins/{daily-recap => bitwarden-daily-recap}/examples/engineering-recap-sample.html (100%) rename plugins/{daily-recap => bitwarden-daily-recap}/skills/engineering-recap/SKILL.md (100%) rename plugins/{daily-recap => bitwarden-daily-recap}/skills/engineering-recap/assets/template.html (100%) rename plugins/{daily-recap => bitwarden-daily-recap}/skills/engineering-recap/references/render-guide.md (100%) rename plugins/{daily-recap => bitwarden-daily-recap}/skills/engineering-recap/scripts/gather-gh-events.sh (100%) diff --git a/plugins/daily-recap/.claude-plugin/plugin.json b/plugins/bitwarden-daily-recap/.claude-plugin/plugin.json similarity index 100% rename from plugins/daily-recap/.claude-plugin/plugin.json rename to plugins/bitwarden-daily-recap/.claude-plugin/plugin.json diff --git a/plugins/daily-recap/CHANGELOG.md b/plugins/bitwarden-daily-recap/CHANGELOG.md similarity index 100% rename from plugins/daily-recap/CHANGELOG.md rename to plugins/bitwarden-daily-recap/CHANGELOG.md diff --git a/plugins/daily-recap/README.md b/plugins/bitwarden-daily-recap/README.md similarity index 100% rename from plugins/daily-recap/README.md rename to plugins/bitwarden-daily-recap/README.md diff --git a/plugins/daily-recap/examples/engineering-recap-sample.html b/plugins/bitwarden-daily-recap/examples/engineering-recap-sample.html similarity index 100% rename from plugins/daily-recap/examples/engineering-recap-sample.html rename to plugins/bitwarden-daily-recap/examples/engineering-recap-sample.html diff --git a/plugins/daily-recap/skills/engineering-recap/SKILL.md b/plugins/bitwarden-daily-recap/skills/engineering-recap/SKILL.md similarity index 100% rename from plugins/daily-recap/skills/engineering-recap/SKILL.md rename to plugins/bitwarden-daily-recap/skills/engineering-recap/SKILL.md diff --git a/plugins/daily-recap/skills/engineering-recap/assets/template.html b/plugins/bitwarden-daily-recap/skills/engineering-recap/assets/template.html similarity index 100% rename from plugins/daily-recap/skills/engineering-recap/assets/template.html rename to plugins/bitwarden-daily-recap/skills/engineering-recap/assets/template.html diff --git a/plugins/daily-recap/skills/engineering-recap/references/render-guide.md b/plugins/bitwarden-daily-recap/skills/engineering-recap/references/render-guide.md similarity index 100% rename from plugins/daily-recap/skills/engineering-recap/references/render-guide.md rename to plugins/bitwarden-daily-recap/skills/engineering-recap/references/render-guide.md diff --git a/plugins/daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh b/plugins/bitwarden-daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh similarity index 100% rename from plugins/daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh rename to plugins/bitwarden-daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh From a83713efd38118e7c61ffd1178137b11d8511fca Mon Sep 17 00:00:00 2001 From: Patrick Honkonen Date: Fri, 1 May 2026 12:28:58 -0400 Subject: [PATCH 7/8] Update plugin identifier references to bitwarden-daily-recap --- .claude-plugin/marketplace.json | 4 ++-- README.md | 2 +- plugins/bitwarden-daily-recap/.claude-plugin/plugin.json | 6 +++--- plugins/bitwarden-daily-recap/CHANGELOG.md | 2 +- plugins/bitwarden-daily-recap/README.md | 4 ++-- .../skills/engineering-recap/references/render-guide.md | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 9aba2fd..214f17c 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -17,8 +17,8 @@ "description": "Comprehensive analysis of Claude Code sessions to identify successful patterns, problematic areas, and opportunities for improvement." }, { - "name": "daily-recap", - "source": "./plugins/daily-recap", + "name": "bitwarden-daily-recap", + "source": "./plugins/bitwarden-daily-recap", "version": "1.0.0", "description": "Generate polished, interactive HTML recaps of a person's daily work. Pulls activity from the relevant systems, shapes it into a standup-ready, colleague-shareable artifact, and applies Bitwarden brand styling." }, diff --git a/README.md b/README.md index 1f0681d..77df77c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ A curated collection of plugins for AI-assisted development at Bitwarden. Enable | [bitwarden-software-engineer](plugins/bitwarden-software-engineer/) | 0.4.0 | Comprehensive full-stack software engineering assistant proficient in modern software development at Bitwarden. | | [claude-config-validator](plugins/claude-config-validator/) | 1.1.1 | Validates Claude Code configuration files for security, structure, and quality | | [claude-retrospective](plugins/claude-retrospective/) | 1.1.1 | Analyze Claude Code sessions to identify successful patterns and improvement opportunities | -| [daily-recap](plugins/daily-recap/) | 1.0.0 | Generate polished, interactive HTML recaps of a person's daily work with Bitwarden brand styling | +| [bitwarden-daily-recap](plugins/bitwarden-daily-recap/) | 1.0.0 | Generate polished, interactive HTML recaps of a person's daily work with Bitwarden brand styling | ## Usage diff --git a/plugins/bitwarden-daily-recap/.claude-plugin/plugin.json b/plugins/bitwarden-daily-recap/.claude-plugin/plugin.json index e5b55b9..0389ee2 100644 --- a/plugins/bitwarden-daily-recap/.claude-plugin/plugin.json +++ b/plugins/bitwarden-daily-recap/.claude-plugin/plugin.json @@ -1,15 +1,15 @@ { - "name": "daily-recap", + "name": "bitwarden-daily-recap", "version": "1.0.0", "description": "Generate polished, interactive HTML recaps of a person's daily work. Pulls activity from the relevant systems, shapes it into a standup-ready, colleague-shareable artifact, and applies Bitwarden brand styling.", "author": { "name": "Bitwarden", "url": "https://github.com/bitwarden" }, - "homepage": "https://github.com/bitwarden/ai-plugins/tree/main/plugins/daily-recap", + "homepage": "https://github.com/bitwarden/ai-plugins/tree/main/plugins/bitwarden-daily-recap", "repository": "https://github.com/bitwarden/ai-plugins", "keywords": [ - "daily-recap", + "bitwarden-daily-recap", "standup", "summary", "retrospective", diff --git a/plugins/bitwarden-daily-recap/CHANGELOG.md b/plugins/bitwarden-daily-recap/CHANGELOG.md index fdacc1b..773dce7 100644 --- a/plugins/bitwarden-daily-recap/CHANGELOG.md +++ b/plugins/bitwarden-daily-recap/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -All notable changes to the Daily Recap Plugin will be documented in this file. +All notable changes to the Bitwarden Daily Recap Plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). diff --git a/plugins/bitwarden-daily-recap/README.md b/plugins/bitwarden-daily-recap/README.md index b9216eb..195d949 100644 --- a/plugins/bitwarden-daily-recap/README.md +++ b/plugins/bitwarden-daily-recap/README.md @@ -1,4 +1,4 @@ -# Daily Recap +# Bitwarden Daily Recap Generate polished, interactive HTML recaps of a person's daily work. Pulls activity from the relevant systems, shapes it into a standup-ready, colleague-shareable artifact, and applies Bitwarden brand styling. @@ -38,7 +38,7 @@ Both knobs are env-var configurable: ## Files ``` -daily-recap/ +bitwarden-daily-recap/ ├── .claude-plugin/plugin.json ├── CHANGELOG.md ├── README.md diff --git a/plugins/bitwarden-daily-recap/skills/engineering-recap/references/render-guide.md b/plugins/bitwarden-daily-recap/skills/engineering-recap/references/render-guide.md index c05ad4f..1f49d9c 100644 --- a/plugins/bitwarden-daily-recap/skills/engineering-recap/references/render-guide.md +++ b/plugins/bitwarden-daily-recap/skills/engineering-recap/references/render-guide.md @@ -1,4 +1,4 @@ -# Render Guide — daily-recap template +# Render Guide — bitwarden-daily-recap template The template at `assets/template.html` uses `{{...}}` placeholders. Most are self-explanatory; this guide covers the HTML shapes you need to inject for `{{PROJECT_SECTIONS}}`, `{{TIMELINE_EVENTS}}`, and `{{TODAY_BANNER}}`. CSS is already tuned to the Bitwarden brand palette — don't regenerate. From 5f7db1aae8a4878397fc4bde03e402130ca52a50 Mon Sep 17 00:00:00 2001 From: Patrick Honkonen Date: Fri, 1 May 2026 12:37:41 -0400 Subject: [PATCH 8/8] Fix GNU date branch in local_to_utc: parse input without -u MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GNU `date -u -d` interprets the input string as UTC, silently breaking the local-time intent on Linux for any non-UTC user. Parse without -u, then switch to UTC when formatting the resulting epoch — mirrors the BSD branch pattern. --- .../engineering-recap/scripts/gather-gh-events.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/bitwarden-daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh b/plugins/bitwarden-daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh index 90f314f..2ffb947 100755 --- a/plugins/bitwarden-daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh +++ b/plugins/bitwarden-daily-recap/skills/engineering-recap/scripts/gather-gh-events.sh @@ -24,12 +24,18 @@ LOGIN="$(gh api user --jq .login)" # Convert "YYYY-MM-DD HH:00:00" interpreted in local TZ to a UTC ISO-8601 # timestamp. Works with both BSD date (macOS) and GNU date (Linux). +# +# IMPORTANT: GNU `date -u -d` parses the input as UTC, not local — so we must +# parse without `-u` and only switch to UTC when formatting the resulting epoch. local_to_utc() { local local_dt="$1" - if date -u -d "$local_dt" "+%Y-%m-%dT%H:%M:%SZ" 2>/dev/null; then + local epoch + # GNU date: parse in local TZ to epoch, then format as UTC. + if epoch=$(date -d "$local_dt" "+%s" 2>/dev/null); then + date -u -d "@$epoch" "+%Y-%m-%dT%H:%M:%SZ" return 0 fi - local epoch + # BSD date fallback (macOS). epoch=$(date -j -f "%Y-%m-%d %H:%M:%S" "$local_dt" "+%s" 2>/dev/null) || return 1 date -u -r "$epoch" "+%Y-%m-%dT%H:%M:%SZ" }