agenthud 0.5.15 → 0.5.17
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 +76 -4
- package/dist/index.js +28 -12
- package/dist/templates/config.yaml +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ When working with AI coding agents like Claude Code, you lose visibility into wh
|
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
15
|
-
Requires Node.js 20
|
|
15
|
+
Requires Node.js 20+. Tested on Ubuntu, Windows, macOS.
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
npx agenthud
|
|
@@ -67,16 +67,88 @@ panels:
|
|
|
67
67
|
interval: 10s
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
+
## Panels
|
|
71
|
+
|
|
72
|
+
### Claude Panel
|
|
73
|
+
|
|
74
|
+
Shows real-time Claude Code activity:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
┌─ Claude ─────────────────────────────────────────────┐
|
|
78
|
+
│ [10:23:45] ○ Read: src/components/Button.tsx │
|
|
79
|
+
│ [10:23:46] ~ Edit: src/components/Button.tsx │
|
|
80
|
+
│ [10:23:47] $ Bash: npm test │
|
|
81
|
+
│ [10:23:50] < Response: Tests passed successfully... │
|
|
82
|
+
└──────────────────────────────────────────────────────┘
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- **○ Read**: File being read
|
|
86
|
+
- **~ Edit/Write**: File being modified
|
|
87
|
+
- **$ Bash**: Command being executed
|
|
88
|
+
- **< Response**: Claude's text response
|
|
89
|
+
|
|
90
|
+
### Git Panel
|
|
91
|
+
|
|
92
|
+
Shows today's git activity and current state:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
┌─ Git ────────────────────────────────────────────────┐
|
|
96
|
+
│ feat/add-dashboard · +142 -23 · 3 commits · 5 files │
|
|
97
|
+
│ • abc1234 Add dashboard component │
|
|
98
|
+
│ • def5678 Fix styling issues │
|
|
99
|
+
└──────────────────────────────────────────────────────┘
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- **Branch name**: Current working branch (green)
|
|
103
|
+
- **Stats**: Lines added/deleted, commits, files changed
|
|
104
|
+
- **dirty**: Shows uncommitted change count (yellow)
|
|
105
|
+
|
|
106
|
+
### Tests Panel
|
|
107
|
+
|
|
108
|
+
Shows test results with staleness detection:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
┌─ Tests ──────────────────────────────────────────────┐
|
|
112
|
+
│ ✓ 42 passed ✗ 1 failed ○ 2 skipped · abc1234 │
|
|
113
|
+
│ ⚠ Outdated (3 commits behind) │
|
|
114
|
+
│──────────────────────────────────────────────────────│
|
|
115
|
+
│ ✗ Button.test.tsx │
|
|
116
|
+
│ • should render correctly │
|
|
117
|
+
└──────────────────────────────────────────────────────┘
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- **✓ passed** (green), **✗ failed** (red), **○ skipped**
|
|
121
|
+
- **⚠ Outdated**: Warning if tests are behind commits
|
|
122
|
+
- **Failures**: Shows failing test file and name
|
|
123
|
+
|
|
124
|
+
### Project Panel
|
|
125
|
+
|
|
126
|
+
Shows project overview and structure:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
┌─ Project ────────────────────────────────────────────┐
|
|
130
|
+
│ agenthud · TypeScript · MIT │
|
|
131
|
+
│ Stack: react, ink, vitest │
|
|
132
|
+
│ Files: 45 .ts · Lines: 3.2k │
|
|
133
|
+
│ Deps: 12 prod · 8 dev │
|
|
134
|
+
└──────────────────────────────────────────────────────┘
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
- **Name/Language/License**: Project basics
|
|
138
|
+
- **Stack**: Detected frameworks and tools
|
|
139
|
+
- **Files/Lines**: Source code stats
|
|
140
|
+
- **Deps**: Dependency counts
|
|
141
|
+
|
|
70
142
|
### Other Sessions Panel
|
|
71
143
|
|
|
72
144
|
Shows activity from your other Claude Code projects:
|
|
73
145
|
|
|
74
146
|
```
|
|
75
147
|
┌─ Other Sessions ─────────────────────────────────────┐
|
|
76
|
-
│ 📁 dotfiles, pain-radar, myapp +4 | ⚡ 1 active
|
|
148
|
+
│ 📁 dotfiles, pain-radar, myapp +4 | ⚡ 1 active │
|
|
77
149
|
│ │
|
|
78
|
-
│ 🔵 dotfiles (2m ago)
|
|
79
|
-
│ "Updated the config file as requested..."
|
|
150
|
+
│ 🔵 dotfiles (2m ago) │
|
|
151
|
+
│ "Updated the config file as requested..." │
|
|
80
152
|
└──────────────────────────────────────────────────────┘
|
|
81
153
|
```
|
|
82
154
|
|
package/dist/index.js
CHANGED
|
@@ -956,6 +956,11 @@ function WelcomePanel() {
|
|
|
956
956
|
import { execSync as nodeExecSync, exec as nodeExec } from "child_process";
|
|
957
957
|
import { promisify } from "util";
|
|
958
958
|
var execAsync = promisify(nodeExec);
|
|
959
|
+
function cleanOutput(str) {
|
|
960
|
+
let result = str.replace(/^\uFEFF/, "");
|
|
961
|
+
result = result.replace(/^"|"$/g, "");
|
|
962
|
+
return result.trim();
|
|
963
|
+
}
|
|
959
964
|
var execFn = (command, options2) => nodeExecSync(command, options2);
|
|
960
965
|
function getUncommittedCount() {
|
|
961
966
|
try {
|
|
@@ -1041,11 +1046,12 @@ async function getGitDataAsync(config) {
|
|
|
1041
1046
|
let commits = [];
|
|
1042
1047
|
try {
|
|
1043
1048
|
const { stdout } = await execAsync(commands.commits);
|
|
1044
|
-
const lines = stdout
|
|
1049
|
+
const lines = cleanOutput(stdout).split("\n").filter(Boolean);
|
|
1045
1050
|
commits = lines.map((line) => {
|
|
1046
|
-
const
|
|
1051
|
+
const cleanLine = cleanOutput(line);
|
|
1052
|
+
const [hash, timestamp, ...messageParts] = cleanLine.split("|");
|
|
1047
1053
|
return {
|
|
1048
|
-
hash,
|
|
1054
|
+
hash: cleanOutput(hash),
|
|
1049
1055
|
message: messageParts.join("|"),
|
|
1050
1056
|
timestamp: new Date(timestamp)
|
|
1051
1057
|
};
|
|
@@ -1905,10 +1911,11 @@ function getOtherSessionsData(currentProjectPath, options2 = {}) {
|
|
|
1905
1911
|
}
|
|
1906
1912
|
const allProjects = getAllProjects();
|
|
1907
1913
|
defaultResult.totalProjects = allProjects.length;
|
|
1908
|
-
const normalizedCurrentPath = currentProjectPath.replace(
|
|
1914
|
+
const normalizedCurrentPath = currentProjectPath.replace(/[/\\]$/, "").replace(/\\/g, "/");
|
|
1909
1915
|
const otherSessions = [];
|
|
1910
1916
|
for (const project of allProjects) {
|
|
1911
|
-
|
|
1917
|
+
const normalizedDecodedPath = project.decodedPath.replace(/\\/g, "/");
|
|
1918
|
+
if (normalizedDecodedPath === normalizedCurrentPath) {
|
|
1912
1919
|
continue;
|
|
1913
1920
|
}
|
|
1914
1921
|
const projectDir = join3(projectsDir, project.encodedPath);
|
|
@@ -2509,22 +2516,31 @@ function DashboardApp({ mode }) {
|
|
|
2509
2516
|
const { exit } = useApp();
|
|
2510
2517
|
const { stdout } = useStdout();
|
|
2511
2518
|
const { config, warnings } = useMemo(() => parseConfig(), []);
|
|
2512
|
-
const
|
|
2519
|
+
const getEffectiveWidth = (terminalColumns) => {
|
|
2520
|
+
if (config.width) {
|
|
2521
|
+
return config.width;
|
|
2522
|
+
}
|
|
2523
|
+
return getClampedWidth(terminalColumns);
|
|
2524
|
+
};
|
|
2525
|
+
const [width, setWidth] = useState(() => getEffectiveWidth(stdout?.columns));
|
|
2513
2526
|
useEffect(() => {
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2527
|
+
if (!config.width) {
|
|
2528
|
+
const newWidth = getEffectiveWidth(stdout?.columns);
|
|
2529
|
+
if (newWidth !== width) {
|
|
2530
|
+
setWidth(newWidth);
|
|
2531
|
+
}
|
|
2517
2532
|
}
|
|
2518
|
-
}, [stdout?.columns, width]);
|
|
2533
|
+
}, [stdout?.columns, width, config.width]);
|
|
2519
2534
|
useEffect(() => {
|
|
2535
|
+
if (config.width) return;
|
|
2520
2536
|
const handleResize = () => {
|
|
2521
|
-
setWidth(
|
|
2537
|
+
setWidth(getEffectiveWidth(stdout?.columns));
|
|
2522
2538
|
};
|
|
2523
2539
|
stdout?.on("resize", handleResize);
|
|
2524
2540
|
return () => {
|
|
2525
2541
|
stdout?.off("resize", handleResize);
|
|
2526
2542
|
};
|
|
2527
|
-
}, [stdout]);
|
|
2543
|
+
}, [stdout, config.width]);
|
|
2528
2544
|
const projectIntervalSeconds = config.panels.project.interval ? config.panels.project.interval / 1e3 : null;
|
|
2529
2545
|
const gitIntervalSeconds = config.panels.git.interval ? config.panels.git.interval / 1e3 : null;
|
|
2530
2546
|
const claudeIntervalSeconds = config.panels.claude.interval ? config.panels.claude.interval / 1e3 : null;
|
package/package.json
CHANGED