@tmustier/pi-usage-extension 0.10.0 → 0.10.1
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/CHANGELOG.md +5 -0
- package/README.md +3 -3
- package/data.ts +20 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.1] - 2026-10-28
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Read sessions from the directory Pi uses. `/usage` always read `<agentDir>/sessions`, so with a custom session directory it showed sessions Pi no longer used and missed the ones it did. It now follows Pi's order: `--session-dir`, then `PI_CODING_AGENT_SESSION_DIR`, then the `sessionDir` setting (project over global). Thanks to @JeremieAlcaraz for the report ([#98](https://github.com/tmustier/pi-extensions/issues/98)).
|
|
7
|
+
|
|
3
8
|
## [0.10.0] - 2026-10-26
|
|
4
9
|
|
|
5
10
|
### Added
|
package/README.md
CHANGED
|
@@ -194,7 +194,7 @@ On narrow terminals, `/usage` automatically switches to a compact table instead
|
|
|
194
194
|
|
|
195
195
|
## Performance & Caching
|
|
196
196
|
|
|
197
|
-
`/usage` builds its stats from every session JSONL file
|
|
197
|
+
`/usage` builds its stats from every session JSONL file in Pi's session directory (see [Data Source](#data-source)). To keep opens fast on large histories (multi-GB, thousands of files):
|
|
198
198
|
|
|
199
199
|
- **On-disk cache.** Per-file extraction results are cached in `<agentDir>/usage-extension-cache.json` (respects `PI_CODING_AGENT_DIR`), keyed by file size + mtime. Warm opens only re-parse session files that changed since the last run — on a 5.2 GB / 3,310-file corpus that takes the open from ~17 s to ~0.3 s.
|
|
200
200
|
- **First open** after install (or after deleting the cache) does a one-off full build, showing the usual cancellable loader. Cancelling saves partial progress, so the next open resumes where it left off.
|
|
@@ -226,11 +226,11 @@ The "Cache" column combines both read and write tokens.
|
|
|
226
226
|
|
|
227
227
|
## Data Source
|
|
228
228
|
|
|
229
|
-
Statistics are parsed recursively from session files in
|
|
229
|
+
Statistics are parsed recursively from session files in Pi's session directory, including nested subagent runs such as `run-0/` directories. Each session is a JSONL file containing assistant messages and, on Pi 0.81.0+, optional usage on tool-result, compaction, and branch-summary entries.
|
|
230
230
|
|
|
231
231
|
Assistant messages duplicated across branched session files are deduplicated by timestamp + total tokens. Auxiliary usage is deduplicated by its stable session entry id, which avoids collapsing parallel tools that happen to report identical usage. Nested-agent reports are suppressed when their child session files are part of the scan (resolved across all copies of the parent entry, since branch copies change runId-derived paths); reports whose children are missing stay under `Tools / summaries`. Tool and summary usage contributes cost and tokens to totals, graphs, project/session mix, and burn trend, but does not count as an assistant message or distort conversation context/cache insights.
|
|
232
232
|
|
|
233
|
-
|
|
233
|
+
The session directory is the one Pi uses: `--session-dir`, then the `PI_CODING_AGENT_SESSION_DIR` environment variable, then the `sessionDir` setting (project `.pi/settings.json` over the global `settings.json`), and otherwise `~/.pi/agent/sessions/`. The agent directory respects the `PI_CODING_AGENT_DIR` environment variable if set.
|
|
234
234
|
|
|
235
235
|
## Changelog
|
|
236
236
|
|
package/data.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* re-parses files that changed since the last run.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { readFileSync } from "node:fs";
|
|
14
15
|
import { readdir, readFile, rename, stat, writeFile } from "node:fs/promises";
|
|
15
16
|
import { homedir } from "node:os";
|
|
16
17
|
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
@@ -239,8 +240,24 @@ export function getAgentDir(): string {
|
|
|
239
240
|
return process.env.PI_CODING_AGENT_DIR || join(homedir(), ".pi", "agent");
|
|
240
241
|
}
|
|
241
242
|
|
|
242
|
-
|
|
243
|
-
|
|
243
|
+
function sessionDirSetting(settingsPath: string): string | undefined {
|
|
244
|
+
try {
|
|
245
|
+
const { sessionDir } = JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
246
|
+
return typeof sessionDir === "string" ? sessionDir : undefined;
|
|
247
|
+
} catch {
|
|
248
|
+
return undefined; // No settings file, or one Pi cannot read either.
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** Where Pi keeps sessions: `--session-dir`, `PI_CODING_AGENT_SESSION_DIR`, then `sessionDir` from project over global settings. */
|
|
253
|
+
function getSessionsDir(): string {
|
|
254
|
+
const flag = process.argv.lastIndexOf("--session-dir");
|
|
255
|
+
const configured =
|
|
256
|
+
(flag >= 0 ? process.argv[flag + 1] : undefined) ||
|
|
257
|
+
process.env.PI_CODING_AGENT_SESSION_DIR ||
|
|
258
|
+
sessionDirSetting(join(".pi", "settings.json")) ||
|
|
259
|
+
sessionDirSetting(join(getAgentDir(), "settings.json"));
|
|
260
|
+
return configured ? resolve(configured.replace(/^~(?=\/|$)/, homedir())) : join(getAgentDir(), "sessions");
|
|
244
261
|
}
|
|
245
262
|
|
|
246
263
|
export function getDefaultCachePath(): string {
|
|
@@ -1387,7 +1404,7 @@ export interface CollectUsageOptions {
|
|
|
1387
1404
|
signal?: AbortSignal;
|
|
1388
1405
|
/** Called once before parsing begins and periodically while files are parsed. */
|
|
1389
1406
|
onProgress?: (progress: CollectProgress) => void;
|
|
1390
|
-
/** Defaults to
|
|
1407
|
+
/** Defaults to the directory where Pi keeps sessions. */
|
|
1391
1408
|
sessionsDir?: string;
|
|
1392
1409
|
/** Defaults to `<agentDir>/usage-extension-cache.json`. Pass `null` to disable the on-disk cache. */
|
|
1393
1410
|
cachePath?: string | null;
|