git-impact 0.3.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +124 -78
  2. package/dist/cli/index.js +32 -211
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/init/installer.d.ts +6 -0
  5. package/dist/init/installer.d.ts.map +1 -1
  6. package/dist/init/installer.js +58 -5
  7. package/dist/init/installer.js.map +1 -1
  8. package/dist/init/installer.test.d.ts +2 -0
  9. package/dist/init/installer.test.d.ts.map +1 -0
  10. package/dist/init/installer.test.js +127 -0
  11. package/dist/init/installer.test.js.map +1 -0
  12. package/dist/init/templates.d.ts +8 -7
  13. package/dist/init/templates.d.ts.map +1 -1
  14. package/dist/init/templates.js +73 -371
  15. package/dist/init/templates.js.map +1 -1
  16. package/dist/mcp/resources.js +0 -1
  17. package/dist/mcp/resources.js.map +1 -1
  18. package/dist/mcp/tools.d.ts.map +1 -1
  19. package/dist/mcp/tools.js +64 -12
  20. package/dist/mcp/tools.js.map +1 -1
  21. package/dist/readers/git.d.ts +2 -1
  22. package/dist/readers/git.d.ts.map +1 -1
  23. package/dist/readers/git.js +12 -6
  24. package/dist/readers/git.js.map +1 -1
  25. package/dist/readers/redact.d.ts +29 -0
  26. package/dist/readers/redact.d.ts.map +1 -0
  27. package/dist/readers/redact.js +82 -0
  28. package/dist/readers/redact.js.map +1 -0
  29. package/dist/readers/redact.test.d.ts +2 -0
  30. package/dist/readers/redact.test.d.ts.map +1 -0
  31. package/dist/readers/redact.test.js +72 -0
  32. package/dist/readers/redact.test.js.map +1 -0
  33. package/dist/report/html.d.ts +2 -0
  34. package/dist/report/html.d.ts.map +1 -1
  35. package/dist/report/html.js +35 -1
  36. package/dist/report/html.js.map +1 -1
  37. package/dist/report/render.d.ts.map +1 -1
  38. package/dist/report/render.js +2 -0
  39. package/dist/report/render.js.map +1 -1
  40. package/dist/storage/db.d.ts +23 -2
  41. package/dist/storage/db.d.ts.map +1 -1
  42. package/dist/storage/db.js +12 -0
  43. package/dist/storage/db.js.map +1 -1
  44. package/dist/storage/db.test.d.ts +2 -0
  45. package/dist/storage/db.test.d.ts.map +1 -0
  46. package/dist/storage/db.test.js +152 -0
  47. package/dist/storage/db.test.js.map +1 -0
  48. package/package.json +7 -6
  49. package/skill/SKILL.md +131 -206
  50. package/skill/references/html-template.md +131 -0
  51. package/skill/references/translation-rules.md +87 -0
  52. package/dist/translator/prompt.d.ts +0 -21
  53. package/dist/translator/prompt.d.ts.map +0 -1
  54. package/dist/translator/prompt.js +0 -117
  55. package/dist/translator/prompt.js.map +0 -1
  56. package/dist/translator/translate.d.ts +0 -36
  57. package/dist/translator/translate.d.ts.map +0 -1
  58. package/dist/translator/translate.js +0 -73
  59. package/dist/translator/translate.js.map +0 -1
package/skill/SKILL.md CHANGED
@@ -1,278 +1,198 @@
1
1
  ---
2
2
  name: git-impact
3
3
  description: >
4
- Translates git commits into plain-English business impact bullets ideal for
5
- daily standups, manager updates, and end-of-quarter performance reviews.
6
- Use this skill whenever the user says anything like: "do my standup",
7
- "what did I work on today", "translate my commits", "summarize my git activity",
8
- "write my standup update", "what should I say in standup", "git-impact",
9
- "/git-impact", "show my impact", "translate today's work", "what did I ship",
10
- "generate a performance review", "what have I done this week/month/quarter",
11
- "review my commits". Also trigger for "since yesterday", "last 3 days commits",
12
- or any request to turn technical git output into something a manager can read.
4
+ Translates git commits into plain-English business impact bullets. Use this
5
+ skill when the user says any of: "do my standup", "/git-impact", "what did I
6
+ ship today", "what did I work on", "translate my commits", "summarize my
7
+ git activity", "write my standup update", "what should I say in standup",
8
+ "show my impact", "since yesterday", "since 3d", "since last standup",
9
+ "what have I done this week / month / quarter", "generate a performance
10
+ review", "performance review prep", "review my commits", "what's blocked",
11
+ "weekly summary". Trigger on any request to turn raw git output into
12
+ something a non-technical manager can read. The skill orchestrates MCP
13
+ tools (get_git_activity, save_impact_entry, get_history, etc.) — it does
14
+ not run sqlite3 or other DB commands directly.
13
15
  ---
