agent-usage-all-in-one 0.4.0 → 0.4.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/dist/cli.js CHANGED
@@ -2571,7 +2571,7 @@ var init_claude_code_connector = __esm({
2571
2571
  usage: history.usage,
2572
2572
  ...history.usage.length > 0 && history.complete ? {
2573
2573
  usageReconciliation: {
2574
- authoritativeIdPrefix: "claude-transcript:",
2574
+ authoritativeIdPrefixes: ["claude-transcript:"],
2575
2575
  retiredIdPrefixes: ["claude-otel:"]
2576
2576
  }
2577
2577
  } : {},
@@ -3126,22 +3126,50 @@ var init_claude_usage_screen_client = __esm({
3126
3126
 
3127
3127
  // src/connectors/codex/codex-connector.ts
3128
3128
  import { z as z2 } from "zod";
3129
- function reconcileAccountRemainders(accountUsage, localUsage) {
3130
- return accountUsage.flatMap((accountObservation) => {
3131
- const day = accountObservation.observedAt.slice(0, 10);
3132
- const accountTotal = normalizeTokenObservation(accountObservation).recordedTokens;
3133
- const localTotal = localUsage.filter((observation) => observation.observedAt.slice(0, 10) === day).reduce(
3134
- (total, observation) => total + normalizeTokenObservation(observation).recordedTokens,
3135
- 0
3136
- );
3137
- if (localTotal === 0 || localTotal > accountTotal) return [];
3129
+ function settledAccountDays(response, nowMs) {
3130
+ return (response?.dailyUsageBuckets ?? []).map((bucket) => ({
3131
+ day: bucket.startDate,
3132
+ startMs: Date.parse(`${bucket.startDate}T00:00:00.000Z`),
3133
+ tokens: bucket.tokens
3134
+ })).filter((day) => Number.isFinite(day.startMs) && day.startMs + DAY_MS <= nowMs);
3135
+ }
3136
+ function reconcileAccountDays(days, localUsage) {
3137
+ const reconciledDays = new Set(days.map((day) => day.day));
3138
+ const localTotals = /* @__PURE__ */ new Map();
3139
+ for (const observation of localUsage) {
3140
+ const day = observation.observedAt.slice(0, 10);
3141
+ if (!reconciledDays.has(day)) continue;
3142
+ const recorded = normalizeTokenObservation(observation).recordedTokens;
3143
+ localTotals.set(day, (localTotals.get(day) ?? 0) + recorded);
3144
+ }
3145
+ return days.flatMap((day) => {
3146
+ const localTotal = localTotals.get(day.day) ?? 0;
3147
+ if (localTotal > day.tokens) return [];
3148
+ const observedAt = new Date(day.startMs).toISOString();
3149
+ const accountObservation = {
3150
+ id: `codex:daily:${day.day}`,
3151
+ billingDomainId: "subscription",
3152
+ model: null,
3153
+ observedAt,
3154
+ sourceReportedTotalTokens: day.tokens,
3155
+ inputTokens: 0,
3156
+ outputTokens: 0,
3157
+ cacheReadTokens: 0,
3158
+ cacheWriteTokens: 0,
3159
+ modelAttribution: "unclassified",
3160
+ timePrecision: "day",
3161
+ usageScope: "account-wide",
3162
+ authority: "official-account"
3163
+ };
3164
+ if (localTotal === 0) return [accountObservation];
3138
3165
  return [
3166
+ accountObservation,
3139
3167
  {
3140
- id: `codex-transcript:account-remainder:${day}`,
3168
+ id: `codex-transcript:account-remainder:${day.day}`,
3141
3169
  billingDomainId: "subscription",
3142
3170
  model: null,
3143
- observedAt: accountObservation.observedAt,
3144
- reconciledRemainderTokens: accountTotal - localTotal,
3171
+ observedAt,
3172
+ reconciledRemainderTokens: day.tokens - localTotal,
3145
3173
  inputTokens: 0,
3146
3174
  outputTokens: 0,
3147
3175
  cacheReadTokens: 0,
@@ -3198,23 +3226,6 @@ function mapQuotaBuckets(response) {
3198
3226
  }
3199
3227
  return buckets;
3200
3228
  }
3201
- function mapTokenUsage(response) {
3202
- return (response?.dailyUsageBuckets ?? []).map((bucket) => ({
3203
- id: `codex:daily:${bucket.startDate}`,
3204
- billingDomainId: "subscription",
3205
- model: null,
3206
- observedAt: `${bucket.startDate}T00:00:00.000Z`,
3207
- sourceReportedTotalTokens: bucket.tokens,
3208
- inputTokens: 0,
3209
- outputTokens: 0,
3210
- cacheReadTokens: 0,
3211
- cacheWriteTokens: 0,
3212
- modelAttribution: "unclassified",
3213
- timePrecision: "day",
3214
- usageScope: "account-wide",
3215
- authority: "official-account"
3216
- }));
3217
- }
3218
3229
  function formatWindowLabel(durationMinutes, fallback) {
3219
3230
  if (durationMinutes === 300) return "5 hour";
3220
3231
  if (durationMinutes === 10080) return "Week";
@@ -3223,7 +3234,7 @@ function formatWindowLabel(durationMinutes, fallback) {
3223
3234
  if (durationMinutes % 60 === 0) return `${durationMinutes / 60} hours`;
3224
3235
  return `${durationMinutes} minutes`;
3225
3236
  }
3226
- var nullableNumeric, numeric, rateLimitWindowSchema, rateLimitSnapshotSchema, codexRateLimitsSchema, codexTokenUsageSchema, CodexConnector;
3237
+ var nullableNumeric, numeric, rateLimitWindowSchema, rateLimitSnapshotSchema, codexRateLimitsSchema, codexTokenUsageSchema, CodexConnector, DAY_MS;
3227
3238
  var init_codex_connector = __esm({
3228
3239
  "src/connectors/codex/codex-connector.ts"() {
3229
3240
  "use strict";
@@ -3273,7 +3284,8 @@ var init_codex_connector = __esm({
3273
3284
  this.#historyClient = historyClient;
3274
3285
  }
3275
3286
  async collect(options = { mode: "incremental" }) {
3276
- const observedAt = this.#clock().toISOString();
3287
+ const now = this.#clock();
3288
+ const observedAt = now.toISOString();
3277
3289
  const warnings = [];
3278
3290
  let payload = null;
3279
3291
  try {
@@ -3283,18 +3295,18 @@ var init_codex_connector = __esm({
3283
3295
  }
3284
3296
  const history = this.#historyClient ? await this.#historyClient.readUsage(options) : { usage: [], costs: [], complete: true };
3285
3297
  const hasLocalHistory = history.usage.length > 0;
3286
- const accountUsage = mapTokenUsage(payload?.tokenUsage ?? null);
3287
- const canReconcile = history.complete && accountUsage.length > 0;
3288
- const reconciledRemainders = canReconcile ? reconcileAccountRemainders(accountUsage, history.usage) : [];
3298
+ const settledDays = settledAccountDays(payload?.tokenUsage ?? null, now.getTime());
3299
+ const canReconcile = history.complete && settledDays.length > 0;
3300
+ const accountUsage = canReconcile ? reconcileAccountDays(settledDays, history.usage) : [];
3289
3301
  if (!history.complete) warnings.push(incompleteTranscriptFailure2());
3290
3302
  return {
3291
3303
  provider: { id: "codex", displayName: "Codex" },
3292
3304
  billingDomains: [{ id: "subscription", displayName: "Codex subscription" }],
3293
3305
  quotaBuckets: payload ? mapQuotaBuckets(payload.rateLimits) : [],
3294
- usage: [...accountUsage, ...history.usage, ...reconciledRemainders],
3306
+ usage: [...accountUsage, ...history.usage],
3295
3307
  ...hasLocalHistory && canReconcile ? {
3296
3308
  usageReconciliation: {
3297
- authoritativeIdPrefix: "codex-transcript:",
3309
+ authoritativeIdPrefixes: ["codex-transcript:", "codex:daily:"],
3298
3310
  retiredIdPrefixes: []
3299
3311
  }
3300
3312
  } : {},
@@ -3304,6 +3316,7 @@ var init_codex_connector = __esm({
3304
3316
  };
3305
3317
  }
3306
3318
  };
3319
+ DAY_MS = 24 * 60 * 60 * 1e3;
3307
3320
  }
3308
3321
  });
3309
3322
 
@@ -3617,7 +3630,7 @@ var init_opencode_local_connector = __esm({
3617
3630
  quotaBuckets: [],
3618
3631
  usage: requests.map(mapLocalUsage),
3619
3632
  usageReconciliation: {
3620
- authoritativeIdPrefix: "opencode-local-request:",
3633
+ authoritativeIdPrefixes: ["opencode-local-request:"],
3621
3634
  retiredIdPrefixes: []
3622
3635
  },
3623
3636
  costs: requests.flatMap(
@@ -4043,7 +4056,7 @@ var init_opencode_go_connector = __esm({
4043
4056
  usage: [],
4044
4057
  ...localResult.status === "fulfilled" ? {
4045
4058
  usageReconciliation: {
4046
- authoritativeIdPrefix: "opencode-request:",
4059
+ authoritativeIdPrefixes: ["opencode-request:"],
4047
4060
  retiredIdPrefixes: ["opencode-session:"]
4048
4061
  }
4049
4062
  } : {},
@@ -4192,7 +4205,7 @@ var init_grok_build_connector = __esm({
4192
4205
  usage: history.usage,
4193
4206
  ...history.usage.length > 0 && history.complete ? {
4194
4207
  usageReconciliation: {
4195
- authoritativeIdPrefix: "grok-transcript:",
4208
+ authoritativeIdPrefixes: ["grok-transcript:"],
4196
4209
  retiredIdPrefixes: ["grok-otel:", "grok-headless:"]
4197
4210
  }
4198
4211
  } : {},
@@ -6152,8 +6165,9 @@ function isForkedCodexSession(payload) {
6152
6165
  const spawn7 = asObject(subagent?.thread_spawn);
6153
6166
  return string(spawn7?.parent_thread_id) !== null;
6154
6167
  }
6155
- async function listTranscriptFiles(root, cutoff) {
6168
+ async function listTranscriptFiles(roots, cutoff) {
6156
6169
  const files = [];
6170
+ const visited = /* @__PURE__ */ new Set();
6157
6171
  let complete = true;
6158
6172
  const walk = async (directory, isRoot = false) => {
6159
6173
  let entries;
@@ -6168,6 +6182,8 @@ async function listTranscriptFiles(root, cutoff) {
6168
6182
  if (entry.isDirectory()) {
6169
6183
  await walk(path);
6170
6184
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
6185
+ if (visited.has(path)) continue;
6186
+ visited.add(path);
6171
6187
  try {
6172
6188
  const metadata = await stat(path);
6173
6189
  if (metadata.mtimeMs >= cutoff) {
@@ -6179,7 +6195,7 @@ async function listTranscriptFiles(root, cutoff) {
6179
6195
  }
6180
6196
  }
6181
6197
  };
6182
- await walk(root, true);
6198
+ for (const root of roots) await walk(root, true);
6183
6199
  return { files, complete };
6184
6200
  }
6185
6201
  function isMissingPath(error) {
@@ -6272,7 +6288,7 @@ var init_local_transcript_usage_client = __esm({
6272
6288
  init_token_normalization();
6273
6289
  LocalTranscriptUsageClient = class {
6274
6290
  #provider;
6275
- #root;
6291
+ #roots;
6276
6292
  #clock;
6277
6293
  #lookbackDays;
6278
6294
  #cachePath;
@@ -6280,7 +6296,7 @@ var init_local_transcript_usage_client = __esm({
6280
6296
  #cacheLoaded = false;
6281
6297
  constructor(options) {
6282
6298
  this.#provider = options.provider;
6283
- this.#root = options.root;
6299
+ this.#roots = options.roots;
6284
6300
  this.#clock = options.clock ?? (() => /* @__PURE__ */ new Date());
6285
6301
  this.#lookbackDays = options.lookbackDays ?? 90;
6286
6302
  this.#cachePath = options.cachePath;
@@ -6289,7 +6305,7 @@ var init_local_transcript_usage_client = __esm({
6289
6305
  await this.#loadCache();
6290
6306
  if (options.mode === "hard-rebuild") this.#fileCache.clear();
6291
6307
  const cutoff = this.#clock().getTime() - this.#lookbackDays * 24 * 60 * 60 * 1e3;
6292
- const discovered = await listTranscriptFiles(this.#root, cutoff);
6308
+ const discovered = await listTranscriptFiles(this.#roots, cutoff);
6293
6309
  const files = discovered.files;
6294
6310
  let complete = discovered.complete;
6295
6311
  const usage = [];
@@ -6482,10 +6498,7 @@ async function runDatabaseWorker(workerData) {
6482
6498
  }
6483
6499
  function additiveUsagePredicate(alias = "") {
6484
6500
  const prefix = alias ? `${alias}.` : "";
6485
- const codexOfficialDays = `(SELECT billing_domain_id, date(observed_at)
6486
- FROM usage_observations
6487
- WHERE provider_id = 'codex' AND id LIKE 'codex:daily:%')`;
6488
- const codexRemainderDays = `(SELECT billing_domain_id, date(observed_at)
6501
+ const codexReconciledRemainderIds = `(SELECT billing_domain_id, id
6489
6502
  FROM usage_observations
6490
6503
  WHERE provider_id = 'codex' AND id LIKE 'codex-transcript:account-remainder:%')`;
6491
6504
  return `NOT (
@@ -6499,18 +6512,11 @@ function additiveUsagePredicate(alias = "") {
6499
6512
  )
6500
6513
  OR (
6501
6514
  ${prefix}provider_id = 'codex'
6515
+ AND ${prefix}id LIKE 'codex:daily:%'
6502
6516
  AND (
6503
- (
6504
- ${prefix}id LIKE 'codex:daily:%'
6505
- AND (${prefix}billing_domain_id, date(${prefix}observed_at)) IN ${codexRemainderDays}
6506
- )
6507
- OR (
6508
- ${prefix}id LIKE 'codex-transcript:%'
6509
- AND ${prefix}id NOT LIKE 'codex-transcript:account-remainder:%'
6510
- AND (${prefix}billing_domain_id, date(${prefix}observed_at)) IN ${codexOfficialDays}
6511
- AND (${prefix}billing_domain_id, date(${prefix}observed_at)) NOT IN ${codexRemainderDays}
6512
- )
6513
- )
6517
+ ${prefix}billing_domain_id,
6518
+ 'codex-transcript:account-remainder:' || substr(${prefix}id, 13)
6519
+ ) IN ${codexReconciledRemainderIds}
6514
6520
  )
6515
6521
  )`;
6516
6522
  }
@@ -7895,7 +7901,7 @@ var init_sqlite_usage_repository = __esm({
7895
7901
  const usageReconciliation = snapshot2.usageReconciliation;
7896
7902
  if (usageReconciliation) {
7897
7903
  const prefixes = [
7898
- usageReconciliation.authoritativeIdPrefix,
7904
+ ...usageReconciliation.authoritativeIdPrefixes,
7899
7905
  ...usageReconciliation.retiredIdPrefixes
7900
7906
  ];
7901
7907
  if (prefixes.some((prefix) => prefix.length === 0)) {
@@ -7930,11 +7936,12 @@ var init_sqlite_usage_repository = __esm({
7930
7936
  for (const prefix of usageReconciliation.retiredIdPrefixes) {
7931
7937
  deleteStoredUsage(prefix, /* @__PURE__ */ new Set());
7932
7938
  }
7933
- const authoritativePrefix = usageReconciliation.authoritativeIdPrefix;
7934
- const incomingAuthoritativeIds = new Set(
7935
- snapshot2.usage.map((observation) => observation.id).filter((id) => id.startsWith(authoritativePrefix))
7936
- );
7937
- deleteStoredUsage(authoritativePrefix, incomingAuthoritativeIds);
7939
+ for (const authoritativePrefix of usageReconciliation.authoritativeIdPrefixes) {
7940
+ const incomingAuthoritativeIds = new Set(
7941
+ snapshot2.usage.map((observation) => observation.id).filter((id) => id.startsWith(authoritativePrefix))
7942
+ );
7943
+ deleteStoredUsage(authoritativePrefix, incomingAuthoritativeIds);
7944
+ }
7938
7945
  }
7939
7946
  const usageStatement = this.#database.prepare(
7940
7947
  `INSERT INTO usage_observations (
@@ -9718,18 +9725,19 @@ async function runDaemon(home) {
9718
9725
  function localTranscriptClient(provider, applicationHome) {
9719
9726
  return new LocalTranscriptUsageClient({
9720
9727
  provider,
9721
- root: localTranscriptRoot(provider),
9728
+ roots: localTranscriptRoots(provider),
9722
9729
  cachePath: join8(applicationHome, "cache", `${provider}-transcripts.json`)
9723
9730
  });
9724
9731
  }
9725
- function localTranscriptRoot(provider) {
9732
+ function localTranscriptRoots(provider) {
9726
9733
  if (provider === "codex") {
9727
- return join8(resolveHomeOverride(process.env.CODEX_HOME, ".codex"), "sessions");
9734
+ const home = resolveHomeOverride(process.env.CODEX_HOME, ".codex");
9735
+ return [join8(home, "sessions"), join8(home, "archived_sessions")];
9728
9736
  }
9729
9737
  if (provider === "claude-code") {
9730
- return join8(resolveHomeOverride(process.env.CLAUDE_CONFIG_DIR, ".claude"), "projects");
9738
+ return [join8(resolveHomeOverride(process.env.CLAUDE_CONFIG_DIR, ".claude"), "projects")];
9731
9739
  }
9732
- return join8(resolveHomeOverride(process.env.GROK_HOME, ".grok"), "sessions");
9740
+ return [join8(resolveHomeOverride(process.env.GROK_HOME, ".grok"), "sessions")];
9733
9741
  }
9734
9742
  function resolveHomeOverride(value, fallback) {
9735
9743
  const configured = value?.trim();