claude-code-hud 0.3.11 → 0.3.12
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/package.json +1 -1
- package/scripts/lib/git-info.mjs +18 -15
- package/tui/hud.tsx +4 -2
package/package.json
CHANGED
package/scripts/lib/git-info.mjs
CHANGED
|
@@ -1,39 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Git status via child_process
|
|
2
|
+
* Git status via child_process exec (async — non-blocking).
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { exec } from 'child_process';
|
|
5
|
+
import { promisify } from 'util';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
const execAsync = promisify(exec);
|
|
8
|
+
|
|
9
|
+
async function run(cmd, cwd) {
|
|
7
10
|
try {
|
|
8
|
-
|
|
11
|
+
const { stdout } = await execAsync(cmd, { cwd, timeout: 3000 });
|
|
12
|
+
return stdout.trim();
|
|
9
13
|
} catch {
|
|
10
14
|
return '';
|
|
11
15
|
}
|
|
12
16
|
}
|
|
13
17
|
|
|
14
|
-
export function readGitInfo(cwd = process.cwd()) {
|
|
15
|
-
const branch = run('git rev-parse --abbrev-ref HEAD', cwd) || 'unknown';
|
|
18
|
+
export async function readGitInfo(cwd = process.cwd()) {
|
|
19
|
+
const branch = await run('git rev-parse --abbrev-ref HEAD', cwd) || 'unknown';
|
|
16
20
|
if (branch === 'unknown' || branch === 'HEAD') {
|
|
17
21
|
return { isRepo: false, branch: 'unknown', ahead: 0, behind: 0, modified: [], added: [], deleted: [], recentCommits: [], totalChanges: 0 };
|
|
18
22
|
}
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
const [aheadBehind, statusOut, logOut, numstatOut] = await Promise.all([
|
|
25
|
+
run('git rev-list --left-right --count @{upstream}...HEAD 2>/dev/null || echo "0\t0"', cwd),
|
|
26
|
+
run('git status --porcelain', cwd),
|
|
27
|
+
run('git log --oneline -5 --format="%h|%s|%cr"', cwd),
|
|
28
|
+
run('git diff --numstat HEAD 2>/dev/null', cwd),
|
|
29
|
+
]);
|
|
30
|
+
|
|
22
31
|
const [behind = 0, ahead = 0] = aheadBehind.split('\t').map(Number);
|
|
23
32
|
|
|
24
|
-
// status
|
|
25
|
-
const statusOut = run('git status --porcelain', cwd);
|
|
26
33
|
const modified = [], added = [], deleted = [];
|
|
27
34
|
for (const line of statusOut.split('\n').filter(Boolean)) {
|
|
28
35
|
const st = line.slice(0, 2).trim();
|
|
29
36
|
const file = line.slice(2).trimStart();
|
|
30
37
|
if (st === 'M' || st === 'MM' || st === 'AM') modified.push(file);
|
|
31
|
-
else if (st === 'A' || st === '??'
|
|
38
|
+
else if (st === 'A' || st === '??') added.push(file);
|
|
32
39
|
else if (st === 'D') deleted.push(file);
|
|
33
40
|
}
|
|
34
41
|
|
|
35
|
-
// recent commits
|
|
36
|
-
const logOut = run('git log --oneline -5 --format="%h|%s|%cr"', cwd);
|
|
37
42
|
const recentCommits = logOut.split('\n').filter(Boolean).map(l => {
|
|
38
43
|
const [hash, ...rest] = l.split('|');
|
|
39
44
|
const time = rest.pop();
|
|
@@ -41,8 +46,6 @@ export function readGitInfo(cwd = process.cwd()) {
|
|
|
41
46
|
return { hash, msg, time };
|
|
42
47
|
});
|
|
43
48
|
|
|
44
|
-
// diff stats: actual +/- line counts per file
|
|
45
|
-
const numstatOut = run('git diff --numstat HEAD 2>/dev/null', cwd);
|
|
46
49
|
const diffStats = {};
|
|
47
50
|
for (const line of numstatOut.split('\n').filter(Boolean)) {
|
|
48
51
|
const [addStr, delStr, ...fileParts] = line.split('\t');
|
package/tui/hud.tsx
CHANGED
|
@@ -753,7 +753,7 @@ function App() {
|
|
|
753
753
|
|
|
754
754
|
const [usage, setUsage] = useState<any>(readTokenUsage(cwd));
|
|
755
755
|
const [history, setHistory] = useState<any>(readTokenHistory(cwd));
|
|
756
|
-
const [git, setGit] = useState<any>(
|
|
756
|
+
const [git, setGit] = useState<any>({ isRepo: false, branch: 'loading…', modified: [], added: [], deleted: [], recentCommits: [], totalChanges: 0 });
|
|
757
757
|
const [project, setProject] = useState<ProjectInfo | null>(null);
|
|
758
758
|
const [rateLimits, setRateLimits] = useState<any>(getUsageSync());
|
|
759
759
|
|
|
@@ -793,8 +793,8 @@ function App() {
|
|
|
793
793
|
const refresh = useCallback(() => {
|
|
794
794
|
setUsage(readTokenUsage(cwd));
|
|
795
795
|
setHistory(readTokenHistory(cwd));
|
|
796
|
-
setGit(readGitInfo(cwd));
|
|
797
796
|
setUpdatedAt(Date.now());
|
|
797
|
+
readGitInfo(cwd).then(setGit).catch(() => {});
|
|
798
798
|
getUsage().then(setRateLimits).catch(() => {});
|
|
799
799
|
readSessionTimeline(cwd).then(entries => {
|
|
800
800
|
setTimeline(entries);
|
|
@@ -812,6 +812,8 @@ function App() {
|
|
|
812
812
|
.catch(() => { setLoading(false); });
|
|
813
813
|
// Full deep scan in background → update silently
|
|
814
814
|
scanProject(cwd, 8).then(p => { setProject(p); }).catch(() => {});
|
|
815
|
+
// Initial git load (async)
|
|
816
|
+
readGitInfo(cwd).then(setGit).catch(() => {});
|
|
815
817
|
// Initial API usage fetch
|
|
816
818
|
getUsage().then(setRateLimits).catch(() => {});
|
|
817
819
|
// Initial timeline load
|