14
16
 
15
17
  # git-impact
16
18
 
17
- Translate git commits into plain-English business impact for standups, manager
18
- updates, and performance reviews — without an API key. You do the translation
19
- inline using bash to read git data and a per-repo context file for personalization.
19
+ You translate git commits into plain-English business impact for standups,
20
+ manager updates, and performance review prep. Your job is **orchestration**:
21
+ call the MCP tools provided by the `git-impact` server, apply the translation
22
+ rules, and produce the output. The MCP server owns all data access (git, DB).
23
+ You own the language.
20
24
 
21
- ---
22
-
23
- ## Sub-commands
24
-
25
- Parse the user's message to determine which mode to run:
26
-
27
- | What the user says | Mode |
28
- |---|---|
29
- | `do my standup`, `today`, `/git-impact`, no args | **today** |
30
- | `since yesterday`, `since 3d`, `since 2026-05-01` | **since \<when\>** |
31
- | `review`, `performance review`, `last 30 days`, `Q2 review` | **review** |
32
- | `init`, `set up context`, `configure for this repo` | **init** |
25
+ If the `git-impact` MCP server is not available in this conversation, fall
26
+ back to the bash steps in `references/fallback-bash.md` — but the MCP path
27
+ is preferred everywhere it works.
33
28
 
34
29
  ---
35
30
 
36
- ## Step 1 Find the repo root
31
+ ## Pick a mode from the user's message
37
32
 
38
- Run this to find the git root from wherever you are:
39
-
40
- ```bash
41
- git rev-parse --show-toplevel 2>/dev/null
42
- ```
33
+ | User says | Mode |
34
+ |---|---|
35
+ | "do my standup", "today", "/git-impact", no args | **standup** (default) |
36
+ | "since yesterday", "since 3d", "since 2026-05-01" | **standup** with explicit `since_iso` |
37
+ | "review", "performance review", "last 90 days", "Q2 review" | **review** |
38
+ | "init", "set up context", "configure for this repo" | **init** |
39
+ | "make a presentation", "make a slide", "make me a shareable" | **standup** + **bespoke HTML** (extra step) |
43
40
 
44
- If it fails, tell the user: *"No git repository found in the current directory. Open
45
- a project folder first, or `cd` into a repo."* Stop there.
41
+ The default standup writes to the rolling HTML dashboard at
42
+ `.git-impact/result.html` (regenerated by the report renderer the user
43
+ opens with `git-impact view`). The per-day bespoke HTML is only created
44
+ when the user explicitly asks for a presentation — don't write one by
45
+ default; it's expensive and most days don't need it.
46
46
 
47
- Store the result as `REPO_ROOT`.
47
+ If the message is ambiguous, default to **standup**.
48
48
 
49
49
  ---
50
50
 
51
- ## Step 2 — Load context (if it exists)
51
+ ## Mode: standup
52
52
 
53
- ```bash
54
- cat "$REPO_ROOT/.git-impact/context.json" 2>/dev/null || echo "NONE"
55
- ```
53
+ ### 1. Resolve the lookback window
56
54
 
57
- If the file exists, parse it. It looks like:
55
+ - If the user said an explicit "since X", convert to an ISO timestamp and use it.
56
+ - Otherwise call **`get_last_standup_date`**. If it returns a date, use the
57
+ start of the day after that date as `since_iso`. If it returns null,
58
+ default to start-of-today.
58
59
 
59
- ```json
60
- {
61
- "companyDescription": "B2B SaaS for workforce analytics",
62
- "managerPriorities": "Shipping on time, not breaking prod",
63
- "glossary": {
64
- "RLS": "data security layer",
65
- "TabPFN": "AI predictions",
66
- "MFA": "login security"
67
- }
68
- }
69
- ```
60
+ This is the "since last standup" default — it survives weekends and days off.
70
61
 
71
- Use this to personalise your translation — apply the glossary and frame impact
72
- around what the manager cares about. If the file doesn't exist, use general
73
- technical language and suggest running `init` at the end.
62
+ ### 2. Fetch git activity
74
63
 
75
- ---
64
+ Call **`get_git_activity`** with `since_iso` and (optionally) `until_iso`.
65
+ You'll get back commits, file stats, branch, and the resolved repo path.
76
66
 
