git-impact 0.2.2 → 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 -252
  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 +18 -8
  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 +132 -160
  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,231 +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)
52
-
53
- ```bash
54
- cat "$REPO_ROOT/.git-impact/context.json" 2>/dev/null || echo "NONE"
55
- ```
51
+ ## Mode: standup
56
52
 
57
- If the file exists, parse it. It looks like:
53
+ ### 1. Resolve the lookback window
58
54
 
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
- ```
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.
70
59
 
71
- Use this to personalise your translationapply 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.
60
+ This is the "since last standup" default it survives weekends and days off.
74
61
 
75
- ---
76
-
77
- ## Mode: today / since \<when\>
62
+ ### 2. Fetch git activity
78
63
 
79
- ### Fetch commits
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.
80
66
 
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
- ```
67
+ If there are no commits in the window: tell the user clearly and stop. Do
68
+ NOT save an empty entry.
89
69
 
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"`
70
+ ### 3. Optional: enrich with GitHub PR data
94
71
 
95
- ### Fetch files changed
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.
96
77
 
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
- ```
78
+ ### 4. Translate
102
79
 
103
- ### Translate
80
+ Read **`references/translation-rules.md`** for the prompt-engineering details.
81
+ Key rules at a glance:
104
82
 
105
- If there are no commits, say so clearly and stop.
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
106
90
 
107
- Otherwise translate into **2–5 bullet points**. Follow these rules:
91
+ ### 5. Print the user-facing output
108
92
 
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.
93
+ ```
94
+ 📅 [Day, Date or date range]
113
95
 
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.
96
+ [Summary]
97
+ [Why it matters]
116
98
 
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.
99
+ In progress: [What]
100
+ [Expected outcome]
119
101
 
120
- 4. **Group related commits.** Three commits all touching auth tell one story —
121
- write one bullet, not three.
102
+ 🚫 Blocked: [What] (only if applicable)
103
+ [What's needed]
122
104
 
123
- 5. **WIP / draft commits** get `⏳ In progress:` and state what the expected
124
- outcome is, not what was done so far.
105
+ 📁 [N] files across [areas]
106
+ [N] commit(s) on [branch]
107
+ ```
125
108
 
126
- 6. **Be specific.** "Improved performance" is vague. "Reduced login latency
127
- by ~40%" is specific. Use whatever numbers exist in the commit messages.
109
+ ### 6. Save to history
128
110
 
129
- ### Output format
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`.
130
115
 
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
+ }
131
125
  ```
132
- 📅 [Day, Date]
133
126
 
134
- [Plain-English summary of what was accomplished]
135
- → [Why it matters — who it unblocks, what risk it reduces, what it enables]
127
+ ### 7. Point the user at the dashboard
136
128
 
137
- In progress: [What is being worked on]
138
- [Expected outcome when complete]
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:
139
133
 
140
- 📁 [N] files changed across [brief description of areas touched]
141
- [N] commit(s) on [branch name]
142
134
  ```
143
-
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
- "
135
+ 🎯 file:///<absolute-repo-path>/.git-impact/result.html
167
136
  ```
168
137
 
169
- If `sqlite3` is not available, skip silently.
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.
170
143
 
171
144
  ---
172
145
 
173
146
  ## Mode: review
174
147
 
175
- Fetch saved history and synthesise a performance review.
176
-
177
- Parse the period from the user's message:
178
- - `last 30 days` / `30d` → last 30 days
179
- - `last 90 days` / `90d` → last 90 days (default)
180
- - `Q2-2026` April 1 June 30, 2026
181
-
182
- ```bash
183
- sqlite3 "$REPO_ROOT/.git-impact/history.db" \
184
- "SELECT date, repo_name, total_commits, items_json
185
- FROM impact_entries
186
- WHERE date >= '$FROM' AND date <= '$TO'
187
- 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:
188
163
  ```
164
+ Performance Review Prep — [Period]
189
165
 
190
- If the DB doesn't exist or returns nothing: *"No saved history found for this
191
- period. Use the standup mode daily to build up history, then come back."*
192
-
193
- Otherwise synthesise:
194
-
195
- ```
196
- Performance Review — [Period]
197
-
198
- [One headline sentence — biggest contribution this period]
166
+ [One headline sentence biggest contribution]
199
167
 
200
168
  🚀 [High-impact theme]
201
- • Specific achievement...
169
+ • Specific achievement [date, refs]
202
170
 
203
171
  ✅ [Medium-impact theme]
204
- Specific achievement...
172
+ • ...
205
173
 
206
174
  🔧 [Lower-impact theme]
207
175
  • ...
208
176
 
209
- ---
210
177
  📊 [N] commits across [N] working days
211
178
  ```
212
179
 
213
- Group by theme (Features shipped, Reliability, Security, Code review,
214
- Infrastructure). Only include themes that apply.
215
-
216
180
  ---
217
181
 
218
182
  ## Mode: init
219
183
 
220
- Ask the user three questions one at a time:
184
+ Ask one at a time:
221
185
 
222
186
  1. *"What does your company/product do? (1–2 sentences)"*
223
187
  2. *"What does your manager care most about?"*
224
- 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)"*
225
189
 
226
- Then write `.git-impact/context.json` and tell the user:
227
- *"Saved to `.git-impact/context.json`. Commit this to share the glossary with
228
- 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.
229
196
 
230
197
  ---
231
198
 
@@ -233,6 +200,11 @@ your team. history.db is gitignored automatically."*
233
200
 
234
201
  - Write for a non-technical manager. No jargon that isn't in the glossary.
235
202
  - Short sentences. No filler. Skip "this change" / "this commit" constructions.
236
- - Confident — if you know the impact, state it. If not, use
237
- "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".
238
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/translator/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,UAAU,CAAC;IAChB,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAmFzD;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,EACF,OAAO,EAAE,WAAW,GAAG,IAAI,EAC3B,WAAW,EAAE,MAAM,GAClB,MAAM,CAyCR"}