whygit 0.1.0 → 0.1.1

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.
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
- <div align="center">
1
+ <div align="center">
2
2
 
3
3
  # whygit
4
4
 
5
5
  **Git blame tells you *who*. whygit tells you *why*.**
6
6
 
7
7
  Point it at any repository. It turns the reasons already buried in git history
8
- into answers you and your coding agent can cite — file, line, commit, author, date.
8
+ into answers you and your coding agent can cite 鈥?file, line, commit, author, date.
9
9
 
10
10
  [![npm](https://img.shields.io/npm/v/whygit?color=cb3837)](https://www.npmjs.com/package/whygit)
11
11
  [![tests](https://github.com/carefreebit/whygit/actions/workflows/ci.yml/badge.svg)](https://github.com/carefreebit/whygit/actions/workflows/ci.yml)
@@ -13,19 +13,19 @@ into answers you and your coding agent can cite — file, line, commit, author,
13
13
  [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
14
14
  [![MCP](https://img.shields.io/badge/MCP-ready-6b46c1)](#give-it-to-your-agent)
15
15
 
16
- [中文](README.zh-CN.md) · [Quickstart](#quickstart) · [Commands](#commands) · [Agents](#give-it-to-your-agent) · [How it works](#how-it-works)
16
+ [涓枃](README.zh-CN.md) 路 [Quickstart](#quickstart) 路 [Commands](#commands) 路 [Agents](#give-it-to-your-agent) 路 [How it works](#how-it-works)
17
17
 
18
18
  </div>
19
19
 
20
20
  ---
21
21
 
22
22
  <p align="center">
23
- <img src="docs/demo.svg" alt="whygit why &quot;cookie jar&quot; in a terminal" width="900">
23
+ <img src="https://raw.githubusercontent.com/carefreebit/whygit/main/docs/demo.svg" alt="whygit why &quot;cookie jar&quot; in a terminal" width="900">
24
24
  </p>
25
25
 
26
- <p align="center"><sub>Real output: <code>whygit why "cookie jar"</code> on <code>psf/requests</code> — 4,884 commits indexed in 3s, answered in 21ms.</sub></p>
26
+ <p align="center"><sub>Real output: <code>whygit why "cookie jar"</code> on <code>psf/requests</code> 鈥?4,884 commits indexed in 3s, answered in 21ms.</sub></p>
27
27
 
28
- That answer existed all along — in a commit body from 2015 that nobody has read since.
28
+ That answer existed all along 鈥?in a commit body from 2015 that nobody has read since.
29
29
  whygit found it in 21 milliseconds, without an LLM, an API key, or a network call.
30
30
 
31
31
  ## The problem
@@ -38,7 +38,7 @@ redundant. A guard that seems paranoid. A `sleep(2)` that looks like laziness.
38
38
  - LLM summaries of history **invent plausible reasons**. In a codebase, a plausible
39
39
  wrong reason is worse than no reason.
40
40
  - Coding agents are the worst affected: they rewrite the guard, delete the retry, and
41
- the bug comes back six months later — because nothing told them the line was load-bearing.
41
+ the bug comes back six months later 鈥?because nothing told them the line was load-bearing.
42
42
 
43
43
  whygit reads what your repository already wrote down, extracts the sentences that
44
44
  actually explain a decision, and makes them retrievable in the two places that matter:
@@ -68,7 +68,7 @@ it is incremental: new commits are picked up automatically on the next run.
68
68
  | `whygit why <words>` | Why does this behaviour exist? Ranked decisions with citations. |
69
69
  | `whygit why <file>:<line>` | Why is *this line* still here? Blame + the decision behind it + how much of that change is still alive. |
70
70
  | `whygit story <file>` | The biography of one file: birth, commits per year, the chapters that mattered, who kept it alive. |
71
- | `whygit cursed` | Ranked risk map: churn × fix density × author spread × freshness. Read before refactoring. |
71
+ | `whygit cursed` | Ranked risk map: churn 脳 fix density 脳 author spread 脳 freshness. Read before refactoring. |
72
72
  | `whygit whylog --write` | Generate `WHYLOG.md`: load-bearing decisions + cursed files, in Markdown. |
73
73
  | `whygit check --base origin/main` | CI gate: what fraction of newly added lines trace to a commit that said why. |
74
74
  | `whygit mcp` | MCP server over stdio for Claude Code, Cursor, Codex, and any MCP client. |
@@ -83,30 +83,30 @@ Every command takes `--json` for scripting, and `--cwd <path>` to point at anoth
83
83
  $ whygit why src/requests/models.py:120
84
84
 
85
85
  1. basics working
86
- 2012-12-15 · 366e8e84 · Kenneth Reitz · change
86
+ 2012-12-15 路 366e8e84 路 Kenneth Reitz 路 change
87
87
  line 120 is 78 lines of this change, still in HEAD
88
88
 
89
89
  2. Add hasattr checks for remaining protocol isinstance checks (#7505)
90
- 2026-06-09 · 6f66281a · change
90
+ 2026-06-09 路 6f66281a 路 change
91
91
  ```
92
92
 
93
93
  The line itself is unremarkable. What matters is that 78 lines around it are still
94
- the original 2012 change — so the surrounding shape is load-bearing, not incidental.
94
+ the original 2012 change 鈥?so the surrounding shape is load-bearing, not incidental.
95
95
 
96
96
  ### `story <file>`
97
97
 
98
98
  ```console
99
99
  $ whygit story src/requests/models.py
100
100
 
101
- born 2011-05-14 · package refactor
101
+ born 2011-05-14 路 package refactor
102
102
 
103
- 2011 ██████████████████████████████████······ 217
104
- 2012 ████████████████████████████████████████ 254
105
- 2013 ██████████████·························· 86
103
+ 2011 鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅路路路路路路 217
104
+ 2012 鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅 254
105
+ 2013 鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅路路路路路路路路路路路路路路路路路路路路路路路路路路 86
106
106
  ...
107
107
 
108
- 717 commits · 202 authors · 154 fixes · 0 TODO markers
109
- ─── the plot ──────────────────────────────────────────────────
108
+ 717 commits 路 202 authors 路 154 fixes 路 0 TODO markers
109
+ 鈹€鈹€鈹€ the plot 鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€
110
110
 
111
111
  2015-04-06 Copy a PreparedRequest's CookieJar reliably
112
112
  By adding _copy_cookie_jar we can reliably copy cookie jars so that we
@@ -119,12 +119,12 @@ $ whygit story src/requests/models.py
119
119
  ```console
120
120
  $ whygit cursed
121
121
 
122
- 1 src/requests/models.py ██████████████ 8.1 717 commits · 202 authors · 154 fixes
123
- 2 src/requests/sessions.py █████████████· 7.5 334 commits · 110 authors · 79 fixes
124
- 3 tests/test_requests.py ████████████·· 7.2 366 commits · 104 authors · 76 fixes
122
+ 1 src/requests/models.py 鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅 8.1 717 commits 路 202 authors 路 154 fixes
123
+ 2 src/requests/sessions.py 鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻埪? 7.5 334 commits 路 110 authors 路 79 fixes
124
+ 3 tests/test_requests.py 鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅鈻堚枅路路 7.2 366 commits 路 104 authors 路 76 fixes
125
125
  ```
126
126
 
127
- Not a code-quality judgement — a map of where history is dense enough that a
127
+ Not a code-quality judgement 鈥?a map of where history is dense enough that a
128
128
  confident rewrite is likely to be wrong.
129
129
 
130
130
  ## Give it to your agent
@@ -159,18 +159,17 @@ Before changing a line you do not understand, call `why_line` (MCP: whygit).
159
159
  If a past decision contradicts your plan, say so before editing.
160
160
  ```
161
161
 
162
- ### WHYLOG.md — history your agent reads without being asked
162
+ ### WHYLOG.md 鈥?history your agent reads without being asked
163
163
 
164
164
  `whygit whylog --write` produces a Markdown file that is small enough to live in a
165
165
  repo and specific enough to change a decision:
166
166
 
167
- - **Load-bearing decisions** — ranked, each with the verbatim reason, date, commit, author, and the files it touches.
168
- - **The cursed files** — a table of where history is thickest.
169
- - **House rule** — the one-line convention (`WHY: ...`) that makes future commits explain themselves.
167
+ - **Load-bearing decisions** 鈥?ranked, each with the verbatim reason, date, commit, author, and the files it touches.
168
+ - **The cursed files** 鈥?a table of where history is thickest.
169
+ - **House rule** 鈥?the one-line convention (`WHY: ...`) that makes future commits explain themselves.
170
170
 
171
171
  It is generated from git, never hand-edited, and it diffs cleanly in review.
172
- Commit it, and every agent that starts in the repo gets the context for free —
173
- no MCP required.
172
+ Commit it, and every agent that starts in the repo gets the context for free 鈥?no MCP required.
174
173
 
175
174
  ### CI gate
176
175
 
@@ -185,25 +184,18 @@ It is a nudge, not a linter: the fix is one sentence in the commit body.
185
184
 
186
185
  ```text
187
186
  git log (two passes: metadata + numstat)
188
- │
189
- ▼
190
- signals: strip trailers, drop bot noise, de-duplicate squash-merge subjects,
187
+ 鈹? 鈻? signals: strip trailers, drop bot noise, de-duplicate squash-merge subjects,
191
188
  keep sentences that contain a reason ("because", "so that", "to avoid",
192
- "由于", "避免", "回滚" ...)
193
- │
194
- ▼
195
- SQLite .git/whygit/index.db commits · files · decisions · FTS5 · risk
196
- │
197
- ▼
198
- ranking: BM25 × confidence × churn × recency × fix-density × noise penalties
199
- │
200
- ├── whygit why / story / cursed (terminal)
201
- ├── whygit whylog (WHYLOG.md)
202
- └── whygit mcp (agents)
189
+ "鐢变簬", "閬垮厤", "鍥炴粴" ...)
190
+ 鈹? 鈻? SQLite .git/whygit/index.db commits 路 files 路 decisions 路 FTS5 路 risk
191
+ 鈹? 鈻? ranking: BM25 脳 confidence 脳 churn 脳 recency 脳 fix-density 脳 noise penalties
192
+ 鈹? 鈹溾攢鈹€ whygit why / story / cursed (terminal)
193
+ 鈹溾攢鈹€ whygit whylog (WHYLOG.md)
194
+ 鈹斺攢鈹€ whygit mcp (agents)
203
195
  ```
204
196
 
205
197
  **What a "decision" is:** a commit whose message contains a sentence explaining a
206
- choice. whygit does not interpret that sentence — it quotes it. If the message says
198
+ choice. whygit does not interpret that sentence 鈥?it quotes it. If the message says
207
199
  nothing, the decision has low confidence and ranks below the ones that do.
208
200
 
209
201
  **Why it can be fast:** the whole index is built from two `git log` passes, and
@@ -211,13 +203,13 @@ queries run against FTS5 in the same process. On a laptop, 4,884 commits index i
211
203
  ~3 seconds and a query takes ~20 ms. No network, no model, no cache to warm.
212
204
 
213
205
  **What it will not do:** invent a reason, summarise code, or judge quality. If the
214
- history is silent, whygit says so — silence is a finding too.
206
+ history is silent, whygit says so 鈥?silence is a finding too.
215
207
 
216
208
  ## Compared to
217
209
 
218
210
  | | Answers "why" | Cites the source | Works offline | Agent-native |
219
211
  | --- | :---: | :---: | :---: | :---: |
220
- | `git blame` | no | — | yes | no |
212
+ | `git blame` | no | 鈥?| yes | no |
221
213
  | `git log` | only if you already know where to look | yes | yes | no |
222
214
  | LLM-generated docs | sometimes | rarely | no | partly |
223
215
  | **whygit** | **yes** | **yes (sha + file + line)** | **yes** | **yes (MCP + WHYLOG.md)** |
@@ -246,7 +238,7 @@ index under `.git/`. History is read-only.
246
238
  - Rationale can only be as good as commit messages. whygit makes silence visible; it cannot fill it.
247
239
  - Very large histories (500k+ commits) index in minutes, not seconds.
248
240
  - Renames are followed by path, not by content similarity: a file moved twice may have two histories.
249
- - The ranking is heuristic. It is tuned to prefer cited reasons over churn, and it will still be wrong sometimes — each result shows its citations so you can check.
241
+ - The ranking is heuristic. It is tuned to prefer cited reasons over churn, and it will still be wrong sometimes 鈥?each result shows its citations so you can check.
250
242
 
251
243
  ## Contributing
252
244
 
@@ -257,7 +249,7 @@ npm run lint
257
249
  node bin/whygit.js why "..." --cwd /path/to/any/repo
258
250
  ```
259
251
 
260
- Issues and PRs welcome — especially real-world ranking failures. Paste the query, the
252
+ Issues and PRs welcome 鈥?especially real-world ranking failures. Paste the query, the
261
253
  repo, and what should have ranked first.
262
254
 
263
255
  ## License
@@ -271,6 +263,6 @@ MIT. See [LICENSE](LICENSE).
271
263
  If whygit saved you from deleting a load-bearing line, a star helps the next person
272
264
  find it.
273
265
 
274
- **[⭐ Star whygit](https://github.com/carefreebit/whygit)**
266
+ **[猸?Star whygit](https://github.com/carefreebit/whygit)**
275
267
 
276
268
  </div>
package/README.zh-CN.md CHANGED
@@ -20,7 +20,7 @@
20
20
  ---
21
21
 
22
22
  <p align="center">
23
- <img src="docs/demo.svg" alt="whygit why &quot;cookie jar&quot; 终端演示" width="900">
23
+ <img src="https://raw.githubusercontent.com/carefreebit/whygit/main/docs/demo.svg" alt="whygit why &quot;cookie jar&quot; 终端演示" width="900">
24
24
  </p>
25
25
 
26
26
  <p align="center"><sub>真实输出:在 <code>psf/requests</code> 上执行 <code>whygit why "cookie jar"</code> —— 4,884 个 commit 索引 3 秒,回答 21 毫秒。</sub></p>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whygit",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Git blame tells you who. whygit tells you why. Turn git history into cited, agent-readable context.",
5
5
  "type": "module",
6
6
  "bin": {