77
- ## Mode: today / since \<when\>
67
+ If there are no commits in the window: tell the user clearly and stop. Do
68
+ NOT save an empty entry.
78
69
 
79
- ### Fetch commits
70
+ ### 3. Optional: enrich with GitHub PR data
80
71
 
81
- For **today**:
82
- ```bash
83
- git -C "$REPO_ROOT" log \
84
- --since="$(date '+%Y-%m-%d') 00:00:00" \
85
- --format="%h|%s|%b|%an|%ad" \
86
- --date=short \
87
- HEAD
88
- ```
89
-
90
- For **since \<when\>** — convert the user's input to a git `--since` value:
91
- - `yesterday` → `--since="yesterday 00:00:00"`
92
- - `3d` → `--since="3 days ago 00:00:00"`
93
- - `2026-05-01` → `--since="2026-05-01 00:00:00"`
94
-
95
- ### Fetch files changed
96
-
97
- ```bash
98
- FIRST=$(git -C "$REPO_ROOT" log --since="..." --format="%h" HEAD | tail -1)
99
- git -C "$REPO_ROOT" diff --stat "$FIRST"^ HEAD 2>/dev/null || \
100
- git -C "$REPO_ROOT" show --stat "$FIRST" 2>/dev/null
101
- ```
72
+ If the user has a `github_token` saved in their context (the
73
+ `get_git_activity` response or a prior `get_github_activity` call will tell
74
+ you), call **`get_github_activity`** to pull PR titles and descriptions.
75
+ PR descriptions are the single best source for accurate "why it matters"
76
+ text — strongly prefer them over inference.
102
77
 
103
- ### Translate
78
+ ### 4. Translate
104
79
 
105
- If there are no commits, say so clearly and stop.
80
+ Read **`references/translation-rules.md`** for the prompt-engineering details.
81
+ Key rules at a glance:
106
82
 
107
- Otherwise translate into **2–5 bullet points**. Follow these rules:
83
+ - **What + why**, not what + how
84
+ - **Apply the glossary** from `context.json` (returned by the context resource
85
+ or visible in `get_git_activity` output)
86
+ - **Provenance is mandatory** — every saved bullet gets `pr` / `commit_body` /
87
+ `commit_message` / `ticket` / `inferred`
88
+ - **Group related commits** into one bullet, not many
89
+ - **2-5 bullets total**, never more
108
90
 
109
- 1. **What + why, not what + how.** Each bullet must say what was accomplished
110
- AND why it matters to the business. "Fixed a bug in the auth middleware" is
111
- useless to a manager. "Fixed login failures for admin users — unblocks the
112
- Q2 portal launch" is useful.
91
+ ### 5. Print the user-facing output
113
92
 
114
- 2. **Apply the glossary.** Replace every technical term listed in context.json
115
- with its plain-English equivalent. If no glossary, infer from context.
116
-
117
- 3. **Never hallucinate impact.** If you can't infer the business reason, say
118
- "technical foundation work for [area]" rather than inventing an outcome.
119
-
120
- 4. **Group related commits.** Three commits all touching auth tell one story —
121
- write one bullet, not three.
93
+ ```
94
+ 📅 [Day, Date or date range]
122
95
 
123
- 5. **WIP / draft commits** get `⏳ In progress:` and state what the expected
124
- outcome is, not what was done so far.
96
+ [Summary]
97
+ [Why it matters]
125
98
 
126
- 6. **Be specific.** "Improved performance" is vague. "Reduced login latency
127
- by ~40%" is specific. Use whatever numbers exist in the commit messages.
99
+ In progress: [What]
100
+ [Expected outcome]
128
101
 
129
- ### Output format
102
+ 🚫 Blocked: [What] (only if applicable)
103
+ → [What's needed]
130
104
 
105
+ 📁 [N] files across [areas]
106
+ [N] commit(s) on [branch]
131
107
  ```
132
- 📅 [Day, Date]
133
108
 
134
- [Plain-English summary of what was accomplished]
135
- → [Why it matters — who it unblocks, what risk it reduces, what it enables]
109
+ ### 6. Save to history
136
110
 
137
- In progress: [What is being worked on]
138
- [Expected outcome when complete]
111
+ Call **`save_impact_entry`** with the structured items including
112
+ `provenance` for each. The MCP tool handles the SQLite write — never run
113
+ `sqlite3` directly. Required fields per item: `status`, `summary`,
114
+ `provenance`. Recommended: `impact`, `refs`.
139
115
 
