gitfamiliar 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,10 +1,28 @@
1
- # GitFamiliar
1
+ <p align="center">
2
+ <h1 align="center">GitFamiliar</h1>
3
+ <p align="center">
4
+ <strong>Visualize your code familiarity from Git history.</strong>
5
+ </p>
6
+ <p align="center">
7
+ <a href="https://www.npmjs.com/package/gitfamiliar"><img src="https://img.shields.io/npm/v/gitfamiliar.svg" alt="npm version"></a>
8
+ <a href="https://www.npmjs.com/package/gitfamiliar"><img src="https://img.shields.io/npm/dm/gitfamiliar.svg" alt="npm downloads"></a>
9
+ <a href="https://github.com/kuze/gitfamiliar/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/gitfamiliar.svg" alt="license"></a>
10
+ <a href="https://github.com/kuze/gitfamiliar/actions"><img src="https://github.com/kuze/gitfamiliar/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
11
+ </p>
12
+ </p>
2
13
 
3
- **Visualize your code familiarity from Git history.**
14
+ ---
4
15
 
5
- Existing tools (git-fame, GitHub Contributors, etc.) measure _how much_ you've written. GitFamiliar estimates _how well_ you understand the codebase. Built for engineers joining a new project, it lets you and your team objectively track onboarding progress.
16
+ Existing tools like git-fame and GitHub Contributors measure _how much_ you've written.
17
+ GitFamiliar measures something different: **how well you understand the codebase.**
18
+
19
+ Built for engineers joining a new project, it gives you and your team an objective way to track onboarding progress.
20
+
21
+ ## Demo
6
22
 
7
23
  ```
24
+ $ npx gitfamiliar
25
+
8
26
  GitFamiliar — my-project (Binary mode)
9
27
 
10
28
  Overall: 58/172 files (34%)
@@ -20,7 +38,18 @@ Overall: 58/172 files (34%)
20
38
  Written: 42 files | Reviewed: 23 files | Both: 7 files
21
39
  ```
22
40
 
23
- ## Install
41
+ Use `--html` to generate an interactive treemap in the browser:
42
+
43
+ ```
44
+ $ npx gitfamiliar --html
45
+ ```
46
+
47
+ > Area = lines of code, Color = familiarity (red -> green).
48
+ > Click folders to drill down. Toggle between All / Written / Reviewed views.
49
+
50
+ ## Quick Start
51
+
52
+ No install needed. Run inside any Git repository:
24
53
 
25
54
  ```bash
26
55
  npx gitfamiliar
@@ -32,137 +61,234 @@ Or install globally:
32
61
  npm install -g gitfamiliar
33
62
  ```
34
63
 
35
- ## Usage
36
-
37
- Run inside any Git repository:
64
+ ## Why GitFamiliar?
38
65
 
39
- ```bash
40
- # Binary mode (default) — which files have you touched?
41
- gitfamiliar
42
-
43
- # Authorship mode how much of the current code did you write? (git blame)
44
- gitfamiliar --mode authorship
45
-
46
- # Review Coverage — which files have you reviewed via PR?
47
- gitfamiliar --mode review-coverage
48
-
49
- # Weighted mode — combined score from blame, commits, and reviews
50
- gitfamiliar --mode weighted
66
+ | | git-fame / GitHub | GitFamiliar |
67
+ |---|---|---|
68
+ | What it measures | How much you **wrote** | How well you **understand** |
69
+ | Metric | Lines / commits (cumulative) | Familiarity score (multi-signal) |
70
+ | Use case | Contribution stats | Onboarding progress |
71
+ | Review awareness | No | Yes (PR reviews count) |
72
+ | Time decay | No | Yes (knowledge fades) |
51
73
 
52
- # HTML treemap report (opens in browser)
53
- gitfamiliar --html
74
+ ## Scoring Modes
54
75
 
55
- # Check a specific user
56
- gitfamiliar --user kota
76
+ GitFamiliar provides 4 modes so you can choose the right lens for your situation.
57
77
 
58
- # Filter by how you touched the code
59
- gitfamiliar --filter written # only files you committed to
60
- gitfamiliar --filter reviewed # only files you reviewed
78
+ ### Binary (default)
61
79
 
62
- # Expiration policies
63
- gitfamiliar --expiration time:180d # expire after 180 days
64
- gitfamiliar --expiration change:50% # expire if 50%+ changed
65
- gitfamiliar --expiration combined:365d:50%
80
+ Files are "read" or "unread". A file counts as read if you committed to it or approved a PR containing it.
66
81
 
67
- # Custom weights for weighted mode
68
- gitfamiliar --mode weighted --weights "0.5,0.35,0.15"
82
+ ```
83
+ familiarity = read_files / total_files
69
84
  ```
70
85
 
71
- ## Scoring Modes
72
-
73
- ### Binary (default)
74
-
75
- Files are either "read" or "unread". A file counts as read if you've committed to it or approved a PR containing it.
86
+ | View | Shows |
87
+ |---|---|
88
+ | All (default) | Written + Reviewed files |
89
+ | Written only | Only files you committed to |
90
+ | Reviewed only | Only files you reviewed via PR |
76
91
 
77
- ```
78
- score = read files / total files
92
+ ```bash
93
+ gitfamiliar # All
94
+ gitfamiliar --filter written # Written only
95
+ gitfamiliar --filter reviewed # Reviewed only
79
96
  ```
