@say8425/cc-statusline 1.2.0 → 1.3.0

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 (3) hide show
  1. package/README.md +7 -6
  2. package/package.json +1 -1
  3. package/src/index.ts +57 -10
package/README.md CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  Custom statusline for Claude Code.
4
4
 
5
- [![npm](https://img.shields.io/npm/v/@say8425/cc-statusline)](https://www.npmjs.com/package/@say8425/cc-statusline)
6
- ![Bun](https://img.shields.io/badge/Bun-black?style=flat&logo=bun)
7
- ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=flat&logo=typescript&logoColor=white)
5
+ [![Claude Code](https://img.shields.io/badge/Claude_Code-D97757?style=flat&logo=claude&logoColor=white)](https://code.claude.com/docs/en/statusline)
6
+ [![npm](https://img.shields.io/npm/v/%40say8425%2Fcc-statusline?logo=npm&logoColor=%23CC3534&color=%23CC3534)](https://www.npmjs.com/package/@say8425/cc-statusline)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=flat&logo=typescript&logoColor=white)](https://www.typescriptlang.org)
8
+ [![Bun](https://img.shields.io/badge/Bun-black?style=flat&logo=bun)](https://bun.sh)
8
9
 
9
10
  ## Preview
10
11
 
@@ -41,9 +42,9 @@ Add the following to `~/.claude/settings.json`:
41
42
 
42
43
  ## Color Thresholds
43
44
 
44
- | Metric | Normal (white) | Warning (yellow) | Critical (red) |
45
- |--------|----------------|------------------|----------------|
46
- | Context % | < 50% | 50-80% | > 80% |
45
+ | Metric | Normal (white) | Warning (yellow) | Critical (red) |
46
+ | --------- | -------------- | ---------------- | -------------- |
47
+ | Context % | < 50% | 50-80% | > 80% |
47
48
 
48
49
  ## License
49
50
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@say8425/cc-statusline",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "description": "Custom statusline for Claude Code",
6
6
  "repository": {
package/src/index.ts CHANGED
@@ -26,12 +26,14 @@ interface ClaudeStatusInput {
26
26
  // 캐시 구조
27
27
  const cache = {
28
28
  branch: { value: "", timestamp: 0 },
29
+ gitChanges: { files: 0, insertions: 0, deletions: 0, timestamp: 0 },
29
30
  prUrl: { value: null as string | null, timestamp: 0 },
30
31
  };
31
32
 
32
33
  // 캐시 TTL (ms)
33
34
  const CACHE_TTL = {
34
35
  branch: 5000, // 5초
36
+ gitChanges: 3000, // 3초
35
37
  prUrl: 30000, // 30초
36
38
  };
37
39
 
@@ -88,6 +90,40 @@ async function getBranchCached(): Promise<string> {
88
90
  }
89
91
  }
90
92
 
93
+ // Git 변경사항 가져오기 (캐싱)
94
+ async function getGitChangesCached(): Promise<{
95
+ files: number;
96
+ insertions: number;
97
+ deletions: number;
98
+ }> {
99
+ if (Date.now() - cache.gitChanges.timestamp < CACHE_TTL.gitChanges) {
100
+ return cache.gitChanges;
101
+ }
102
+ try {
103
+ const [diff, staged] = await Promise.all([
104
+ $`git diff --shortstat 2>/dev/null`.text(),
105
+ $`git diff --cached --shortstat 2>/dev/null`.text(),
106
+ ]);
107
+ const combined = `${diff}\n${staged}`;
108
+
109
+ // 파일 수, insertions, deletions 추출
110
+ const [files, insertions, deletions] = [
111
+ /(\d+) file/g,
112
+ /(\d+) insertion/g,
113
+ /(\d+) deletion/g,
114
+ ].map((regex) =>
115
+ (combined.match(regex) || []).reduce(
116
+ (sum, m) => sum + Number.parseInt(m, 10),
117
+ 0,
118
+ ),
119
+ );
120
+ cache.gitChanges = { files, insertions, deletions, timestamp: Date.now() };
121
+ return cache.gitChanges;
122
+ } catch {
123
+ return cache.gitChanges;
124
+ }
125
+ }
126
+
91
127
  // PR URL 가져오기 (캐싱)
92
128
  async function getPrUrlCached(): Promise<string | null> {
93
129
  if (Date.now() - cache.prUrl.timestamp < CACHE_TTL.prUrl) {
@@ -134,8 +170,9 @@ async function main() {
134
170
  const ctxColor = getContextColor(contextPct);
135
171
 
136
172
  // 6. Git 정보 (캐싱, 병렬 실행)
137
- const [branch, prUrl] = await Promise.all([
173
+ const [branch, gitChanges, prUrl] = await Promise.all([
138
174
  getBranchCached(),
175
+ getGitChangesCached(),
139
176
  getPrUrlCached(),
140
177
  ]);
141
178
 
@@ -154,15 +191,25 @@ async function main() {
154
191
  `${ctxColor}🧠 ${formatNumber(totalTokens)} (${contextPct}%)${C.RESET}`,
155
192
  );
156
193
 
157
- // 3번째 줄: PR URL (있을 경우만)
158
- if (prUrl) {
159
- const prLabel = prUrl
160
- .replace("https://github.com/", "")
161
- .replace("/pull/", "#");
162
- // OSC 8 하이퍼링크
163
- console.log(
164
- `📎 ${C.WHITE}${C.UNDERLINE}\x1b]8;;${prUrl}\x07${prLabel}\x1b]8;;\x07${C.RESET}`,
165
- );
194
+ // 3번째 줄: git changes | PR URL
195
+ const hasGitChanges =
196
+ gitChanges.files > 0 ||
197
+ gitChanges.insertions > 0 ||
198
+ gitChanges.deletions > 0;
199
+ if (hasGitChanges || prUrl) {
200
+ let line3 = "";
201
+ if (hasGitChanges) {
202
+ line3 += `✏️ ${C.WHITE}${gitChanges.files} files${C.RESET} ${C.GREEN}+${gitChanges.insertions}${C.RESET} ${C.RED}-${gitChanges.deletions}${C.RESET}`;
203
+ }
204
+ if (prUrl) {
205
+ const prLabel = prUrl
206
+ .replace("https://github.com/", "")
207
+ .replace("/pull/", "#");
208
+ if (line3) line3 += " | ";
209
+ // OSC 8 하이퍼링크
210
+ line3 += `📎 ${C.WHITE}${C.UNDERLINE}\x1b]8;;${prUrl}\x07${prLabel}\x1b]8;;\x07${C.RESET}`;
211
+ }
212
+ console.log(line3);
166
213
  }
167
214
  }
168
215