idletime 0.1.2 → 0.2.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.
package/README.md CHANGED
@@ -14,7 +14,7 @@ Local Bun CLI for Codex activity, token burn, visual 24-hour rhythm charts, and
14
14
 
15
15
  ## How It Works
16
16
 
17
- `idletime` is read-only. It scans your local Codex session logs under `~/.codex/sessions/YYYY/MM/DD/*.jsonl` and builds reports from those raw events.
17
+ The dashboard and snapshot commands are read-only. They scan your local Codex session logs under `~/.codex/sessions/YYYY/MM/DD/*.jsonl` and build reports from those raw events. The explicit `refresh-bests` command is the maintenance exception: it updates `~/.idletime/` and can fire best-related notifications.
18
18
 
19
19
  At a high level:
20
20
 
@@ -64,7 +64,9 @@ bun run idletime
64
64
 
65
65
  That shows:
66
66
 
67
+ - A gold `BEST` plaque in the header for your top concurrent agents, top 24-hour raw burn, and top agent-sum record
67
68
  - A framed trailing-24h dashboard
69
+ - A dedicated `Agents` section that charts concurrent child-task windows over the day
68
70
  - A `24h Rhythm` strip for `focus`, `active`, `quiet` or `idle`, and `burn`
69
71
  - `Spike Callouts` for the biggest burn hours
70
72
  - A lower detail section with activity, tokens, and wake-window stats
@@ -76,11 +78,14 @@ That shows:
76
78
  - `idle`: awake idle time, only shown when you pass `--wake`
77
79
  - `quiet`: non-active time when no wake window is provided
78
80
  - `burn`: practical burn, calculated as `input - cached_input + output`
81
+ - `Agents`: concurrent child-task windows derived from transcript lifecycle records when they exist, with a compatibility fallback for older subagent logs
79
82
 
80
83
  Additional behavior:
81
84
 
82
85
  - `last24h`: the default trailing window, clipped to the actual last 24 hours
83
86
  - `today`: local midnight to now
87
+ - `live`: global task scoreboard by default, with `waiting on you`, `running`, recent concurrency, and per-project live state
88
+ - `refresh-bests`: explicit full-history personal-record refresh for the `BEST` plaque and best-related notifications
84
89
  - `direct`: user-started work in the main CLI or compatible direct session types
85
90
  - `subagent`: spawned agent sessions
86
91
  - `idle cutoff`: how long activity stays alive after the last event before it counts as quiet or idle
@@ -123,12 +128,54 @@ Open the full hourly table:
123
128
  bun run idletime hourly --window 24h --workspace-only /path/to/demo-workspace
124
129
  ```
125
130
 
131
+ Open the live global scoreboard:
132
+
133
+ ```bash
134
+ bun run idletime live
135
+ ```
136
+
137
+ `live` defaults to all local sessions. Use `--workspace-only` when you want to pin the board to one repo or project path.
138
+ Use `--global` when you want to clear a previously added workspace scope explicitly.
139
+ When stdout is a TTY it repaints in place like a scoreboard. When stdout is not a TTY, it renders one snapshot and exits, which makes it usable in scripts and validation.
140
+
141
+ Pin the live board to one workspace:
142
+
143
+ ```bash
144
+ bun run idletime live --workspace-only /path/to/demo-workspace
145
+ ```
146
+
147
+ Refresh your `BEST` records explicitly:
148
+
149
+ ```bash
150
+ bun run idletime refresh-bests
151
+ ```
152
+
126
153
  Group the summary by model and effort:
127
154
 
128
155
  ```bash
129
156
  bun run idletime last24h --group-by model --group-by effort
130
157
  ```
131
158
 
159
+ Get machine-readable snapshots:
160
+
161
+ ```bash
162
+ bun run idletime --json
163
+ ```
164
+
165
+ ```bash
166
+ bun run idletime today --json
167
+ ```
168
+
169
+ ```bash
170
+ bun run idletime hourly --json
171
+ ```
172
+
173
+ ```bash
174
+ bun run idletime live --json
175
+ ```
176
+
177
+ `--json` is read-only. It emits one versioned JSON snapshot and exits. On `last24h` and `today`, it does not refresh best metrics or trigger best-related notifications. `--share` is human-only and cannot be combined with `--json`.
178
+
132
179
  ## Share Mode
133
180
 
134
181
  `--share` keeps the visual story and trims the secondary detail:
@@ -144,6 +191,7 @@ That is the best mode for terminal screenshots.
144
191
 
145
192
  The top of the dashboard is intentionally visual-first.
146
193
 
194
+ - `Agents` plots concurrent child-task windows with real clock labels like `8am`, `12pm`, and `4pm`
147
195
  - `24h Rhythm` gives one character per hour bucket across the trailing day
148
196
  - `focus` makes it obvious where you were actually engaged
149
197
  - `active` shows the broader direct-session footprint
@@ -151,6 +199,17 @@ The top of the dashboard is intentionally visual-first.
151
199
  - `burn` highlights token spikes without making you read the table first
152
200
  - `Spike Callouts` surfaces the top burn hours immediately
153
201
 
202
+ The live board is intentionally narrower:
203
+
204
+ - `waiting on you`: recent direct sessions whose latest task completed after your last `user_message`, so you likely owe the next reply
205
+ - `running`: active task windows across the selected scope after effort-aware staleness
206
+ - `running at`: per-project counts for currently running work
207
+ - `waiting at`: per-project counts for sessions currently waiting on you
208
+ - `top waiting`: the specific waiting threads, shown as `project • age • thread id`
209
+ - `recent`: short live concurrency strip across the last 15 minutes
210
+ - `this turn`: completed child tasks anchored to the latest still-warm direct `user_message`
211
+ - `today peak`: highest observed concurrent child-task count since local midnight
212
+
154
213
  ## Help
155
214
 
156
215
  ```bash