80
97
 
81
- Best for: **New team members** tracking onboarding progress.
98
+ > Best for: **New team members** tracking onboarding progress.
99
+ > Scores only go up (by default), giving a sense of achievement.
82
100
 
83
101
  ### Authorship
84
102
 
85
- Your share of the current codebase, based on `git blame`.
103
+ Your share of the current codebase, based on `git blame -w`.
86
104
 
87
105
  ```
88
- score = your blame lines / total lines
106
+ score(file) = your_blame_lines / total_lines
107
+ score(project) = sum(your_lines) / sum(all_lines)
89
108
  ```
90
109
 
91
- Best for: **Tech leads** assessing bus factor and code ownership distribution.
110
+ ```bash
111
+ gitfamiliar --mode authorship
112
+ ```
113
+
114
+ > Best for: **Tech leads** assessing bus factor and code ownership.
115
+ > A file where one person owns 95% of the lines is a risk signal.
92
116
 
93
117
  ### Review Coverage
94
118
 
95
- Files you've reviewed through PR approvals or comments (excluding your own commits).
119
+ Files you reviewed through PR approvals or comments, excluding your own commits.
96
120
 
97
121
  ```
98
- score = reviewed files / total files
122
+ score = reviewed_files / total_files
99
123
  ```
100
124
 
