| ... | @@ -118,9 +118,9 @@ function fingerprintKey(fingerprint: UsageSourceFingerprint): string { | ... | @@ -118,9 +118,9 @@ function fingerprintKey(fingerprint: UsageSourceFingerprint): string { |
| 118 | * | 118 | * |
| 119 | * Several environments on one machine (worktree servers, for instance) resolve | 119 | * Several environments on one machine (worktree servers, for instance) resolve |
| 120 | * the same provider home and would otherwise double count every token. The | 120 | * the same provider home and would otherwise double count every token. The |
| 121 | * first environment in a stable order claims a fingerprint; the rest have that | 121 | * most recently read summary claims a fingerprint; the rest have that provider's |
| 122 | * provider's buckets dropped. Environments are sorted by id so the winner does | 122 | * buckets dropped. Environment ids break ties so the winner is stable when |
| 123 | * not change between renders. | 123 | * summaries have the same read time. |
| 124 | */ | 124 | */ |
| 125 | function claimSources(environments: readonly EnvironmentUsage[]): { | 125 | function claimSources(environments: readonly EnvironmentUsage[]): { |
| 126 | readonly ownerByFingerprint: ReadonlyMap<string, EnvironmentId>; | 126 | readonly ownerByFingerprint: ReadonlyMap<string, EnvironmentId>; |
| ... | @@ -129,7 +129,11 @@ function claimSources(environments: readonly EnvironmentUsage[]): { | ... | @@ -129,7 +129,11 @@ function claimSources(environments: readonly EnvironmentUsage[]): { |
| 129 | const ownerByFingerprint = new Map<string, EnvironmentId>(); | 129 | const ownerByFingerprint = new Map<string, EnvironmentId>(); |
| 130 | const duplicates: string[] = []; | 130 | const duplicates: string[] = []; |
| 131 | | 131 | |
| 132 | const ordered = [...environments].sort((a, b) => a.environmentId.localeCompare(b.environmentId)); | 132 | const ordered = [...environments].sort( |
| | 133 | (a, b) => |
| | 134 | (Date.parse(b.summary.readAt) || 0) - (Date.parse(a.summary.readAt) || 0) || |
| | 135 | a.environmentId.localeCompare(b.environmentId), |
| | 136 | ); |
| 133 | | 137 | |
| 134 | for (const environment of ordered) { | 138 | for (const environment of ordered) { |
| 135 | for (const source of environment.summary.sources) { | 139 | for (const source of environment.summary.sources) { |