140
- 📁 [N] files changed across [brief description of areas touched]
141
- [N] commit(s) on [branch name]
116
+ Example item:
117
+ ```json
118
+ {
119
+ "status": "done",
120
+ "summary": "Shipped multi-tenant data isolation",
121
+ "impact": "Unblocks SOC2 sign-off, prevents cross-company data leaks",
122
+ "provenance": "pr",
123
+ "refs": ["PR #142", "ENG-1234"]
124
+ }
142
125
  ```
143
126
 
144
- ### Save to history
145
-
146
- After printing the output, silently save to `.git-impact/history.db`:
147
-
148
- ```bash
149
- mkdir -p "$REPO_ROOT/.git-impact"
150
- grep -qxF '.git-impact/history.db' "$REPO_ROOT/.gitignore" 2>/dev/null || \
151
- printf '\n# git-impact local history (private, per-machine)\n.git-impact/history.db\n' \
152
- >> "$REPO_ROOT/.gitignore"
153
-
154
- sqlite3 "$REPO_ROOT/.git-impact/history.db" "
155
- CREATE TABLE IF NOT EXISTS impact_entries (
156
- id INTEGER PRIMARY KEY AUTOINCREMENT,
157
- date TEXT NOT NULL,
158
- repo_name TEXT NOT NULL,
159
- total_commits INTEGER NOT NULL DEFAULT 0,
160
- total_files INTEGER NOT NULL DEFAULT 0,
161
- items_json TEXT NOT NULL DEFAULT '[]',
162
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
163
- );
164
- INSERT INTO impact_entries (date, repo_name, total_commits, total_files, items_json)
165
- VALUES ('$(date +%Y-%m-%d)', '$(basename $REPO_ROOT)', $COMMIT_COUNT, $FILE_COUNT, '$ITEMS_JSON');
166
- "
167
- ```
127
+ ### 7. Point the user at the dashboard
168
128
 
