agenthud 0.13.0 → 0.13.2
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 +32 -252
- package/dist/index.js +1 -1
- package/dist/{main-UBXFOCNF.js → main-GMNV6O4E.js} +85 -8
- package/dist/templates/summary-prompt.md +33 -14
- package/package.json +26 -7
package/README.md
CHANGED
|
@@ -10,9 +10,11 @@ An observability layer for [Claude Code](https://github.com/anthropics/claude-co
|
|
|
10
10
|
|
|
11
11
|
AgentHUD reads Claude Code's session files from `~/.claude/projects/` and gives you three things:
|
|
12
12
|
|
|
13
|
-
- **Live monitor** (
|
|
14
|
-
- **Structured export** (
|
|
15
|
-
- **LLM digest** (
|
|
13
|
+
- **Live monitor** (`agenthud`) — a split-view TUI showing every project, session, sub-agent, and activity as it happens
|
|
14
|
+
- **Structured export** (`agenthud report`) — Markdown or JSON for piping to scripts, dashboards, or other LLMs
|
|
15
|
+
- **LLM digest** (`agenthud summary`) — a day or a date range synthesized into an engineering summary via the `claude` CLI
|
|
16
|
+
|
|
17
|
+
→ **See [FEATURES.md](./FEATURES.md) for the full surface** — every flag, keybinding, config key, file path, and env var.
|
|
16
18
|
|
|
17
19
|
## Install
|
|
18
20
|
|
|
@@ -26,17 +28,28 @@ Run this in a separate terminal while using Claude Code. Press `?` inside the TU
|
|
|
26
28
|
|
|
27
29
|
> **Platform support.** Primary development is on macOS and Linux; the full test suite runs on all three platforms in CI (including Windows). Windows runtime behavior is exercised by a manual smoke job but isn't daily-driven — issues there are valued bug reports.
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
## Quickstart
|
|
30
32
|
|
|
31
33
|
```bash
|
|
32
|
-
|
|
33
|
-
agenthud
|
|
34
|
-
agenthud --
|
|
34
|
+
# Live monitor
|
|
35
|
+
agenthud # all Claude projects
|
|
36
|
+
agenthud --cwd # scope to the project containing $PWD
|
|
37
|
+
agenthud --once # snapshot mode, no alt-screen
|
|
38
|
+
|
|
39
|
+
# Activity report
|
|
40
|
+
agenthud report --date today # today's activity as markdown
|
|
41
|
+
agenthud report --format json # script-readable
|
|
42
|
+
agenthud report --with-git # merge git commits into the timeline
|
|
43
|
+
|
|
44
|
+
# LLM summary
|
|
45
|
+
agenthud summary --date today # daily summary via `claude -p`
|
|
46
|
+
agenthud summary --last 7d # cross-day synthesis of last 7 days
|
|
47
|
+
agenthud summary -oI # open the summary + the summaries index
|
|
35
48
|
```
|
|
36
49
|
|
|
37
|
-
##
|
|
50
|
+
## What you see
|
|
38
51
|
|
|
39
|
-
|
|
52
|
+
The TUI splits into a project tree (top) and an activity viewer (bottom):
|
|
40
53
|
|
|
41
54
|
```
|
|
42
55
|
┌─ Projects ─────────────────────────────────────────────────┐
|
|
@@ -57,257 +70,24 @@ AgentHUD's TUI splits the screen into a project tree and an activity viewer:
|
|
|
57
70
|
└────────────────────────────────────────────────────────────┘
|
|
58
71
|
```
|
|
59
72
|
|
|
60
|
-
|
|
61
|
-
- Sessions grouped under their project (project name + path at the top).
|
|
62
|
-
- Session rows show short ID + first user prompt (the session's "topic"). Long titles truncate with a `…` suffix.
|
|
63
|
-
- Right edge of each row shows how long ago it was last touched: `42m`, `17h`, `3d`, `2w`, `1mo`, `1y`. Project rows use the most recent session's mtime.
|
|
64
|
-
- Non-interactive sessions (from `claude -p`, SDK, `agenthud summary`) appear in parens and dimmed.
|
|
65
|
-
- Sub-agents nest one level deeper under their parent session.
|
|
66
|
-
- Cold projects collapse under `... N cold projects` at the bottom (press Enter on the line to expand).
|
|
67
|
-
- Press `h` to hide a project, session, or sub-agent (saved to `~/.agenthud/state.yaml`).
|
|
68
|
-
|
|
69
|
-
**Activity viewer (bottom pane)**
|
|
70
|
-
- Real-time feed for the selected session: file reads, edits, bash, responses, thinking, git commits. Newest at the bottom, like `tail -f`.
|
|
71
|
-
- The **newest visible row is rendered "alive"** while in LIVE mode: its icon is replaced with a spinning glyph and the text turns bold. When a new activity arrives, the spinner moves to the new bottom row. Hidden when paused or empty.
|
|
72
|
-
- Press `f` to cycle through filter presets (configurable).
|
|
73
|
-
- Press `↵` on any row to open a scrollable detail view; on a commit row this shows `git show --stat --patch`.
|
|
74
|
-
|
|
75
|
-
### Session status
|
|
76
|
-
|
|
77
|
-
Each session row carries a colored badge derived from when its JSONL file was last touched:
|
|
78
|
-
|
|
79
|
-
| Badge | Color | Meaning |
|
|
80
|
-
|-------|-------|---------|
|
|
81
|
-
| `[hot]` | green | Updated in the last 30 minutes — actively running |
|
|
82
|
-
| `[warm]` | yellow | Updated in the last hour |
|
|
83
|
-
| `[cool]` | cyan | Updated earlier today |
|
|
84
|
-
| `[cold]` | gray | Last updated yesterday or earlier — collapsed under `... N cold projects` at the bottom |
|
|
85
|
-
|
|
86
|
-
Sub-agents use the same scheme. Projects inherit the hottest status of their sessions; a project is treated as "cold" only when all its sessions are cold.
|
|
87
|
-
|
|
88
|
-
### Activity types
|
|
89
|
-
|
|
90
|
-
| Icon | Type | Description |
|
|
91
|
-
|------|------|-------------|
|
|
92
|
-
| `○` | Read | File being read |
|
|
93
|
-
| `~` | Edit / Write | File being modified |
|
|
94
|
-
| `$` | Bash | Shell command |
|
|
95
|
-
| `*` | Glob / Grep | File search |
|
|
96
|
-
| `@` | WebFetch / WebSearch | Web request |
|
|
97
|
-
| `»` | Task | Sub-agent task |
|
|
98
|
-
| `<` | Response | Claude's text response |
|
|
99
|
-
| `>` | User | Your message |
|
|
100
|
-
| `…` | Thinking | Claude's thinking (requires `showThinkingSummaries: true`) |
|
|
101
|
-
| `◆` | Commit | Git commit in the project (when `--with-git` or in viewer) |
|
|
102
|
-
|
|
103
|
-
### Keyboard shortcuts
|
|
104
|
-
|
|
105
|
-
Full reference is also available inside the app — press `?`.
|
|
106
|
-
|
|
107
|
-
#### Project tree focus
|
|
108
|
-
|
|
109
|
-
| Key | Action |
|
|
110
|
-
|-----|--------|
|
|
111
|
-
| `↑` / `k` | Move up |
|
|
112
|
-
| `↓` / `j` | Move down |
|
|
113
|
-
| `←` | Jump to parent (sub-agent → session, session → project) |
|
|
114
|
-
| `↵` | Expand/collapse project, session, or sub-agent summary |
|
|
115
|
-
| `h` | Hide selected (project / session / sub-agent) |
|
|
116
|
-
| `Tab` | Switch focus to activity viewer |
|
|
117
|
-
| `PgUp` / `Ctrl+B` | Page up |
|
|
118
|
-
| `PgDn` / `Ctrl+F` | Page down |
|
|
119
|
-
| `t` | Track — auto-follow the newest live sub-agent (any nav key turns it off) |
|
|
120
|
-
| `r` | Refresh now |
|
|
121
|
-
| `?` | Help |
|
|
122
|
-
| `q` | Quit |
|
|
123
|
-
|
|
124
|
-
When tracking is on, the tree panel's title shows `[LIVE ⠧]` and the status bar replaces `t: track` with `TRK ●`. Any explicit selection-changing key (`↑/k`, `↓/j`, `PgUp/PgDn`, `↵`, `h`, or `t` again) turns tracking off.
|
|
125
|
-
|
|
126
|
-
#### Activity viewer focus
|
|
127
|
-
|
|
128
|
-
| Key | Action |
|
|
129
|
-
|-----|--------|
|
|
130
|
-
| `↑` / `k` | Scroll one line up |
|
|
131
|
-
| `↓` / `j` | Scroll one line down |
|
|
132
|
-
| `PgUp` / `Ctrl+B` | Page up |
|
|
133
|
-
| `PgDn` / `Ctrl+F` | Page down |
|
|
134
|
-
| `Ctrl+U` / `Ctrl+D` | Half page up / down |
|
|
135
|
-
| `g` | Jump to top (oldest) |
|
|
136
|
-
| `G` | Jump to live (newest, bottom) |
|
|
137
|
-
| `↵` | Open detail view |
|
|
138
|
-
| `f` | Cycle filter preset |
|
|
139
|
-
| `r` | Refresh now |
|
|
140
|
-
| `Tab` | Switch focus to project tree |
|
|
141
|
-
| `?` | Help |
|
|
142
|
-
| `q` | Quit |
|
|
143
|
-
|
|
144
|
-
#### Detail view
|
|
145
|
-
|
|
146
|
-
| Key | Action |
|
|
147
|
-
|-----|--------|
|
|
148
|
-
| `↑` / `k` / `↓` / `j` | Scroll one line |
|
|
149
|
-
| `Ctrl+U` / `Ctrl+D` | Half page up / down |
|
|
150
|
-
| `↵` / `Esc` / `q` | Close |
|
|
151
|
-
|
|
152
|
-
Detail view colors the content based on activity type:
|
|
153
|
-
|
|
154
|
-
- **Git commit detail** (`git show --stat --patch`): added lines green (`+`), removed lines red (`-`), hunk headers cyan (`@@ ... @@`), `commit/Author/Date/diff` metadata dimmed.
|
|
155
|
-
- **Response / thinking / prompt**: text inside triple-backtick code fences renders in cyan so the boundary between prose and code is obvious. No language-specific syntax highlighting — just code-vs-prose separation.
|
|
156
|
-
|
|
157
|
-
### Behavior
|
|
158
|
-
|
|
159
|
-
- **Alternate screen buffer.** Watch mode uses the alt-screen (like `vim`, `htop`, `btop`), so quitting (`q`) restores the pre-launch shell completely. No TUI residue, no "is it still running?" confusion.
|
|
160
|
-
- **Minimum terminal size.** 80 cols × 20 rows. Smaller terminals show a one-line hint and redraw automatically when you resize.
|
|
161
|
-
- **Help overlay scrolls.** Press `?` for an in-app reference. The overlay scrolls (`j/k`, `PgUp/PgDn`, `Ctrl+B/F`, `Space`, `g/G`) so the full content is reachable on shorter terminals.
|
|
162
|
-
|
|
163
|
-
## Report
|
|
164
|
-
|
|
165
|
-
Print activity for a date in Markdown or JSON — suitable for piping to scripts or LLMs:
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
agenthud report # today (Markdown)
|
|
169
|
-
agenthud report --date 2026-05-14 # specific date
|
|
170
|
-
agenthud report --date today --include all # all activity types
|
|
171
|
-
agenthud report --format json # JSON output
|
|
172
|
-
agenthud report --detail-limit 0 # no truncation (full text)
|
|
173
|
-
agenthud report --with-git # merge git commits into timeline
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
Output:
|
|
177
|
-
|
|
178
|
-
```
|
|
179
|
-
# AgentHUD Report: 2026-05-14
|
|
180
|
-
|
|
181
|
-
## myproject (10:23 – 14:45)
|
|
182
|
-
|
|
183
|
-
[10:23] $ npm test
|
|
184
|
-
[10:35] ~ src/ui/App.tsx
|
|
185
|
-
[11:15] < Added spinner hook to make the UI feel alive.
|
|
186
|
-
[14:30] ◆ abc1234 feat: fix auth callback
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**Options:**
|
|
190
|
-
|
|
191
|
-
| Flag | Default | Description |
|
|
192
|
-
|------|---------|-------------|
|
|
193
|
-
| `--date` | today | `YYYY-MM-DD`, `today`, `yesterday`, or `-Nd` (N days ago, local date) |
|
|
194
|
-
| `--include` | `user,response,bash,edit,thinking,task` | Comma-separated types or `all` |
|
|
195
|
-
| `--format` | `markdown` | `markdown` or `json` |
|
|
196
|
-
| `--detail-limit` | `120` | Max chars per detail field; `0` = unlimited |
|
|
197
|
-
| `--with-git` | off | Merge git commits from each session's project into the timeline |
|
|
198
|
-
|
|
199
|
-
`--include` types: `response`, `bash`, `edit`, `thinking`, `read`, `glob`, `user`, `task` (Task tool delegations to subagents — surfaces the subagent's returned text so the LLM summary can see what the subagent actually did)
|
|
200
|
-
|
|
201
|
-
## Summary
|
|
202
|
-
|
|
203
|
-
Generate an LLM-based summary of one day or a date range using the `claude` CLI:
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
# Single day
|
|
207
|
-
agenthud summary # today (always regenerated)
|
|
208
|
-
agenthud summary --date yesterday # natural-language date
|
|
209
|
-
agenthud summary --date 2026-05-14 # past date (cached on second run)
|
|
210
|
-
agenthud summary --date 2026-05-14 --force # ignore cache
|
|
211
|
-
agenthud summary --prompt "Only commits" # override prompt
|
|
212
|
-
|
|
213
|
-
# Date range — daily summaries are re-summarized into a meta-summary
|
|
214
|
-
agenthud summary --last 7d # last 7 days, ending today
|
|
215
|
-
agenthud summary --from 2026-05-10 --to 2026-05-16 # explicit range
|
|
216
|
-
agenthud summary --last 7d -y # skip per-day confirmations
|
|
217
|
-
|
|
218
|
-
# Tune what gets sent to the LLM — same option shape as `report`
|
|
219
|
-
agenthud summary --include all # include every activity type
|
|
220
|
-
agenthud summary --detail-limit 200 # truncate long tool outputs
|
|
221
|
-
agenthud summary --with-git # include git commits (default in config)
|
|
222
|
-
# Defaults are CLI flag → `summary:` config → `report:` config → built-in.
|
|
223
|
-
|
|
224
|
-
# Cheaper model — summarization doesn't need Opus-tier reasoning
|
|
225
|
-
agenthud summary --date today --model sonnet # ~40% cheaper than Opus
|
|
226
|
-
agenthud summary --last 7d --model haiku # ~80% cheaper, 200K context
|
|
227
|
-
|
|
228
|
-
# Open the resulting summary in your OS default app (browser, VS Code, etc.)
|
|
229
|
-
agenthud summary --last 7d --open # -o is the short form
|
|
230
|
-
|
|
231
|
-
# Open the index (~/.agenthud/summaries/index.md) instead — a hub
|
|
232
|
-
# listing every daily and range summary, grouped by year/month.
|
|
233
|
-
agenthud summary --open-index # -I is the short form
|
|
234
|
-
agenthud summary -oI # open today + the index
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
The index is auto-regenerated whenever a summary writes, and each summary file gets a one-line backlink footer at the top (`← all summaries · ← prev · next →`) so any markdown viewer is enough to navigate the whole corpus without leaving the file.
|
|
238
|
-
|
|
239
|
-
**Daily summaries** are saved to `~/.agenthud/summaries/YYYY-MM-DD.md`. Past dates are cached and returned instantly; today is always regenerated (activity still growing).
|
|
73
|
+
Sessions get colored badges — `[hot]` / `[warm]` / `[cool]` / `[cold]` — based on how recently their JSONL file was touched. Cold projects collapse under a `... N cold projects` sentinel. Press `↵` on any activity to open a scrollable detail view.
|
|
240
74
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
Each missing daily prompts for confirmation just before generation, so you see concrete context (session/activity/commit counts and report size) before deciding. Pass `-y` / `--yes` to skip all prompts. Press Enter to accept the default (`[Y/n]`).
|
|
244
|
-
|
|
245
|
-
**Prompt customization:** The daily template lives at `~/.agenthud/summary-prompt.md` and the range template at `~/.agenthud/summary-range-prompt.md`. Both are auto-created from built-in templates on first run. Edit them freely.
|
|
246
|
-
|
|
247
|
-
**`--date` formats:** `YYYY-MM-DD`, `today`, `yesterday`, or `-Nd` (N days ago).
|
|
248
|
-
|
|
249
|
-
**Model selection:** Summarization is a low-reasoning task (structured input → structured markdown) — Sonnet or Haiku usually beats Opus on cost-per-summary with no quality loss. Pass `--model sonnet`, `--model haiku`, or a full model id (`--model claude-sonnet-4-6`). With no flag, `claude` uses its default model.
|
|
250
|
-
|
|
251
|
-
**Cost warning:** If the day's activity log is large (~300K tokens or more), AgentHUD prints a warning before sending and asks for one more confirmation in interactive mode. `-y` skips the prompt but still prints the warning.
|
|
252
|
-
|
|
253
|
-
**Requires:** [`@anthropic-ai/claude-code`](https://www.npmjs.com/package/@anthropic-ai/claude-code) installed and authenticated.
|
|
75
|
+
Full keybinding and badge reference: [FEATURES.md](./FEATURES.md#keybindings).
|
|
254
76
|
|
|
255
77
|
## Configuration
|
|
256
78
|
|
|
257
|
-
`~/.agenthud/config.yaml` is auto-created on first run with sensible defaults.
|
|
258
|
-
|
|
259
|
-
```yaml
|
|
260
|
-
# How often to poll for activity updates (Linux fallback when fs.watch isn't used)
|
|
261
|
-
refreshInterval: 2s
|
|
262
|
-
|
|
263
|
-
# Activity filter presets (cycle with 'f' key in viewer)
|
|
264
|
-
# Each list is one preset. Use "all" (or "*") to show everything.
|
|
265
|
-
# Types: response, user, bash, edit, thinking, read, glob, commit, task
|
|
266
|
-
filterPresets:
|
|
267
|
-
- ["all"]
|
|
268
|
-
- ["response", "user"]
|
|
269
|
-
- ["commit"]
|
|
270
|
-
|
|
271
|
-
# Defaults for `agenthud report` (CLI flags still win per-invocation).
|
|
272
|
-
report:
|
|
273
|
-
include: [user, response, bash, edit, thinking, task]
|
|
274
|
-
detailLimit: 120
|
|
275
|
-
withGit: false
|
|
276
|
-
format: markdown
|
|
277
|
-
|
|
278
|
-
# Defaults for `agenthud summary`. Any field omitted here is inherited
|
|
279
|
-
# from `report` above. `model` is summary-specific.
|
|
280
|
-
summary:
|
|
281
|
-
withGit: true
|
|
282
|
-
detailLimit: 0
|
|
283
|
-
# model: sonnet
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
`report` / `summary` resolve each option as **CLI flag → `summary:` key → `report:` key → built-in default**. The effective set is printed to stderr at the start of each run (e.g. `agenthud: report → include=[user,response,bash,edit,thinking] detail-limit=120 with-git=off format=markdown`), so the actual values are always visible.
|
|
287
|
-
|
|
288
|
-
App-managed state (hidden items) lives separately in `~/.agenthud/state.yaml` so your config file stays clean. You shouldn't need to edit it manually — use `h` in the TUI to hide things.
|
|
289
|
-
|
|
290
|
-
## Files
|
|
291
|
-
|
|
292
|
-
| Path | Purpose |
|
|
293
|
-
|------|---------|
|
|
294
|
-
| `~/.agenthud/config.yaml` | User settings (edit freely) |
|
|
295
|
-
| `~/.agenthud/state.yaml` | Hidden projects/sessions/sub-agents (app-managed) |
|
|
296
|
-
| `~/.agenthud/summary-prompt.md` | LLM prompt template for daily `summary` |
|
|
297
|
-
| `~/.agenthud/summary-range-prompt.md` | LLM prompt template for range `summary --last/--from/--to` |
|
|
298
|
-
| `~/.agenthud/summaries/YYYY-MM-DD.md` | Cached daily summaries |
|
|
299
|
-
| `~/.agenthud/summaries/range-FROM_TO.md` | Cached range summaries |
|
|
300
|
-
| `~/.agenthud/summaries/index.md` | Auto-regenerated hub linking every summary; each summary also gets a backlink footer at the top |
|
|
79
|
+
`~/.agenthud/config.yaml` is auto-created on first run with sensible defaults. CLI flags override config values per-invocation. Resolution order is `CLI flag → summary.<key> → report.<key> → built-in default`, and the effective values print to stderr at the start of every `report` / `summary` run.
|
|
301
80
|
|
|
302
|
-
|
|
81
|
+
App-managed UI state (hidden projects/sessions/sub-agents toggled by `h`) lives separately in `~/.agenthud/state.yaml`.
|
|
303
82
|
|
|
304
|
-
|
|
305
|
-
|----------|---------|-------------|
|
|
306
|
-
| `CLAUDE_PROJECTS_DIR` | `~/.claude/projects` | Path to Claude Code projects directory. Useful for backups or mounted volumes. |
|
|
83
|
+
Full schema, file paths, and env vars: [FEATURES.md → Config](./FEATURES.md#config).
|
|
307
84
|
|
|
308
|
-
##
|
|
85
|
+
## More
|
|
309
86
|
|
|
310
|
-
|
|
87
|
+
- **Reference:** [FEATURES.md](./FEATURES.md) — every flag, keybinding, config key, file path, env var
|
|
88
|
+
- **Release history:** [CHANGELOG.md](./CHANGELOG.md)
|
|
89
|
+
- **Deferred items:** [BACKLOG.md](./BACKLOG.md)
|
|
90
|
+
- **Issues / PRs:** [GitHub](https://github.com/neochoon/agenthud)
|
|
311
91
|
|
|
312
92
|
## License
|
|
313
93
|
|
package/dist/index.js
CHANGED
|
@@ -946,6 +946,17 @@ function numberLines(content, start) {
|
|
|
946
946
|
const width = String(start + lines.length - 1).length;
|
|
947
947
|
return lines.map((line, i) => `${String(start + i).padStart(width)}: ${line}`).join("\n");
|
|
948
948
|
}
|
|
949
|
+
function formatBashBody(stdout, stderr, interrupted) {
|
|
950
|
+
const out = stdout?.replace(/\n+$/, "");
|
|
951
|
+
const err = stderr?.replace(/\n+$/, "");
|
|
952
|
+
const sections = [];
|
|
953
|
+
if (out) sections.push(out);
|
|
954
|
+
if (err) sections.push(out ? `--- stderr ---
|
|
955
|
+
${err}` : err);
|
|
956
|
+
if (interrupted) sections.push("[interrupted]");
|
|
957
|
+
if (sections.length === 0) return null;
|
|
958
|
+
return sections.join("\n\n");
|
|
959
|
+
}
|
|
949
960
|
function buildToolDetailBody(name, input, result) {
|
|
950
961
|
if (name === "Write") {
|
|
951
962
|
const content = result?.content ?? input?.content;
|
|
@@ -955,6 +966,14 @@ function buildToolDetailBody(name, input, result) {
|
|
|
955
966
|
const content = result?.content;
|
|
956
967
|
if (content) return { text: content, kind: "code" };
|
|
957
968
|
}
|
|
969
|
+
if (name === "Bash") {
|
|
970
|
+
const text = formatBashBody(
|
|
971
|
+
result?.stdout,
|
|
972
|
+
result?.stderr,
|
|
973
|
+
result?.interrupted
|
|
974
|
+
);
|
|
975
|
+
if (text) return { text, kind: "code" };
|
|
976
|
+
}
|
|
958
977
|
if (name === "Read") {
|
|
959
978
|
const content = result?.file?.content;
|
|
960
979
|
if (content) {
|
|
@@ -3847,6 +3866,41 @@ function SessionTreePanel({
|
|
|
3847
3866
|
] });
|
|
3848
3867
|
}
|
|
3849
3868
|
|
|
3869
|
+
// src/ui/viewerCursor.ts
|
|
3870
|
+
function adjustViewerCursorOnNewActivities(args) {
|
|
3871
|
+
const {
|
|
3872
|
+
prevCursorLine,
|
|
3873
|
+
prevActivityCount,
|
|
3874
|
+
newActivityCount,
|
|
3875
|
+
isLive,
|
|
3876
|
+
viewerRows
|
|
3877
|
+
} = args;
|
|
3878
|
+
const noOp = {
|
|
3879
|
+
cursorLine: prevCursorLine,
|
|
3880
|
+
autoPause: false,
|
|
3881
|
+
scrollDelta: 0
|
|
3882
|
+
};
|
|
3883
|
+
if (!isLive) return noOp;
|
|
3884
|
+
if (prevCursorLine === 0)
|
|
3885
|
+
return { cursorLine: 0, autoPause: false, scrollDelta: 0 };
|
|
3886
|
+
if (newActivityCount <= prevActivityCount) return noOp;
|
|
3887
|
+
const delta = newActivityCount - prevActivityCount;
|
|
3888
|
+
const maxCursor = Math.max(0, viewerRows - 1);
|
|
3889
|
+
const upwardRoom = maxCursor - prevCursorLine;
|
|
3890
|
+
if (delta <= upwardRoom) {
|
|
3891
|
+
return {
|
|
3892
|
+
cursorLine: prevCursorLine + delta,
|
|
3893
|
+
autoPause: false,
|
|
3894
|
+
scrollDelta: 0
|
|
3895
|
+
};
|
|
3896
|
+
}
|
|
3897
|
+
return {
|
|
3898
|
+
cursorLine: maxCursor,
|
|
3899
|
+
autoPause: true,
|
|
3900
|
+
scrollDelta: delta - upwardRoom
|
|
3901
|
+
};
|
|
3902
|
+
}
|
|
3903
|
+
|
|
3850
3904
|
// src/ui/App.tsx
|
|
3851
3905
|
import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3852
3906
|
var VIEWER_HEIGHT_FRACTION = 0.55;
|
|
@@ -4081,12 +4135,12 @@ function App({
|
|
|
4081
4135
|
useEffect3(() => {
|
|
4082
4136
|
allFlatRef.current = allFlat;
|
|
4083
4137
|
}, [allFlat]);
|
|
4084
|
-
const activitiesLengthRef = useRef(0);
|
|
4085
4138
|
const activitiesRef = useRef(activities);
|
|
4086
4139
|
useEffect3(() => {
|
|
4087
|
-
activitiesLengthRef.current = activities.length;
|
|
4088
4140
|
activitiesRef.current = activities;
|
|
4089
4141
|
}, [activities]);
|
|
4142
|
+
const prevMergedCountRef = useRef(0);
|
|
4143
|
+
const prevPausedCountRef = useRef(0);
|
|
4090
4144
|
const lastLoadedFileRef = useRef(null);
|
|
4091
4145
|
useEffect3(() => {
|
|
4092
4146
|
let node = allFlatRef.current.find((s) => s.id === selectedId);
|
|
@@ -4181,13 +4235,8 @@ function App({
|
|
|
4181
4235
|
setSessionTree(tree);
|
|
4182
4236
|
if (!node || !node.filePath) return;
|
|
4183
4237
|
const newActivities = parseSessionHistory(node.filePath);
|
|
4184
|
-
const delta = newActivities.length - activitiesLengthRef.current;
|
|
4185
4238
|
setActivities(newActivities);
|
|
4186
|
-
|
|
4187
|
-
setScrollOffset((o) => o + delta);
|
|
4188
|
-
setNewCount((n) => n + delta);
|
|
4189
|
-
}
|
|
4190
|
-
}, [selectedId, isLive, expandedIds, tracking, discoverOptions]);
|
|
4239
|
+
}, [selectedId, expandedIds, tracking, discoverOptions]);
|
|
4191
4240
|
const refreshRef = useRef(refresh);
|
|
4192
4241
|
useEffect3(() => {
|
|
4193
4242
|
refreshRef.current = refresh;
|
|
@@ -4252,6 +4301,34 @@ function App({
|
|
|
4252
4301
|
const naturalTreeRows = allFlat.length;
|
|
4253
4302
|
const treeRows = Math.max(1, Math.min(naturalTreeRows, maxTreeRows));
|
|
4254
4303
|
const viewerRows = Math.max(5, height - 7 - treeRows);
|
|
4304
|
+
useEffect3(() => {
|
|
4305
|
+
const prev = prevMergedCountRef.current;
|
|
4306
|
+
prevMergedCountRef.current = mergedActivities.length;
|
|
4307
|
+
const result = adjustViewerCursorOnNewActivities({
|
|
4308
|
+
prevCursorLine: viewerCursorLine,
|
|
4309
|
+
prevActivityCount: prev,
|
|
4310
|
+
newActivityCount: mergedActivities.length,
|
|
4311
|
+
isLive,
|
|
4312
|
+
viewerRows
|
|
4313
|
+
});
|
|
4314
|
+
if (result.cursorLine !== viewerCursorLine) {
|
|
4315
|
+
setViewerCursorLine(result.cursorLine);
|
|
4316
|
+
}
|
|
4317
|
+
if (result.autoPause) {
|
|
4318
|
+
setIsLive(false);
|
|
4319
|
+
setScrollOffset((o) => o + result.scrollDelta);
|
|
4320
|
+
setNewCount((n) => n + result.scrollDelta);
|
|
4321
|
+
}
|
|
4322
|
+
}, [mergedActivities.length, isLive, viewerRows, viewerCursorLine]);
|
|
4323
|
+
useEffect3(() => {
|
|
4324
|
+
const prev = prevPausedCountRef.current;
|
|
4325
|
+
prevPausedCountRef.current = mergedActivities.length;
|
|
4326
|
+
if (!isLive && mergedActivities.length > prev) {
|
|
4327
|
+
const delta = mergedActivities.length - prev;
|
|
4328
|
+
setScrollOffset((o) => o + delta);
|
|
4329
|
+
setNewCount((n) => n + delta);
|
|
4330
|
+
}
|
|
4331
|
+
}, [mergedActivities.length, isLive]);
|
|
4255
4332
|
const spinner = useSpinner(isWatchMode, 150);
|
|
4256
4333
|
const tickActive = isWatchMode && isLive && !helpMode && !detailMode && activities.length > 0;
|
|
4257
4334
|
const liveTick = useTick(tickActive, 150);
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
The following is an activity log from a single day of Claude Code sessions
|
|
2
|
-
|
|
1
|
+
The following is an activity log from a single day of Claude Code sessions,
|
|
2
|
+
possibly spanning multiple projects.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Each entry: `[HH:MM] <icon> <label>: <detail>`. Icons:
|
|
5
|
+
○ Read ~ Edit/Write $ Bash
|
|
6
|
+
* Glob/Grep @ WebFetch » Sub-agent task
|
|
7
|
+
< Response > User message … Thinking
|
|
8
|
+
◆ Git commit
|
|
9
|
+
|
|
10
|
+
Write a concise, high-signal engineering retro in first-person voice
|
|
11
|
+
("I implemented X", "I discovered Y") — treat the developer as the author.
|
|
12
|
+
|
|
13
|
+
Target ~300-500 words total; individual sections may be 50-100 words.
|
|
14
|
+
Favor synthesis over completeness.
|
|
6
15
|
|
|
7
16
|
Focus on:
|
|
8
17
|
- meaningful accomplishments
|
|
@@ -10,28 +19,38 @@ Focus on:
|
|
|
10
19
|
- architectural decisions
|
|
11
20
|
- implementation progress
|
|
12
21
|
- important tradeoffs or realizations
|
|
13
|
-
- unfinished work and next steps
|
|
22
|
+
- unfinished work and explicit next steps
|
|
23
|
+
|
|
24
|
+
Do NOT:
|
|
25
|
+
- mechanically summarize every edit, response, or commit
|
|
26
|
+
- list every modified file (cite paths only for important changes)
|
|
27
|
+
- invent follow-ups not present in the log (no "consider refactoring X")
|
|
28
|
+
- include placeholders like "None" or "N/A" — omit empty sections entirely
|
|
14
29
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Omit any section that has no substantive content — do not emit placeholders like "None" or "N/A".
|
|
18
|
-
Prefer high-level synthesis grouped by theme or workstream.
|
|
30
|
+
If activity spans multiple projects, group findings by project where clarity
|
|
31
|
+
improves. If they share a theme, synthesize.
|
|
19
32
|
|
|
20
|
-
|
|
33
|
+
If the day was light (few entries, no meaningful work), output a single short
|
|
34
|
+
paragraph instead of the full template. Do not pad.
|
|
35
|
+
|
|
36
|
+
Format (omit any section without substance):
|
|
21
37
|
|
|
22
38
|
## Context
|
|
23
|
-
|
|
39
|
+
The primary goal(s) of the day. If multi-project, briefly note each.
|
|
24
40
|
|
|
25
41
|
## Key Accomplishments
|
|
26
42
|
Meaningful progress, completed implementations, resolved issues.
|
|
27
43
|
|
|
28
44
|
## Technical Insights
|
|
29
|
-
Important debugging findings, architectural decisions, tradeoffs,
|
|
45
|
+
Important debugging findings, architectural decisions, tradeoffs, discoveries.
|
|
30
46
|
|
|
31
47
|
## Major Code Changes
|
|
32
|
-
Significant codebase
|
|
48
|
+
Significant codebase changes grouped by theme. Reference commits inline
|
|
49
|
+
(e.g., `abc1234`).
|
|
33
50
|
|
|
34
51
|
## Open Questions / Next Steps
|
|
35
|
-
Only
|
|
52
|
+
Only items explicitly stated in the log or directly tied to unfinished workflows.
|
|
53
|
+
|
|
54
|
+
After reading the log below, write the summary.
|
|
36
55
|
|
|
37
56
|
Activity log:
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agenthud",
|
|
3
|
-
"version": "0.13.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.13.2",
|
|
4
|
+
"description": "Claude Code TUI dashboard: live monitor for parallel sessions and sub-agents, with LLM-generated daily/weekly digest",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -29,13 +29,32 @@
|
|
|
29
29
|
"url": "git+https://github.com/neochoon/agenthud.git"
|
|
30
30
|
},
|
|
31
31
|
"keywords": [
|
|
32
|
-
"
|
|
32
|
+
"claude",
|
|
33
|
+
"claude-code",
|
|
34
|
+
"claude-code-cli",
|
|
35
|
+
"claude-code-tui",
|
|
36
|
+
"anthropic",
|
|
33
37
|
"agent",
|
|
38
|
+
"ai-agent",
|
|
39
|
+
"coding-agent",
|
|
40
|
+
"sub-agent",
|
|
41
|
+
"tui",
|
|
42
|
+
"terminal",
|
|
43
|
+
"terminal-ui",
|
|
44
|
+
"monitor",
|
|
45
|
+
"live-monitor",
|
|
46
|
+
"observability",
|
|
47
|
+
"session",
|
|
48
|
+
"sessions",
|
|
49
|
+
"session-monitor",
|
|
50
|
+
"session-manager",
|
|
34
51
|
"dashboard",
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
52
|
+
"digest",
|
|
53
|
+
"summary",
|
|
54
|
+
"llm",
|
|
55
|
+
"llm-summary",
|
|
56
|
+
"cli",
|
|
57
|
+
"developer-tools"
|
|
39
58
|
],
|
|
40
59
|
"author": "",
|
|
41
60
|
"license": "MIT",
|