repospend 0.1.3 → 0.1.5

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 CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  All notable changes to RepoSpend will be documented in this file.
4
4
 
5
+ ## 0.1.5
6
+
7
+ - Correct GPT-5.6 Sol and its alias to the current promotional rates, preserving custom pricing overrides.
8
+ - Add explicit Claude Sonnet 5.5 rates and newer Gemini Flash, MAI-Code, Grok, and Kimi Copilot models.
9
+ - Price Claude Opus 4.8, 5, and 5.5 fast-mode usage separately, including mixed-speed sessions and cached token buckets.
10
+ - Keep fast requests without a published rate unpriced rather than inheriting Standard rates.
11
+ - Prevent date-suffixed older Claude model IDs from inheriting newer model prices.
12
+ - Record promotional pricing dates and update model aliases and pricing documentation.
13
+
14
+ ## 0.1.4
15
+
16
+ - Add exact Standard API-equivalent rates for GPT-6 Astra, Sol, and Luna, including cached input and cache writes.
17
+ - Add Claude Fable 5.1, Mythos 5.1, Opus 5, and Opus 5.5 rates, including the lower cache-read rates for the newest models.
18
+ - Leave unlisted fast-mode model IDs unpriced instead of silently applying Standard rates.
19
+ - Keep legacy full pricing files eligible for bundled rate updates as new model rows are added, while preserving custom pricing overrides.
20
+ - Correct the Claude Sonnet 5 pricing note to reflect Anthropic's permanent $2 input and $10 output rates.
21
+ - Document the limits of short-context Standard pricing estimates for long-context and other processing modes.
22
+
5
23
  ## 0.1.3
6
24
 
7
25
  - Correct GPT-5.6 Terra and Luna API-equivalent pricing to the reduced July 30, 2026 OpenAI rates, including cached-input and cache-write rates.
package/dist/cli.js CHANGED
@@ -229,18 +229,25 @@ import path from "node:path";
229
229
 
230
230
  // packages/types/src/index.ts