169
- If `sqlite3` is not available, skip silently.
170
-
171
- ### Build a polished HTML presentation
172
-
173
- After saving to history, **use your Write tool to create a bespoke HTML
174
- presentation** for today's standup. This is not a generic template — each day's
175
- file should be tailored to the actual content, with custom layout, charts, or
176
- diagrams when they help.
177
-
178
- **Where to write:**
179
- - `$REPO_ROOT/.git-impact/standups/YYYY-MM-DD.html` — today's file
180
- - `$REPO_ROOT/.git-impact/standups/index.html` — list of all standups (regenerate it)
181
-
182
- **Stack (all CDN, no install):**
183
- - Tailwind CSS via `<script src="https://cdn.tailwindcss.com">`
184
- - Inter font via Google Fonts
185
- - Chart.js (`https://cdn.jsdelivr.net/npm/chart.js`) only if there are real numbers worth charting
186
- - Mermaid (`https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs`) for flow/architecture diagrams when relevant
187
-
188
- **Required structure:**
189
- 1. **Hero** — date label + a bold, plain-English headline that captures the day
190
- ("Shipped safety analytics, hardened tenant isolation" — not "9 commits")
191
- 2. **Stats grid** — 3-4 metric cards (commits, files, PRs merged, areas touched)
192
- 3. **Achievement cards** — one per ✅ item with status pill, title, summary,
193
- "→ Why it matters" line, and tags (PR #, area, file count)
194
- 4. **Optional visual** — only when the content warrants one (a Mermaid flow
195
- diagram for architecture changes, a Chart.js chart for ratios/comparisons,
196
- a code-style block for a key formula). Skip if forced.
197
- 5. **Footer** — file count, branch, link back to `index.html`
198
-
199
- **Design language:**
200
- - Dark theme by default (`bg-slate-950`), generous spacing, max width 4xl
201
- - Cards: `bg-slate-900/50 border border-slate-800 rounded-2xl p-6`
202
- - Status pills: emerald for done, amber for in-progress, rose for blocked
203
- - Print-friendly via `@media print`
204
-
205
- **Status pill colors:**
206
- - ✅ Shipped → `bg-emerald-500/20 text-emerald-400`
207
- - ⏳ In Progress → `bg-amber-500/20 text-amber-400`
208
- - 🚫 Blocked → `bg-rose-500/20 text-rose-400`
209
-
210
- After writing both files, print the file URL on the very last line of your reply:
129
+ The rolling HTML dashboard at `<repo>/.git-impact/result.html` is the
130
+ default visual output — it's regenerated automatically when the user runs
131
+ `git-impact view`, and now includes today's entry because you just saved
132
+ it. End your reply with that file URL on its own last line:
211
133
 
212
134
  ```
213
- 🎯 file://$REPO_ROOT/.git-impact/standups/YYYY-MM-DD.html
135
+ 🎯 file:///<absolute-repo-path>/.git-impact/result.html
214
136
  ```
215
137
 
216
- Replace `$REPO_ROOT` with the real absolute path so the user can ⌘-click.
138
+ **Only if the user explicitly asked for a "presentation", "slide",
139
+ "shareable", or "screenshot-friendly" output**, ALSO read
140
+ `references/html-template.md` and use your `Write` tool to create
141
+ `<repo>/.git-impact/standups/YYYY-MM-DD.html` (plus update
142
+ `standups/index.html`). Most days don't need this — skip by default.
217
143
 
218
144
  ---
219
145
 
220
146
  ## Mode: review
221
147
 
222
- Fetch saved history and synthesise a performance review.
223
-
224
- Parse the period from the user's message:
225
- - `last 30 days` / `30d` → last 30 days
226
- - `last 90 days` / `90d` → last 90 days (default)
227
- - `Q2-2026` April 1 June 30, 2026
228
-
229
- ```bash
230
- sqlite3 "$REPO_ROOT/.git-impact/history.db" \
231
- "SELECT date, repo_name, total_commits, items_json
232
- FROM impact_entries
233
- WHERE date >= '$FROM' AND date <= '$TO'
234
- ORDER BY date ASC;" 2>/dev/null
148
+ 1. Parse the period from the user's message:
149
+ - "last 30 days" / "30d" → `last_days: 30`
150
+ - "last 90 days" / "90d" / no arg → `last_days: 90`
151
+ - "Q2-2026" `from_date: 2026-04-01`, `to_date: 2026-06-30`
152
+ 2. Call **`get_history`** with the parsed window.
153
+ 3. If no entries returned: tell the user
154
+ *"No saved history yet for this period. Use the standup mode daily to
155
+ build up history, then come back."* and stop.
156
+ 4. Synthesise themes (Features, Reliability, Security, Code review,
157
+ Infrastructure). Only include themes that apply.
158
+ 5. Frame as **performance review prep** (evidence pack), not a finished
159
+ review bullets should include dates and refs the user can paste into
160
+ their own writing.
161
+
162
+ Output:
235
163
  ```
164
+ Performance Review Prep — [Period]
236
165
 
237
- If the DB doesn't exist or returns nothing: *"No saved history found for this
238
- period. Use the standup mode daily to build up history, then come back."*
239
-
240
- Otherwise synthesise:
241
-
242
- ```
243
- Performance Review — [Period]
244
-
245
- [One headline sentence — biggest contribution this period]
166
+ [One headline sentence biggest contribution]
246
167
 
247
168
  🚀 [High-impact theme]
248
- • Specific achievement...
169
+ • Specific achievement [date, refs]
249
170
 
250
171
  ✅ [Medium-impact theme]
251
- Specific achievement...
172
+ • ...
252
173
 
253
174
  🔧 [Lower-impact theme]
254
175
  • ...
255
176
 
256
- ---
257
177
  📊 [N] commits across [N] working days
258
178
  ```
259
179
 
260
- Group by theme (Features shipped, Reliability, Security, Code review,
261
- Infrastructure). Only include themes that apply.
262
-
263
180
  ---
264
181
 
265
182
  ## Mode: init
266
183
 
267
- Ask the user three questions one at a time:
184
+ Ask one at a time:
268
185
 
269
186
  1. *"What does your company/product do? (1–2 sentences)"*
270
187
  2. *"What does your manager care most about?"*
271
- 3. *"Any technical terms to translate? Format: RLS=data security, MFA=login security (leave blank to skip)"*
188
+ 3. *"Technical terms to translate? Format: RLS=data security, MFA=login security (blank to skip)"*
272
189
 
273
- Then write `.git-impact/context.json` and tell the user:
274
- *"Saved to `.git-impact/context.json`. Commit this to share the glossary with
275
- your team. history.db is gitignored automatically."*
190
+ Then call **`update_context`** with the answers. Tell the user:
191
+ *"Saved to `.git-impact/context.json`. Commit this to share the glossary with your team."*
192
+
193
+ If the install also wrote slash command files for other editors (Cursor,
194
+ Copilot, Gemini), point that out so they know the same workflow works
195
+ elsewhere.
276
196
 
277
197
  ---
278
198
 
@@ -280,6 +200,11 @@ your team. history.db is gitignored automatically."*
280
200
 
281
201
  - Write for a non-technical manager. No jargon that isn't in the glossary.
282
202
  - Short sentences. No filler. Skip "this change" / "this commit" constructions.
283
- - Confident — if you know the impact, state it. If not, use
284
- "technical foundation work for X", never hedge with "might potentially".
203
+ - Confident — if you know the impact, state it. If you guessed, label
204
+ `provenance: inferred` and use phrases like "technical foundation work
205
+ for X". Never hedge with "might potentially".
285
206
  - 2 accurate bullets beat 5 vague ones.
207
+
208
+ For prompt details, anti-patterns, and the full output format, see
209
+ `references/translation-rules.md`. For the bespoke daily HTML, see
210
+ `references/html-template.md`.
@@ -0,0 +1,131 @@
1
+ # HTML presentation guide
2
+
3
+ Read this file ONLY when composing today's bespoke HTML presentation. The
4
+ `renderReport` MCP-side renderer handles the rolling dashboard at
5
+ `.git-impact/result.html` automatically — this file is for the *daily artifact*
6
+ the user can share as a screenshot or paste-into-Slack visual.
7
+
8
+ ## Where to write
9
+
10
+ Use your `Write` tool to create:
11
+ - `<repo>/.git-impact/standups/YYYY-MM-DD.html` — today's bespoke file
12
+ - `<repo>/.git-impact/standups/index.html` — list of all standups (regenerate)
13
+
14
+ ## Stack (all CDN — no install)
15
+
16
+ | Tool | URL | When to use |
17
+ |---|---|---|
18
+ | Tailwind CSS | `<script src="https://cdn.tailwindcss.com"></script>` | Always |
19
+ | Inter font | `https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap` | Always |
20
+ | Chart.js | `https://cdn.jsdelivr.net/npm/chart.js` | Only if there are real numbers worth charting |
21
+ | Mermaid | `https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs` | Only for architecture/flow diagrams when relevant |
22
+ | Lucide icons | `https://unpkg.com/lucide@latest` | Optional — call `lucide.createIcons()` after DOM ready |
23
+
24
+ Don't include all of them. Pick what the day's content actually needs.
25
+
26
+ ## Required structure
27
+
28
+ 1. **Hero** — date label + a bold, plain-English headline that captures the day.
29
+ "Shipped safety analytics, hardened tenant isolation" — NOT "9 commits today".
30
+ 2. **Stats grid** — 3-4 metric cards (commits, files, PRs merged, areas touched).
31
+ 3. **Achievement cards** — one per ✅ item with status pill, title, summary,
32
+ "→ Why it matters" line, and small chips: PR #, area, file count, plus an
33
+ "inferred" chip when the bullet's provenance is `inferred`.
34
+ 4. **Optional visual** — only if the content warrants one:
35
+ - Mermaid flow diagram for architecture/data-flow changes
36
+ - Chart.js for ratios/comparisons
37
+ - Code block for a key formula or snippet
38
+ - Skip entirely if the day was straightforward — don't force visuals.
39
+ 5. **Footer** — file count, commit count, branch, link back to `index.html`.
40
+
41
+ ## Design language
42
+
43
+ - **Theme:** dark by default (`bg-slate-950`), generous spacing, max width 4xl
44
+ - **Cards:** `bg-slate-900/50 border border-slate-800 rounded-2xl p-6`
45
+ - **Status pills:**
46
+ - ✅ Shipped → `bg-emerald-500/20 text-emerald-400`
47
+ - ⏳ In Progress → `bg-amber-500/20 text-amber-400`
48
+ - 🚫 Blocked → `bg-rose-500/20 text-rose-400`
49
+ - **Inferred chip:** `bg-amber-500/10 text-amber-300/70 border border-amber-500/30`
50
+ with title attribute "Impact inferred — not explicitly stated in PR or commit"
51
+ - **Print-friendly:** include `@media print { ... }` that hides nav and switches to light theme
52
+ - **Spacing:** `max-w-4xl mx-auto px-8 py-12`, `space-y-6` between cards
53
+ - **Typography:** Inter, tight letter-spacing on headlines, 1.6 line-height on body
54
+
55
+ ## Skeleton (adapt content to today's actual work)
56
+
57
+ ```html
58
+ <!doctype html>
59
+ <html lang="en">
60
+ <head>
61
+ <meta charset="utf-8" />
62
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
63
+ <title>Standup — [Day, Date] · [Repo]</title>
64
+ <script src="https://cdn.tailwindcss.com"></script>
65
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
66
+ <style>
67
+ body { font-family: 'Inter', system-ui, sans-serif; }
68
+ @media print { .no-print { display: none } body { background: white; color: black; } }
69
+ </style>
70
+ </head>
71
+ <body class="bg-slate-950 text-slate-100 min-h-screen">
72
+ <div class="absolute inset-0 bg-[radial-gradient(circle_at_top,rgba(56,189,248,0.08),transparent_50%)] pointer-events-none"></div>
73
+
74
+ <main class="relative max-w-4xl mx-auto px-8 py-16">
75
+ <header class="mb-16">
76
+ <p class="text-sm uppercase tracking-widest text-slate-500 font-medium">[Saturday, May 9, 2026]</p>
77
+ <h1 class="mt-3 text-5xl font-bold tracking-tight leading-tight">[Headline that captures the day]</h1>
78
+ <p class="mt-4 text-xl text-slate-400 max-w-2xl">[One-sentence subtitle]</p>
79
+ </header>
80
+
81
+ <section class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-16">
82
+ <div class="bg-slate-900/50 border border-slate-800 rounded-2xl p-5">
83
+ <div class="text-3xl font-bold">[N]</div>
84
+ <div class="text-sm text-slate-400 mt-1">commits</div>
85
+ </div>
86
+ <!-- ... 3 more stat cards -->
87
+ </section>
88
+
89
+ <section class="space-y-4 mb-16">
90
+ <h2 class="text-xs uppercase tracking-widest text-slate-500 font-semibold mb-4">Shipped today</h2>
91
+ <article class="bg-slate-900/50 border border-slate-800 rounded-2xl p-6">
92
+ <div class="flex items-start gap-4">
93
+ <span class="px-2 py-1 rounded-md bg-emerald-500/20 text-emerald-400 text-xs font-medium">✅ Shipped</span>
94
+ <div class="flex-1">
95
+ <h3 class="text-lg font-semibold">[Plain-English title]</h3>
96
+ <p class="text-slate-300 mt-2 leading-relaxed">[One-sentence summary]</p>
97
+ <p class="text-slate-400 mt-3 text-sm">→ [Why it matters in business terms]</p>
98
+ <div class="flex gap-2 mt-4 flex-wrap">
99
+ <span class="text-xs px-2 py-0.5 rounded-full border border-slate-700 text-slate-400">PR #142</span>
100
+ <!-- Add an inferred chip when provenance === "inferred" -->
101
+ <span class="text-xs px-2 py-0.5 rounded-full bg-amber-500/10 text-amber-300/70 border border-amber-500/30" title="Impact inferred">inferred</span>
102
+ </div>
103
+ </div>
104
+ </div>
105
+ </article>
106
+ </section>
107
+
108
+ <footer class="pt-8 border-t border-slate-800 text-sm text-slate-500 flex justify-between">
109
+ <span>[N] files · [N] commits · [branch]</span>
110
+ <a href="./index.html" class="hover:text-slate-300">← All standups</a>
111
+ </footer>
112
+ </main>
113
+ </body>
114
+ </html>
115
+ ```
116
+
117
+ ## Index page
118
+
119
+ `<repo>/.git-impact/standups/index.html` should list every daily HTML file
120
+ (newest first). Same dark theme, simple grid of cards each linking to its day.
121
+ Keep it lightweight — don't re-render everything, just enumerate files.
122
+
123
+ ## Final line
124
+
125
+ After writing both files, print exactly this on the LAST line of your reply:
126
+
127
+ ```
128
+ 🎯 file:///<repo-absolute-path>/.git-impact/standups/YYYY-MM-DD.html
129
+ ```
130
+
131
+ Use the real absolute path so the user can ⌘-click.
@@ -0,0 +1,87 @@
1
+ # Translation rules
2
+
3
+ Read this file when translating commits into impact bullets. The main `SKILL.md`
4
+ covers orchestration; this file owns the prompt-engineering details.
5
+
6
+ ## Core rules
7
+
8
+ 1. **What + why, not what + how.** Each bullet must say what was accomplished
9
+ AND why it matters. "Fixed a bug in the auth middleware" is useless to a
10
+ manager. "Fixed login failures for admin users — unblocks the Q2 portal
11
+ launch" is useful.
12
+
13
+ 2. **Apply the glossary.** Replace every term in `context.json`'s `glossary`
14
+ with its plain-English equivalent. If no glossary exists, infer from
15
+ context but stay non-jargon.
16
+
17
+ 3. **Provenance is mandatory.** Every bullet you save via `save_impact_entry`
18
+ MUST include a `provenance` value. Use the strongest source available:
19
+
20
+ | Provenance | When to use |
21
+ |---|---|
22
+ | `pr` | The "why" came from the linked PR description body |
23
+ | `commit_body` | The "why" came from a multi-line commit message body (after the subject) |
24
+ | `commit_message` | The "why" was visible in the commit subject line itself |
25
+ | `ticket` | The "why" came from a linked Linear/Jira/GitHub issue |
26
+ | `inferred` | You guessed the impact without explicit text supporting it |
27
+
28
+ **Never label something `pr` or `commit_body` if you actually inferred it.**
29
+ Inferred is honest; faking provenance is worse than admitting a guess.
30
+
31
+ 4. **Group related commits.** Three commits all touching auth tell one story.
32
+ Write one bullet, not three. The grouping should follow the user's
33
+ *narrative*, not just shared paths — two commits in `/auth/` may be unrelated.
34
+
35
+ 5. **WIP / draft commits** get `status: "in_progress"` and the bullet should
36
+ describe the **expected outcome** when complete, not what was done so far.
37
+ "Refactoring auth flow → will reduce login latency by ~40%" beats
38
+ "WIP: extracted middleware function".
39
+
40
+ 6. **Blocked work** gets `status: "blocked"`. Use this when a commit is
41
+ reverted, a branch is abandoned, or the user explicitly says "stuck on X".
42
+
43
+ 7. **Be specific with numbers.** "Improved performance" is vague.
44
+ "Reduced login latency by ~40%" is specific. Pull numbers from commit
45
+ messages, PR descriptions, or diff stats. Don't invent them.
46
+
47
+ 8. **Refs help reviewers trust you.** When you have them, populate the `refs`
48
+ array: `["PR #142", "a1b2c3d", "ENG-1234"]`. These show as small chips in
49
+ the HTML report and let a reader click through to verify.
50
+
51
+ ## Output format (for the user-facing text reply)
52
+
53
+ ```
54
+ 📅 [Day, Date]
55
+
56
+ ✅ [Plain-English summary of what was accomplished]
57
+ → [Why it matters — who it unblocks, what risk it reduces, what it enables]
58
+
59
+ ⏳ In progress: [What is being worked on]
60
+ → [Expected outcome when complete]
61
+
62
+ 🚫 Blocked: [What is stuck]
63
+ → [What's needed to unblock]
64
+
65
+ 📁 [N] files changed across [brief description of areas touched]
66
+ [N] commit(s) on [branch name]
67
+ ```
68
+
69
+ If a bullet is `inferred`, the HTML report will mark it with an "inferred"
70
+ chip automatically — you don't need to do anything special in the text reply.
71
+
72
+ ## Tone
73
+
74
+ - Write for a non-technical manager. No jargon that isn't in the glossary.
75
+ - Short sentences. No filler. Skip "this change" / "this commit" constructions.
76
+ - Confident — if you know the impact, state it. If you don't, label it
77
+ `inferred` and use phrases like "technical foundation work for X". Never
78
+ hedge with "might potentially" or "could possibly".
79
+ - 2 accurate bullets beat 5 vague ones.
80
+
81
+ ## Anti-patterns
82
+
83
+ - ❌ Restating commit messages verbatim ("refactor: extract middleware")
84
+ - ❌ Inventing impact you can't ground in the data ("saves 10 hours per week")
85
+ - ❌ Mixing provenance — one bullet pulled from PR + one from inference labeled the same way
86
+ - ❌ Using `done` status when the work is genuinely in progress
87
+ - ❌ Writing 5+ bullets to look productive — pick the 2-3 that actually mattered
@@ -1,21 +0,0 @@
1
- import { GitSummary } from "../readers/git";
2
- import { GitHubSummary } from "../readers/github";
3
- import { UserContext } from "../storage/db";
4
- export interface TranslateInput {
5
- git: GitSummary;
6
- github: GitHubSummary | null;
7
- context: UserContext | null;
8
- dateLabel: string;
9
- }
10
- export declare function buildPrompt(input: TranslateInput): string;
11
- export declare function buildReviewPrompt(entries: Array<{
12
- date: string;
13
- items: Array<{
14
- status: string;
15
- summary: string;
16
- impact: string;
17
- }>;
18
- totalCommits: number;
19
- repoName: string;
20
- }>, context: UserContext | null, periodLabel: string): string;
21
- //# sourceMappingURL=prompt.d.ts.map