101
- Best for: **Senior engineers** tracking review breadth. Requires a GitHub token.
125
+ ```bash
126
+ gitfamiliar --mode review-coverage
127
+ ```
128
+
129
+ > Best for: **Senior engineers** tracking how broadly they review.
130
+ > Requires a GitHub token (see [GitHub Integration](#github-integration)).
102
131
 
103
132
  ### Weighted
104
133
 
105
- Combines blame, commit frequency, and review signals with configurable weights and time decay.
134
+ The most nuanced mode. Combines three signals with configurable weights and time decay:
106
135
 
107
136
  ```
108
- score = 0.5 × blame_score + 0.35 × commit_score + 0.15 × review_score
137
+ familiarity = w1 x blame_score + w2 x commit_score + w3 x review_score
109
138
  ```
110
139
 
111
- Commit contributions use sigmoid normalization and exponential recency decay (half-life: 180 days). Review scores account for PR size (attention dilution).
140
+ Default weights: `blame=0.5, commit=0.35, review=0.15`
141
+
142
+ Key features:
143
+ - **Sigmoid normalization** prevents a single large commit from dominating
144
+ - **Recency decay** (half-life: 180 days) models knowledge fading over time
145
+ - **Scope factor** discounts reviews on huge PRs (attention dilution)
112
146
 
113
- Best for: **Power users** who want the most nuanced picture.
147
+ ```bash
148
+ gitfamiliar --mode weighted
149
+ gitfamiliar --mode weighted --weights "0.6,0.3,0.1" # custom weights
150
+ ```
114
151
 
115
- ## HTML Report
152
+ <details>
153
+ <summary><b>Numerical example</b></summary>
116
154
 
117
- Use `--html` to generate an interactive treemap visualization:
155
+ File: `src/auth/login.ts` (200 lines)
118
156
 
119
- - **Area** = lines of code (file/folder volume)
120
- - **Color** = familiarity score (red yellow green)
121
- - Click folders to drill down
122
- - Toggle between All / Written / Reviewed views
123
- - Hover for detailed scores
157
+ ```
158
+ blame_score = 30 lines / 200 lines = 0.15
124
159
 
125
- ## File Filtering
160
+ commit_score:
161
+ commit 1 (10 days ago, +30/-0): sigmoid(30/200) x decay(10d) = 0.33 x 0.96
162
+ commit 2 (45 days ago, +5/-2): sigmoid(6/200) x decay(45d) = 0.09 x 0.84
163
+ total: min(1, 0.39) = 0.39
126
164
 
127
- GitFamiliar ignores lock files, build outputs, and generated code by default. Customize by creating `.gitfamiliarignore` in your repo root (same syntax as `.gitignore`):
165
+ review_score:
166
+ PR approved (20 days ago, 4 files): 0.30 x 1.0 x decay(20d) = 0.28
128
167
 
129
- ```gitignore
130
- # Example: also ignore vendor code
131
- vendor/
132
- third_party/
168
+ familiarity = 0.5 x 0.15 + 0.35 x 0.39 + 0.15 x 0.28
169
+ = 0.075 + 0.137 + 0.042
170
+ = 0.254 -> 25%
133
171
  ```
134
172
 
135
- Default exclusions: `package-lock.json`, `yarn.lock`, `*.min.js`, `*.map`, `dist/`, `build/`, etc.
173
+ </details>
174
+
175
+ > Best for: **Power users** who want the most accurate picture.
176
+ > Score breakdowns are always visible so it never feels like a black box.
136
177
 
137
178
  ## Expiration Policies
138
179
 
139
- Control whether "read" status expires over time:
180
+ By default, "read" status never expires. But real knowledge fades. Configure expiration to keep scores honest:
140
181
 
141
- | Policy | Flag | Behavior |
182
+ | Policy | Flag | What happens |
142
183
  |---|---|---|
143
- | Never (default) | `--expiration never` | Once read, always read |
144
- | Time-based | `--expiration time:180d` | Expires 180 days after last touch |
145
- | Change-based | `--expiration change:50%` | Expires if 50%+ of the file changed since your last touch |
146
- | Combined | `--expiration combined:365d:50%` | Expires if either condition is met |
184
+ | Never | `--expiration never` | Once read, always read (default) |
185
+ | Time-based | `--expiration time:180d` | Expires 180 days after your last touch |
186
+ | Change-based | `--expiration change:50%` | Expires if 50%+ of the file changed since you last touched it |
187
+ | Combined | `--expiration combined:365d:50%` | Expires if **either** condition is met |
188
+
189
+ The change-based policy is the smartest: it detects when the code you read has been substantially rewritten, meaning your understanding is likely outdated.
190
+
191
+ ## File Filtering
192
+
193
+ GitFamiliar automatically ignores noise. It only considers git-tracked files, minus:
194
+
195
+ - Lock files (`package-lock.json`, `yarn.lock`, etc.)
196
+ - Generated/minified files (`*.min.js`, `*.map`, `*.generated.*`)
197
+ - Build outputs (`dist/`, `build/`, `.next/`)
198
+ - Config files that rarely need understanding (`tsconfig.json`, `.eslintrc*`)
199
+
200
+ ### Custom filtering
201
+
202
+ Create a `.gitfamiliarignore` in your repo root (same syntax as `.gitignore`):
203
+
204
+ ```gitignore
205
+ # Also ignore vendor code
206
+ vendor/
207
+ third_party/
208
+
209
+ # Ignore migration files
210
+ **/migrations/
211
+ ```
147
212
 
148
213
  ## GitHub Integration
149
214
 
150
- For review-related features (Review Coverage mode, reviewed files in Binary mode), set a GitHub token:
215
+ For review-related features (Review Coverage mode, reviewed files in Binary mode), GitFamiliar needs a GitHub token:
151
216
 
152
217
  ```bash
153
218
  # Option 1: environment variable
154
- export GITHUB_TOKEN=ghp_xxx
219
+ export GITHUB_TOKEN=ghp_xxxxxxxxxxxxx
155
220
 
156
- # Option 2: GitHub CLI (auto-detected)
221
+ # Option 2: GitHub CLI (auto-detected if installed)
157
222
  gh auth login
158
223
  ```
159
224
 
225
+ Without a token, GitFamiliar works perfectly for all non-review features. Review features degrade gracefully with a helpful message.
226
+
227
+ ## CLI Reference
228
+
229
+ ```
230
+ Usage: gitfamiliar [options]
231
+
232
+ Options:
233
+ -m, --mode <mode> Scoring mode (default: "binary")
234
+ Choices: binary, authorship, review-coverage, weighted
235
+ -u, --user <user> Git user name or email (default: git config)
236
+ -f, --filter <filter> Display filter (default: "all")
237
+ Choices: all, written, reviewed
238
+ -e, --expiration <policy> Expiration policy (default: "never")
239
+ Examples: time:180d, change:50%, combined:365d:50%
240
+ --html Generate interactive HTML treemap report
241
+ -w, --weights <weights> Weights for weighted mode: blame,commit,review
242
+ Example: "0.5,0.35,0.15" (must sum to 1.0)
243
+ -V, --version Output version number
244
+ -h, --help Display help
245
+ ```
246
+
247
+ ## Programmatic API
248
+
249
+ GitFamiliar can also be used as a library:
250
+
251
+ ```typescript
252
+ import { computeFamiliarity } from 'gitfamiliar';
253
+
254
+ const result = await computeFamiliarity({
255
+ mode: 'binary',
256
+ filter: 'all',
257
+ expiration: { policy: 'never' },
258
+ weights: { blame: 0.5, commit: 0.35, review: 0.15 },
259
+ html: false,
260
+ repoPath: '/path/to/repo',
261
+ });
262
+
263
+ console.log(`Score: ${Math.round(result.tree.score * 100)}%`);
264
+ ```
265
+
160
266
  ## Requirements
161
267
 
162
- - Node.js >= 18
163
- - Git
164
- - GitHub token (optional, for review features)
268
+ - **Node.js** >= 18
269
+ - **Git** (available in PATH)
270
+ - **GitHub token** (optional, for review features)
271
+
272
+ ## Contributing
273
+
274
+ Contributions are welcome! Please open an issue first to discuss what you'd like to change.
275
+
276
+ ```bash
277
+ git clone https://github.com/kuze/gitfamiliar.git
278
+ cd gitfamiliar
279
+ npm install
280
+ npm run build
281
+ npm test
282
+ ```
283
+
284
+ ## Roadmap
285
+
286
+ - [ ] **Dependency Awareness** - Factor in understanding of imported files
287
+ - [ ] **Churn Risk Alert** - Highlight files with high change frequency + low familiarity
288
+ - [ ] **GitHub Action** - Post familiarity reports as PR comments
289
+ - [ ] **VS Code Extension** - See familiarity scores inline in the editor
290
+ - [ ] **README Badge** - Codecov-style badge for your project README
165
291
 
166
292
  ## License
167
293
 
168
- MIT
294
+ [MIT](LICENSE)
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitfamiliar",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Visualize your code familiarity from Git history",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,7 +13,7 @@
13
13
  "templates"
14
14
  ],
15
15
  "scripts": {
16
- "build": "tsup && node -e \"const fs=require('fs');const f='dist/bin/gitfamiliar.js';const c=fs.readFileSync(f,'utf8');if(!c.startsWith('#!'))fs.writeFileSync(f,'#!/usr/bin/env node\\n'+c)\"",
16
+ "build": "tsup && node -e \"const fs=require('fs');const f='dist/bin/gitfamiliar.js';const c=fs.readFileSync(f,'utf8');if(!c.startsWith('#!'))fs.writeFileSync(f,'#!/usr/bin/env node\\n'+c)\" && chmod +x dist/bin/gitfamiliar.js",
17
17
  "dev": "tsup --watch",
18
18
  "test": "vitest run",
19
19
  "test:watch": "vitest",