231
231
  function normalizePricingModelId(model) {
232
- return model.toLowerCase().replace(/^github_copilot\//, "").replace(/^github-copilot\//, "").replace(/^copilot\//, "").replace(/claude-(opus|sonnet|haiku)-(\d+)\.(\d+)(?=$|[-.])/, "claude-$1-$2-$3");
232
+ return model.toLowerCase().replace(/-\d{8}(?=-fast-mode(?:$|-))/, "").replace(/^github_copilot\//, "").replace(/^github-copilot\//, "").replace(/^copilot\//, "").replace(/claude-(opus|sonnet|haiku)-(\d+)\.(\d+)(?=$|[-.])/, "claude-$1-$2-$3");
233
233
  }
234
234
  function claudePricingFamilyModel(model, isUsable = () => true) {
235
235
  const families = [
236
+ "claude-fable-5-1",
236
237
  "claude-fable-5",
238
+ "claude-mythos-5-1",
237
239
  "claude-mythos-5",
240
+ "claude-opus-5-5-fast-mode",
241
+ "claude-opus-5-fast-mode",
242
+ "claude-opus-5-5",
243
+ "claude-opus-5",
238
244
  "claude-opus-4-8-fast-mode",
239
245
  "claude-opus-4-7",
240
246
  "claude-opus-4-6",
241
247
  "claude-opus-4-5",
242
248
  "claude-opus-4-1",
243
249
  "claude-opus-4",
250
+ "claude-sonnet-5-5",
244
251
  "claude-sonnet-5",
245
252
  "claude-sonnet-4-6",
246
253
  "claude-sonnet-4-5",
@@ -249,8 +256,11 @@ function claudePricingFamilyModel(model, isUsable = () => true) {
249
256
  "claude-3-5-haiku"
250
257
  ];
251
258
  const normalized = normalizePricingModelId(model);
252
- if (normalized === "claude-opus-4-6-fast-mode") return void 0;
253
- return families.find((candidate) => (normalized === candidate || normalized.startsWith(`${candidate}-`) || normalized.startsWith(`${candidate}.`)) && isUsable(candidate));
259
+ const matchesFamily = (candidate) => normalized === candidate || normalized.startsWith(`${candidate}-`) || normalized.startsWith(`${candidate}.`);
260
+ if (normalized.includes("fast-mode")) {
261
+ return families.find((candidate) => candidate.includes("fast-mode") && matchesFamily(candidate) && isUsable(candidate));
262
+ }
263
+ return families.find((candidate) => matchesFamily(candidate) && isUsable(candidate));
254
264
  }
255
265
  function copilotPricingFamilyModel(model, isUsable = () => true) {
256
266
  const normalized = normalizePricingModelId(model);
@@ -261,6 +271,9 @@ function copilotPricingFamilyModel(model, isUsable = () => true) {
261
271
  if ((normalized === "gemini-3-flash" || normalized.startsWith("gemini-3-flash-")) && isUsable("gemini-3-flash")) return "gemini-3-flash";
262
272
  if ((normalized === "gemini-3.1-pro" || normalized.startsWith("gemini-3.1-pro-")) && isUsable("gemini-3.1-pro")) return "gemini-3.1-pro";
263
273
  if ((normalized === "gemini-3.5-flash" || normalized.startsWith("gemini-3.5-flash-")) && isUsable("gemini-3.5-flash")) return "gemini-3.5-flash";
274
+ for (const candidate of ["gemini-3.6-flash", "gemini-3.7-flash", "gemini-3.8-flash", "grok-4.5", "grok-4.6", "grok-4.7", "mai-code-1.1-flash", "kimi-k3"]) {
275
+ if ((normalized === candidate || normalized.startsWith(`${candidate}-`)) && isUsable(candidate)) return candidate;
276
+ }
264
277
  if ((normalized === "raptor-mini" || normalized.startsWith("raptor-mini-") || normalized.startsWith("oswe-vscode")) && isUsable("raptor-mini")) return "raptor-mini";
265
278
  if ((normalized === "lark" || normalized.startsWith("lark-")) && isUsable("lark")) return "lark";
266
279
  if ((normalized === "goldeneye" || normalized.startsWith("goldeneye-")) && isUsable("goldeneye")) return "goldeneye";
@@ -270,7 +283,7 @@ function copilotPricingFamilyModel(model, isUsable = () => true) {
270
283
  }
271
284
  function parseVersionedModel(normalized) {
272
285
  if (normalized.includes("fast-mode")) return void 0;
273
- const claude = normalized.match(/^(claude-(?:fable|mythos|opus|sonnet|haiku))-(\d+)(?:-(\d+))?/);
286
+ const claude = normalized.match(/^(claude-(?:fable|mythos|opus|sonnet|haiku))-(\d+)(?:-(\d{1,2}))?(?!\d)/);
274
287
  if (claude) {
275
288
  const minor = claude[3] ? Number(claude[3]) : 0;
276
289
  return { tier: claude[1], version: Number(claude[2]) + minor / 100 };
@@ -296,7 +309,7 @@ function versionedFallbackModel(model, knownModels, isUsable = () => true) {
296
309
  }
297
310
  function isCopilotAliasModel(model) {
298
311
  const normalized = normalizePricingModelId(model);
299
- return normalized.startsWith("raptor-mini") || normalized.startsWith("oswe-vscode") || normalized === "lark" || normalized.startsWith("lark-") || normalized.startsWith("goldeneye") || normalized.startsWith("mai-code-1-flash") || normalized.startsWith("kimi-k2.7-code");
312
+ return normalized.startsWith("raptor-mini") || normalized.startsWith("oswe-vscode") || normalized === "lark" || normalized.startsWith("lark-") || normalized.startsWith("goldeneye") || normalized.startsWith("mai-code-1-flash") || normalized.startsWith("kimi-k2.7-code") || normalized.startsWith("mai-code-1.1-flash") || (normalized === "kimi-k3" || normalized.startsWith("kimi-k3-")) || /^grok-4\.[567](?:$|-)/.test(normalized);
300
313
  }
301
314
  function positiveRate(value) {
302
315
  return typeof value === "number" && Number.isFinite(value) && value > 0;
@@ -323,18 +336,22 @@ var pricingInfo = {
323
336
  sourceUrl: "https://developers.openai.com/api/docs/pricing",
324
337
  sourceUrls: [
325
338
  { label: "OpenAI pricing reference", url: "https://developers.openai.com/api/docs/pricing" },
339
+ { label: "OpenAI GPT-6 model reference", url: "https://developers.openai.com/api/docs/models" },
326
340
  { label: "OpenAI GPT-5.6 preview pricing", url: "https://openai.com/index/previewing-gpt-5-6-sol/" },
327
341
  { label: "OpenAI GPT-5.6 price update", url: "https://openai.com/index/advancing-the-price-performance-frontier-with-gpt-5-6/" },
328
342
  { label: "Claude pricing reference", url: "https://platform.claude.com/docs/en/about-claude/pricing" },
329
343
  { label: "GitHub Copilot model pricing reference", url: "https://docs.github.com/en/copilot/reference/copilot-billing/models-and-pricing" }
330
344
  ],
331
345
  unit: "USD per 1M tokens",
332
- updatedAt: "2026-07-30",
333
- note: "RepoSpend estimates API-equivalent cost from local token counts and public API-style Standard pricing. GPT-5.6 Terra and Luna use the reduced OpenAI API rates effective July 30, 2026. This is not your actual bill; subscriptions, credits, provider terms, cache behavior, regional processing, or other billing factors can make your real cost different."
346
+ updatedAt: "2026-09-28",
347
+ note: "RepoSpend estimates API-equivalent cost from local token counts and public Standard pricing. GPT-6 defaults use short-context rates. Claude transcript fast-mode speeds use explicit published cards. Long-context, other processing modes, regional, and account-specific pricing can differ. This is not your actual bill."
334
348
  };
335
349
  var defaultPricing = {
336
- "gpt-5.6": { inputPerMillion: 5, cachedInputPerMillion: 0.5, cacheCreationInputPerMillion: 6.25, outputPerMillion: 30, reasoningOutputPerMillion: 30, note: "GPT-5.6 Sol flagship tier. OpenAI preview pricing lists Sol at $5 input / $30 output per 1M tokens, cache writes at 1.25x input, and cache reads at a 90% discount." },
337
- "gpt-5.6-sol": { inputPerMillion: 5, cachedInputPerMillion: 0.5, cacheCreationInputPerMillion: 6.25, outputPerMillion: 30, reasoningOutputPerMillion: 30 },
350
+ "gpt-6-astra": { inputPerMillion: 10, cachedInputPerMillion: 1, cacheCreationInputPerMillion: 12.5, outputPerMillion: 50, reasoningOutputPerMillion: 50 },
351
+ "gpt-6-sol": { inputPerMillion: 2, cachedInputPerMillion: 0.2, cacheCreationInputPerMillion: 2.5, outputPerMillion: 10, reasoningOutputPerMillion: 10 },
352
+ "gpt-6-luna": { inputPerMillion: 0.1, cachedInputPerMillion: 0.01, cacheCreationInputPerMillion: 0.125, outputPerMillion: 0.5, reasoningOutputPerMillion: 0.5 },
353
+ "gpt-5.6": { inputPerMillion: 4, cachedInputPerMillion: 0.4, cacheCreationInputPerMillion: 5, outputPerMillion: 20, reasoningOutputPerMillion: 20, note: "GPT-5.6 aliases Sol. Promotional Standard short-context rates are available at least through November 21, 2026: $4 input / $20 output, $0.40 cache reads, and $5 cache writes per 1M tokens." },
354
+ "gpt-5.6-sol": { inputPerMillion: 4, cachedInputPerMillion: 0.4, cacheCreationInputPerMillion: 5, outputPerMillion: 20, reasoningOutputPerMillion: 20, note: "Promotional Standard short-context rates available at least through November 21, 2026." },
338
355
  "gpt-5.6-terra": { inputPerMillion: 2, cachedInputPerMillion: 0.2, cacheCreationInputPerMillion: 2.5, outputPerMillion: 12, reasoningOutputPerMillion: 12, note: "GPT-5.6 Terra reduced API pricing effective July 30, 2026. Cache reads are 90% below input and cache writes are 1.25x input." },
339
356
  "gpt-5.6-luna": { inputPerMillion: 0.2, cachedInputPerMillion: 0.02, cacheCreationInputPerMillion: 0.25, outputPerMillion: 1.2, reasoningOutputPerMillion: 1.2, note: "GPT-5.6 Luna reduced API pricing effective July 30, 2026. Cache reads are 90% below input and cache writes are 1.25x input." },
340
357
  "gpt-5.5": { inputPerMillion: 5, cachedInputPerMillion: 0.5, outputPerMillion: 30, reasoningOutputPerMillion: 30 },
@@ -364,6 +381,14 @@ var defaultPricing = {
364
381
  "gemini-3-flash": { inputPerMillion: 0.5, cachedInputPerMillion: 0.05, outputPerMillion: 3, note: "GitHub Copilot supported Google-hosted model; API-equivalent estimate, not a Copilot bill." },
365
382
  "gemini-3.1-pro": { inputPerMillion: 2, cachedInputPerMillion: 0.2, outputPerMillion: 12, note: "GitHub Copilot supported Google-hosted model; API-equivalent estimate, not a Copilot bill." },
366
383
  "gemini-3.5-flash": { inputPerMillion: 1.5, cachedInputPerMillion: 0.15, outputPerMillion: 9, note: "GitHub Copilot supported Google-hosted model; API-equivalent estimate, not a Copilot bill." },
384
+ "gemini-3.6-flash": { inputPerMillion: 0.75, cachedInputPerMillion: 0.075, outputPerMillion: 3.75, note: "GitHub Copilot promotional rates through December 31, 2026; API-equivalent estimate." },
385
+ "gemini-3.7-flash": { inputPerMillion: 0.75, cachedInputPerMillion: 0.075, outputPerMillion: 3.75, note: "GitHub Copilot promotional rates through December 31, 2026; API-equivalent estimate." },
386
+ "gemini-3.8-flash": { inputPerMillion: 0.75, cachedInputPerMillion: 0.075, outputPerMillion: 3.75, note: "GitHub Copilot promotional rates through December 31, 2026; API-equivalent estimate." },
387
+ "grok-4.5": { inputPerMillion: 2, cachedInputPerMillion: 0.5, outputPerMillion: 6, note: "GitHub Copilot Standard rates up to 200K input tokens; longer requests use different rates." },
388
+ "grok-4.6": { inputPerMillion: 2, cachedInputPerMillion: 0.5, outputPerMillion: 6, note: "GitHub Copilot Standard rates up to 200K input tokens; longer requests use different rates." },
389
+ "grok-4.7": { inputPerMillion: 2, cachedInputPerMillion: 0.5, outputPerMillion: 6, note: "GitHub Copilot Standard rates up to 200K input tokens; longer requests use different rates." },
390
+ "mai-code-1.1-flash": { inputPerMillion: 0.2, cachedInputPerMillion: 0.02, outputPerMillion: 1.2, note: "GitHub Copilot Microsoft model; API-equivalent estimate." },
391
+ "kimi-k3": { inputPerMillion: 3, cachedInputPerMillion: 0.3, outputPerMillion: 15, note: "GitHub Copilot Moonshot AI model; API-equivalent estimate." },
367
392
  "raptor-mini": { inputPerMillion: 0.25, cachedInputPerMillion: 0.025, outputPerMillion: 2, note: "GitHub Copilot fine-tuned model using GPT-5 mini pricing." },
368
393
  "oswe-vscode-prime": { inputPerMillion: 0.25, cachedInputPerMillion: 0.025, outputPerMillion: 2, note: "GitHub Copilot Raptor mini internal model id." },
369
394
  "lark": { inputPerMillion: 0.25, cachedInputPerMillion: 0.025, outputPerMillion: 2, note: "GitHub Copilot preview model; estimated with lightweight Copilot pricing." },
@@ -371,7 +396,13 @@ var defaultPricing = {
371
396
  "mai-code-1-flash": { inputPerMillion: 0.75, cachedInputPerMillion: 0.075, outputPerMillion: 4.5, note: "GitHub Copilot supported Microsoft model; API-equivalent estimate, not a Copilot bill." },
372
397
  "kimi-k2.7-code": { inputPerMillion: 0.95, cachedInputPerMillion: 0.19, outputPerMillion: 4, note: "GitHub Copilot supported Moonshot AI model; API-equivalent estimate, not a Copilot bill." },
373
398
  "claude-fable-5": { inputPerMillion: 10, cacheCreationInput5mPerMillion: 12.5, cacheCreationInput1hPerMillion: 20, cacheCreationInputPerMillion: 20, cachedInputPerMillion: 1, outputPerMillion: 50 },
399
+ "claude-fable-5-1": { inputPerMillion: 10, cacheCreationInput5mPerMillion: 12.5, cacheCreationInput1hPerMillion: 20, cacheCreationInputPerMillion: 20, cachedInputPerMillion: 0.25, outputPerMillion: 50 },
374
400
  "claude-mythos-5": { inputPerMillion: 10, cacheCreationInput5mPerMillion: 12.5, cacheCreationInput1hPerMillion: 20, cacheCreationInputPerMillion: 20, cachedInputPerMillion: 1, outputPerMillion: 50, note: "Limited availability Anthropic model; same public API-equivalent pricing as Claude Fable 5." },
401
+ "claude-mythos-5-1": { inputPerMillion: 10, cacheCreationInput5mPerMillion: 12.5, cacheCreationInput1hPerMillion: 20, cacheCreationInputPerMillion: 20, cachedInputPerMillion: 0.25, outputPerMillion: 50, note: "Limited availability Anthropic model; same public API-equivalent pricing as Claude Fable 5.1." },
402
+ "claude-opus-5-5-fast-mode": { inputPerMillion: 8, cacheCreationInput5mPerMillion: 10, cacheCreationInput1hPerMillion: 16, cacheCreationInputPerMillion: 16, cachedInputPerMillion: 0.4, outputPerMillion: 40, note: "Anthropic first-party fast mode rates; cache multipliers apply." },
403
+ "claude-opus-5-5": { inputPerMillion: 4, cacheCreationInput5mPerMillion: 5, cacheCreationInput1hPerMillion: 8, cacheCreationInputPerMillion: 8, cachedInputPerMillion: 0.2, outputPerMillion: 20 },
404
+ "claude-opus-5-fast-mode": { inputPerMillion: 10, cacheCreationInput5mPerMillion: 12.5, cacheCreationInput1hPerMillion: 20, cacheCreationInputPerMillion: 20, cachedInputPerMillion: 1, outputPerMillion: 50, note: "Anthropic first-party fast mode rates; cache multipliers apply." },
405
+ "claude-opus-5": { inputPerMillion: 5, cacheCreationInput5mPerMillion: 6.25, cacheCreationInput1hPerMillion: 10, cacheCreationInputPerMillion: 10, cachedInputPerMillion: 0.5, outputPerMillion: 25 },
375
406
  "claude-opus-4-8": { inputPerMillion: 5, cacheCreationInput5mPerMillion: 6.25, cacheCreationInput1hPerMillion: 10, cacheCreationInputPerMillion: 10, cachedInputPerMillion: 0.5, outputPerMillion: 25 },
376
407
  "claude-opus-4-8-fast-mode": { inputPerMillion: 10, cacheCreationInput5mPerMillion: 12.5, cacheCreationInput1hPerMillion: 20, cacheCreationInputPerMillion: 12.5, cachedInputPerMillion: 1, outputPerMillion: 50, note: "Claude Opus 4.8 fast mode research preview pricing. Prompt caching multipliers apply on top of fast mode pricing." },
377
408
  "claude-opus-4-7": { inputPerMillion: 5, cacheCreationInput5mPerMillion: 6.25, cacheCreationInput1hPerMillion: 10, cacheCreationInputPerMillion: 10, cachedInputPerMillion: 0.5, outputPerMillion: 25 },
@@ -380,7 +411,8 @@ var defaultPricing = {
380
411
  "claude-opus-4-5": { inputPerMillion: 5, cacheCreationInput5mPerMillion: 6.25, cacheCreationInput1hPerMillion: 10, cacheCreationInputPerMillion: 10, cachedInputPerMillion: 0.5, outputPerMillion: 25 },
381
412
  "claude-opus-4-1": { inputPerMillion: 15, cacheCreationInput5mPerMillion: 18.75, cacheCreationInput1hPerMillion: 30, cacheCreationInputPerMillion: 30, cachedInputPerMillion: 1.5, outputPerMillion: 75 },
382
413
  "claude-opus-4": { inputPerMillion: 15, cacheCreationInput5mPerMillion: 18.75, cacheCreationInput1hPerMillion: 30, cacheCreationInputPerMillion: 30, cachedInputPerMillion: 1.5, outputPerMillion: 75 },
383
- "claude-sonnet-5": { inputPerMillion: 2, cacheCreationInput5mPerMillion: 2.5, cacheCreationInput1hPerMillion: 4, cacheCreationInputPerMillion: 4, cachedInputPerMillion: 0.2, outputPerMillion: 10, note: "Anthropic introductory pricing through August 31, 2026. Standard pricing from September 1, 2026 is $3 input / $15 output per 1M tokens." },
414
+ "claude-sonnet-5-5": { inputPerMillion: 2, cacheCreationInput5mPerMillion: 2.5, cacheCreationInput1hPerMillion: 4, cacheCreationInputPerMillion: 4, cachedInputPerMillion: 0.2, outputPerMillion: 10 },
415
+ "claude-sonnet-5": { inputPerMillion: 2, cacheCreationInput5mPerMillion: 2.5, cacheCreationInput1hPerMillion: 4, cacheCreationInputPerMillion: 4, cachedInputPerMillion: 0.2, outputPerMillion: 10, note: "Anthropic made the $2 input / $10 output introductory pricing permanent on August 10, 2026." },
384
416
  "claude-sonnet-4-6": { inputPerMillion: 3, cacheCreationInput5mPerMillion: 3.75, cacheCreationInput1hPerMillion: 6, cacheCreationInputPerMillion: 6, cachedInputPerMillion: 0.3, outputPerMillion: 15 },
385
417
  "claude-sonnet-4-5": { inputPerMillion: 3, cacheCreationInput5mPerMillion: 3.75, cacheCreationInput1hPerMillion: 6, cacheCreationInputPerMillion: 6, cachedInputPerMillion: 0.3, outputPerMillion: 15 },
386
418
  "claude-sonnet-4": { inputPerMillion: 3, cacheCreationInput5mPerMillion: 3.75, cacheCreationInput1hPerMillion: 6, cacheCreationInputPerMillion: 6, cachedInputPerMillion: 0.3, outputPerMillion: 15 },
@@ -388,9 +420,67 @@ var defaultPricing = {
388
420
  "claude-3-5-haiku": { inputPerMillion: 0.8, cacheCreationInput5mPerMillion: 1, cacheCreationInput1hPerMillion: 1.6, cacheCreationInputPerMillion: 1.6, cachedInputPerMillion: 0.08, outputPerMillion: 4 }
389
421
  };
390
422
  var legacyBundledPricing = {
423
+ "gpt-5.6": { inputPerMillion: 5, cachedInputPerMillion: 0.5, cacheCreationInputPerMillion: 6.25, outputPerMillion: 30, reasoningOutputPerMillion: 30, note: "GPT-5.6 Sol flagship tier. OpenAI preview pricing lists Sol at $5 input / $30 output per 1M tokens, cache writes at 1.25x input, and cache reads at a 90% discount." },
424
+ "gpt-5.6-sol": { inputPerMillion: 5, cachedInputPerMillion: 0.5, cacheCreationInputPerMillion: 6.25, outputPerMillion: 30, reasoningOutputPerMillion: 30 },
391
425
  "gpt-5.6-terra": { inputPerMillion: 2.5, cachedInputPerMillion: 0.25, cacheCreationInputPerMillion: 3.125, outputPerMillion: 15, reasoningOutputPerMillion: 15 },
392
- "gpt-5.6-luna": { inputPerMillion: 1, cachedInputPerMillion: 0.1, cacheCreationInputPerMillion: 1.25, outputPerMillion: 6, reasoningOutputPerMillion: 6 }
426
+ "gpt-5.6-luna": { inputPerMillion: 1, cachedInputPerMillion: 0.1, cacheCreationInputPerMillion: 1.25, outputPerMillion: 6, reasoningOutputPerMillion: 6 },
427
+ "claude-sonnet-5": { inputPerMillion: 2, cacheCreationInput5mPerMillion: 2.5, cacheCreationInput1hPerMillion: 4, cacheCreationInputPerMillion: 4, cachedInputPerMillion: 0.2, outputPerMillion: 10, note: "Anthropic introductory pricing through August 31, 2026. Standard pricing from September 1, 2026 is $3 input / $15 output per 1M tokens." }
393
428
  };
429
+ var legacyFullTableModelIds = [
430
+ "gpt-5.6",
431
+ "gpt-5.6-sol",
432
+ "gpt-5.6-terra",
433
+ "gpt-5.6-luna",
434
+ "gpt-5.5",
435
+ "gpt-5.5-pro",
436
+ "gpt-5.4",
437
+ "gpt-5.4-mini",
438
+ "gpt-5.4-nano",
439
+ "gpt-5.4-pro",
440
+ "gpt-5.3-codex",
441
+ "gpt-5.3-codex-spark",
442
+ "gpt-5.2",
443
+ "gpt-5.2-chat-latest",
444
+ "gpt-5.2-codex",
445
+ "gpt-5.2-pro",
446
+ "gpt-5.1",
447
+ "gpt-5.1-chat-latest",
448
+ "gpt-5.1-codex",
449
+ "gpt-5.1-codex-max",
450
+ "gpt-5",
451
+ "gpt-5-chat-latest",
452
+ "gpt-5-codex",
453
+ "gpt-5-pro",
454
+ "gpt-5-mini",
455
+ "gpt-5-nano",
456
+ "gpt-4.1",
457
+ "gemini-2.5-pro",
458
+ "gemini-3-flash",
459
+ "gemini-3.1-pro",
460
+ "gemini-3.5-flash",
461
+ "raptor-mini",
462
+ "oswe-vscode-prime",
463
+ "lark",
464
+ "goldeneye",
465
+ "mai-code-1-flash",
466
+ "kimi-k2.7-code",
467
+ "claude-fable-5",
468
+ "claude-mythos-5",
469
+ "claude-opus-4-8",
470
+ "claude-opus-4-8-fast-mode",
471
+ "claude-opus-4-7",
472
+ "claude-opus-4-6",
473
+ "claude-opus-4-6-fast-mode",
474
+ "claude-opus-4-5",
475
+ "claude-opus-4-1",
476
+ "claude-opus-4",
477
+ "claude-sonnet-5",
478
+ "claude-sonnet-4-6",
479
+ "claude-sonnet-4-5",
480
+ "claude-sonnet-4",
481
+ "claude-haiku-4-5",
482
+ "claude-3-5-haiku"
483
+ ];
394
484
  function loadPricingTable(pricingPath) {
395
485
  if (!pricingPath) {
396
486
  return defaultPricing;
@@ -412,7 +502,7 @@ function pricingOverrides(pricing) {
412
502
  );
413
503
  }
414
504
  function migrateLegacyBundledPricing(stored) {
415
- const isLegacyFullTable = Object.keys(defaultPricing).every((model) => Object.hasOwn(stored, model));
505
+ const isLegacyFullTable = legacyFullTableModelIds.every((model) => Object.hasOwn(stored, model));
416
506
  if (!isLegacyFullTable) return stored;
417
507
  const migrated = { ...stored };
418
508
  for (const [model, legacyPricing] of Object.entries(legacyBundledPricing)) {
@@ -2960,11 +3050,21 @@ function claudeBreakdownToUsage(file, index, options, breakdown, idSuffix = "")
2960
3050
  promptTimeline: breakdown.promptTimeline,
2961
3051
  sessionOutcome: inferOutcome2(breakdown)
2962
3052
  };
2963
- const cost = hasTokenBreakdown ? calculateCostUsd(usage, options.pricing) : void 0;
3053
+ const costBuckets = /* @__PURE__ */ new Map();
3054
+ for (const event of breakdown.usageEvents) {
3055
+ const model = event.model ?? breakdown.model;
3056
+ const normalized = model ? normalizePricingModelId(model) : void 0;
3057
+ const pricingModel = normalized && normalizedServiceTier(event.usage.speed) === "fast" && !normalized.includes("fast-mode") && !/^claude-opus-4-6(?:$|-)/.test(normalized) ? `${normalized}-fast-mode` : model;
3058
+ const totals = costBuckets.get(pricingModel) ?? emptyBreakdown2();
3059
+ applyUsage(totals, event.usage);
3060
+ costBuckets.set(pricingModel, totals);
3061
+ }
3062
+ const costs = hasTokenBreakdown ? [...costBuckets].map(([model, totals]) => calculateCostUsd({ ...totals, model, reasoningTokens: 0 }, options.pricing)) : [];
3063
+ const cost = costs.length && costs.every((value) => value !== void 0) ? Number(costs.reduce((sum2, value) => sum2 + (value ?? 0), 0).toFixed(6)) : void 0;
2964
3064
  return {
2965
3065
  ...usage,
2966
3066
  estimatedCostUsd: cost,
2967
- warnings: cost === void 0 ? [...usage.warnings, "unknown_pricing"] : usage.warnings
3067
+ warnings: cost === void 0 ? [...usage.warnings, "unknown_pricing", ...costs.some((value, index2) => value === void 0 && [...costBuckets.keys()][index2]?.includes("fast-mode")) ? ["unknown_fast_mode_pricing"] : []] : usage.warnings
2968
3068
  };
2969
3069
  }
2970
3070
  function inferClaudeEntrypointFromPath(filePath) {
package/docs/pricing.md CHANGED
@@ -4,10 +4,20 @@ RepoSpend estimates API-equivalent cost from a local pricing table. The bundled
4
4
 
5
5
  The bundled table is seeded from public OpenAI, Anthropic, Google, and GitHub Copilot model references and is expressed as USD per 1M tokens. Pricing changes over time, so treat RepoSpend costs as API-equivalent estimates rather than invoice-grade accounting.
6
6
 
7
- The bundled defaults use currently published standard API prices unless a provider has an active introductory API rate. For example, Claude Sonnet 5 uses Anthropic's $2 input and $10 output introductory rate through August 31, 2026, with a pricing-table note for the $3 input and $15 output standard rate that starts September 1, 2026.
7
+ The bundled defaults were checked on September 28, 2026 and use published Standard API prices. Claude Sonnet 5.5 has explicit $2 input / $10 output rates with the same cache rates as Sonnet 5. Claude Sonnet 5 remains at $2 input and $10 output per 1M tokens because Anthropic made its introductory rate permanent on August 10, 2026.
8
+
9
+ GPT-6 Astra, Sol, and Luna use OpenAI's Standard short-context rates. Their long-context requests above 272,000 input tokens use different rates, and local session totals do not identify every request's pricing tier. Fast, batch, and regional processing can also differ from these defaults. RepoSpend keeps the result labeled as an API-equivalent estimate.
10
+
11
+ Claude Fable 5.1 and Mythos 5.1 retain their predecessor's base rates but have lower cache-read pricing. Claude Opus 5.5 has its own lower base and cache rates. These model rows use Anthropic's global Standard rates.
8
12
 
9
13
  OpenAI reduced GPT-5.6 pricing effective July 30, 2026. RepoSpend uses $2 input and $12 output per 1M tokens for Terra, and $0.20 input and $1.20 output for Luna. Cached input remains 90% below the uncached input rate, and cache writes are billed at 1.25x the uncached input rate, so Luna's bundled cache-write rate is $0.25 per 1M tokens.
10
14
 
15
+ GPT-5.6 Sol and its `gpt-5.6` alias use promotional $4 input, $0.40 cached input, $5 cache writes, and $20 output/reasoning per 1M tokens, available at least through November 21, 2026. Older full bundled pricing files receive this correction; intentionally saved sparse overrides remain unchanged.
16
+
17
+ Gemini 3.6, 3.7, and 3.8 Flash use GitHub Copilot promotional rates through December 31, 2026. MAI-Code-1.1-Flash, Grok 4.5–4.7, and Kimi K3 have explicit Copilot reference cards. Grok rates use the up-to-200K input tier; longer requests cost more.
18
+
19
+ Claude transcript `usage.speed: "fast"` selects a fast-mode card per model and speed bucket, preserving accurate estimates for mixed-speed sessions. Opus 5.5 uses $8 input / $40 output, and Opus 5 uses $10 / $50; caching multipliers apply. Unknown fast cards remain unpriced with a visible warning. [Anthropic's current pricing documentation](https://platform.claude.com/docs/en/about-claude/pricing) states that Opus 4.6 ignores fast speed and uses Standard pricing. Regional and account modifiers are not applied.
20
+
11
21
  The Settings page persists only custom or intentionally edited model rows. This lets future bundled rate updates flow through automatically. Older full pricing files are migrated for the GPT-5.6 Terra and Luna reductions when they still contain the previous bundled rates.
12
22
 
13
23
  Some GitHub Copilot model rows are hosted or fine-tuned vendor models such as Raptor mini, MAI-Code-1-Flash, and Kimi K2.7 Code. RepoSpend prices those rows from GitHub's public per-token table as API-equivalent estimates, not as a Copilot invoice.
@@ -57,7 +67,7 @@ sessions that mostly used 5-minute cache writes. RepoSpend prices the buckets
57
67
  recorded in the local Claude transcript instead of forcing every cache write into
58
68
  one column.
59
69
 
60
- When an exact model id is not present in the pricing table, RepoSpend first tries conservative family matching for known provider naming patterns. For example, a nearby newer Claude Opus 4.x or GPT 5.x variant can inherit the closest older bundled rate so the dashboard stays useful while public rate cards catch up. Inherited rates are labeled in Settings.
70
+ When an exact model id is not present in the pricing table, RepoSpend first tries the closest older version in the same model tier, then conservative family matching for known provider naming patterns. For example, a nearby newer Claude Opus 4.x or GPT 5.x variant can inherit the closest older bundled rate so the dashboard stays useful while public rate cards catch up. Inherited rates are labeled in Settings.
61
71
 
62
72
  If RepoSpend cannot resolve a usable rate, it still displays token totals and marks cost as unknown. Unknown pricing does not stop scans, dashboard responses, CLI output, or exports.
63
73
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repospend",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Local-first dashboard for tracking AI coding token usage and API-equivalent spend by repository, session, model, and tool.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Mehmet Mustafa Demir",