@usagefleet/cli 1.2.174 → 1.2.175

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/dist/jcode.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { str } from './parser.js';
2
+ import { dirname, join } from 'node:path';
3
+ import { cacheSplit, str } from './parser.js';
4
4
  // "claude" and "claude-oauth" run on the Claude subscription; "claude-api" is a billed API key.
5
5
  const SUBSCRIPTION_PROVIDERS = new Set(['claude', 'claude-oauth']);
6
6
  // Same reason as the scanner's QUIET_MS: a write right after a read can keep the read's mtime.
@@ -26,6 +26,7 @@ export function readJcodeSession(snapshotPath, source, prev) {
26
26
  if (prev?.mtimeMs === mtimeMs) {
27
27
  return null;
28
28
  }
29
+ const cacheTtl1h = readsCacheTtl1h(join(dirname(dirname(snapshotPath)), 'config.toml'));
29
30
  const snapshot = JSON.parse(readFileSync(snapshotPath, 'utf-8'));
30
31
  // shortcut: snapshot turns take the session's current provider/model; a provider switch rewrites
31
32
  // the snapshot, so a first backfill of such a session books older turns on the new provider.
@@ -40,7 +41,7 @@ export function readJcodeSession(snapshotPath, source, prev) {
40
41
  const seen = new Set();
41
42
  const records = [];
42
43
  for (const [message, meta] of turns) {
43
- const record = toRecord(message, meta, str(snapshot.id), source);
44
+ const record = toRecord(message, meta, str(snapshot.id), source, cacheTtl1h);
44
45
  if (!record || seen.has(record.uuid) || Date.parse(record.timestamp) <= uploadedThrough) {
45
46
  continue;
46
47
  }
@@ -68,8 +69,16 @@ function readJournal(path) {
68
69
  }
69
70
  return lines;
70
71
  }
72
+ /** jcode caches every breakpoint with one TTL: `[provider] anthropic_cache_ttl_1h`, default true, which its
73
+ * /cache command rewrites. shortcut: past turns take today's setting, exact once jcode logs the split per turn. */
74
+ function readsCacheTtl1h(configPath) {
75
+ if (!existsSync(configPath)) {
76
+ return true;
77
+ }
78
+ return !/^\s*anthropic_cache_ttl_1h\s*=\s*false\b/m.test(readFileSync(configPath, 'utf-8'));
79
+ }
71
80
  /** jcode's `token_usage` is Anthropic's usage block (`prompt_tokens` is their sum, left out). */
72
- function toRecord(m, meta, sessionId, source) {
81
+ function toRecord(m, meta, sessionId, source, cacheTtl1h) {
73
82
  const u = m.token_usage;
74
83
  const id = str(m.id);
75
84
  const timestamp = str(m.timestamp);
@@ -81,11 +90,10 @@ function toRecord(m, meta, sessionId, source) {
81
90
  !SUBSCRIPTION_PROVIDERS.has(str(meta.provider_key) ?? '')) {
82
91
  return null;
83
92
  }
93
+ const cacheWrite = u.cache_creation_input_tokens ?? 0;
84
94
  return {
85
- // jcode does not log the cache-write TTL; the server prices it by the user's setting.
86
- cacheCreation1h: null,
87
- cacheCreation5m: null,
88
- cacheCreationTokens: u.cache_creation_input_tokens ?? 0,
95
+ ...cacheSplit(cacheWrite, cacheTtl1h ? cacheWrite : 0),
96
+ cacheCreationTokens: cacheWrite,
89
97
  cacheReadTokens: u.cache_read_input_tokens ?? 0,
90
98
  cwd: str(meta.working_dir),
91
99
  gitBranch: null,
package/dist/parser.js CHANGED
@@ -19,8 +19,16 @@ function cacheCreation(u) {
19
19
  const total = typeof u.cache_creation_input_tokens === 'number' ? u.cache_creation_input_tokens : (five ?? 0) + (oneHour ?? 0);
20
20
  return { five, oneHour, total };
21
21
  }
22
+ /** The 5m/1h split of a cache write for logs that name only its 1h part; unknown when they do not. */
23
+ export function cacheSplit(total, oneHour) {
24
+ if (typeof oneHour !== 'number') {
25
+ return { cacheCreation1h: null, cacheCreation5m: null };
26
+ }
27
+ const capped = Math.min(Math.max(oneHour, 0), total);
28
+ return { cacheCreation1h: capped, cacheCreation5m: total - capped };
29
+ }
22
30
  /** pi agent session line: `{type:"message", id, timestamp, message:{role:"assistant",
23
- * provider, model, responseId, usage:{input, output, cacheRead, cacheWrite}}}`.
31
+ * provider, model, responseId, usage:{input, output, cacheRead, cacheWrite, cacheWrite1h?}}}`.
24
32
  * Only requests that land on the user's Claude subscription count: provider
25
33
  * "anthropic" (pi's own client) and "claude-bridge" (the extension that routes
26
34
  * through Claude Code's OAuth login, so it burns the same limits — and writes no
@@ -50,10 +58,8 @@ function parsePiLine(o, sessionCwd) {
50
58
  return null;
51
59
  }
52
60
  return {
53
- // pi's usage line does not say which TTL the cache write used — leave the
54
- // breakdown unknown so the server prices it by the user's TTL setting.
55
- cacheCreation1h: null,
56
- cacheCreation5m: null,
61
+ // Older pi lines lack cacheWrite1h; the server prices those by the user's TTL setting.
62
+ ...cacheSplit(u.cacheWrite ?? 0, u.cacheWrite1h),
57
63
  cacheCreationTokens: u.cacheWrite ?? 0,
58
64
  cacheReadTokens: u.cacheRead ?? 0,
59
65
  cwd: sessionCwd,
@@ -72,7 +78,7 @@ function parsePiLine(o, sessionCwd) {
72
78
  };
73
79
  }
74
80
  /** agent CLI session line: `{type:"usage", id, provider, account, model, timestamp,
75
- * input, output, cache_read, cache_write}`, one per request, `timestamp` in epoch ms.
81
+ * input, output, cache_read, cache_write, cache_write_1h?}`, one per request, `timestamp` in epoch ms.
76
82
  * Only provider "anthropic" with an `account` (the Claude account uuid; API keys
77
83
  * have none) ran on a subscription, and each line books on its own account because
78
84
  * the agent switches accounts between requests. Lines from agents that predate
@@ -101,9 +107,8 @@ export function parseAgentLine(line, sessionCwd, sessionId) {
101
107
  return {
102
108
  accountExtId: account,
103
109
  record: {
104
- // The agent does not log the cache-write TTL; the server prices it by the user's setting.
105
- cacheCreation1h: null,
106
- cacheCreation5m: null,
110
+ // Lines from agents before cache_write_1h are priced by the user's TTL setting.
111
+ ...cacheSplit(tokens(o.cache_write), o.cache_write_1h),
107
112
  cacheCreationTokens: tokens(o.cache_write),
108
113
  cacheReadTokens: tokens(o.cache_read),
109
114
  cwd: sessionCwd,
package/dist/release.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by .github/workflows/release.yml.
2
- export const RELEASE_VERSION = "1.2.174";
2
+ export const RELEASE_VERSION = "1.2.175";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usagefleet/cli",
3
- "version": "1.2.174",
3
+ "version": "1.2.175",
4
4
  "description": "Tails Claude Code, Claude Desktop, and pi agent JSONL logs and reports token usage to a UsageFleet server.",
5
5
  "keywords": [
6
6
  "claude",