@@ -171,6 +230,27 @@ Once published, that also works as:
171
230
  idletime --version
172
231
  ```
173
232
 
233
+ ## Record Tracking
234
+
235
+ `idletime` now keeps a local personal-best ledger under `~/.idletime/`.
236
+
237
+ - `bests-v1.json`: durable best values for the header plaque
238
+ - `best-events.ndjson`: append-only new-best history
239
+ - `near-best-notifications-v1.json`: opt-in state for “close to best” nudges
240
+
241
+ By default:
242
+
243
+ - dashboards read cached `BEST` values when `bests-v1.json` already exists
244
+ - a cold cache renders without the `BEST` plaque instead of bootstrapping best state implicitly
245
+ - genuine new-best events can trigger a local macOS notification during the explicit refresh path
246
+ - near-best nudges are stored but disabled until you opt in by setting `nearBestEnabled` to `true`
247
+
248
+ When you want to recompute those records, update the ledger, and fire any eligible notifications, run:
249
+
250
+ ```bash
251
+ bun run idletime refresh-bests
252
+ ```
253
+
174
254
  ## Validation
175
255
 
176
256
  ```bash
@@ -191,6 +271,8 @@ That QA pass reads:
191
271
 
192
272
  It builds the package, packs the current checkout, installs the tarball into an isolated temp `BUN_INSTALL`, seeds synthetic Codex session logs, and runs the shell journeys against the installed `idletime` binary.
193
273
 
274
+ Operational note: the default `last24h` and `today` commands now stay on the fast read path. They render from the requested report window plus any cached `BEST` ledger state and do not refresh records implicitly. `refresh-bests` is the only CLI command that performs the full-history best-metrics scan.
275
+
194
276
  ## Release Prep
195
277
 
196
278
  Build the publishable CLI bundle:
@@ -0,0 +1,33 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256" fill="none">
2
+ <defs>
3
+ <linearGradient id="bg" x1="24" y1="20" x2="228" y2="236" gradientUnits="userSpaceOnUse">
4
+ <stop offset="0" stop-color="#202611"/>
5
+ <stop offset="1" stop-color="#12160A"/>
6
+ </linearGradient>
7
+ <linearGradient id="glow" x1="44" y1="42" x2="212" y2="220" gradientUnits="userSpaceOnUse">
8
+ <stop offset="0" stop-color="#C7BC61"/>
9
+ <stop offset="1" stop-color="#786B2A"/>
10
+ </linearGradient>
11
+ <linearGradient id="top" x1="128" y1="62" x2="128" y2="116" gradientUnits="userSpaceOnUse">
12
+ <stop offset="0" stop-color="#F0E6AB"/>
13
+ <stop offset="1" stop-color="#D7C770"/>
14
+ </linearGradient>
15
+ <linearGradient id="left" x1="90" y1="92" x2="118" y2="196" gradientUnits="userSpaceOnUse">
16
+ <stop offset="0" stop-color="#D0BC58"/>
17
+ <stop offset="1" stop-color="#937F34"/>
18
+ </linearGradient>
19
+ <linearGradient id="right" x1="166" y1="92" x2="138" y2="198" gradientUnits="userSpaceOnUse">
20
+ <stop offset="0" stop-color="#BFA747"/>
21
+ <stop offset="1" stop-color="#6E5E22"/>
22
+ </linearGradient>
23
+ </defs>
24
+ <rect x="16" y="16" width="224" height="224" rx="44" fill="url(#bg)"/>
25
+ <rect x="26" y="26" width="204" height="204" rx="34" stroke="url(#glow)" stroke-opacity=".42" stroke-width="4"/>
26
+ <rect x="42" y="42" width="172" height="22" rx="11" fill="url(#glow)" fill-opacity=".34"/>
27
+ <path d="M128 58 184 90 128 122 72 90 128 58Z" fill="url(#top)"/>
28
+ <path d="M72 90 128 122V190L72 158V90Z" fill="url(#left)"/>
29
+ <path d="M184 90 128 122V190L184 158V90Z" fill="url(#right)"/>
30
+ <path d="M128 58 184 90 128 122 72 90 128 58Z" stroke="#F5EDBD" stroke-opacity=".74" stroke-width="3"/>
31
+ <path d="M72 90 128 122M184 90 128 122M128 122V190" stroke="#FFF5C5" stroke-opacity=".42" stroke-width="3"/>
32
+ <path d="M86 178h84" stroke="#FFF0AB" stroke-opacity=".24" stroke-width="6" stroke-linecap="round"/>
33
+ </svg>
Binary file