Skip to content

Conversation

@juicemia
Copy link
Contributor

@juicemia juicemia commented Jul 29, 2025

This adds a weekly usage command. (#375) From what I read, it wasn't exactly clear how they were going to set the usage window so I added code that makes it work for both Sunday and Monday. When we know how the windows are going to work we can update it. I tested both though and they both seem to work.

With it set to Monday:
Screenshot 2025-07-29 at 11 06 14 AM

With it set to Sunday:
Screenshot 2025-07-29 at 11 06 45 AM

For now I left it set to Monday because I think that'll most likely be the day they reset it since it's the first day of the working week.

Summary by CodeRabbit

  • New Features

    • Added weekly usage reporting, allowing users to view aggregated token usage and costs by week.
    • Introduced a new CLI command to generate weekly usage reports with options for JSON or table output, filtering, and detailed breakdowns.
    • Enhanced data aggregation to support grouping usage by arbitrary time buckets (weekly or monthly).
    • Added support for weekly usage data type across calculations and validations.
    • Introduced configurable start day of the week for weekly reports.
  • Bug Fixes

    • Ensured tests run consistently in the UTC timezone.
  • Chores

    • Updated development dependencies to earlier versions for improved compatibility.

@coderabbitai
Copy link

coderabbitai bot commented Jul 29, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This update introduces weekly aggregation and reporting features to the codebase. New types, schemas, and helper functions for weekly buckets are added. The data loader is refactored to support generic aggregation by week or month. A new CLI command outputs weekly usage reports. The cost calculation, CLI command registry, and tests are updated accordingly. Minor dependency version changes and test environment updates are also included.

Changes

Cohort / File(s) Change Summary
Weekly Types and Utilities
src/_types.ts
Added weeklyDateSchema, WeeklyDate, Bucket, createWeeklyDate, and createBucket for weekly date validation and bucket type support.
Generic and Weekly Data Aggregation
src/data-loader.ts
Introduced weekly aggregation logic: new schemas/types (weeklyUsageSchema, WeeklyUsage, bucketUsageSchema, BucketUsage), helper getDateWeek, generic loadBucketUsageData, and loadWeeklyUsageData. Refactored monthly aggregation to use the new generic function. Added comprehensive tests for weekly aggregation.
Cost Calculation Update
src/calculate-cost.ts
Updated calculateTotals to support the new WeeklyUsage data type in its input, allowing aggregation over weekly data.
CLI Command Registry
src/commands/index.ts
Registered a new "weekly" CLI subcommand by importing and mapping weeklyCommand in the subCommands map.
Weekly CLI Command
src/commands/weekly.ts
Added new exported weeklyCommand for generating weekly usage reports, supporting JSON/table output, filtering, ordering, breakdowns, and debug reporting. Implements aggregation, formatting, and output logic for weekly data.
Weekday Constants
src/_consts.ts
Added WEEK_DAYS constant as a tuple of weekday strings from "sunday" to "saturday" for use in weekly aggregation logic.
Test Script and Dev Dependencies
package.json
Modified test script to use TZ=UTC for consistent timezone testing. Downgraded several devDependencies by minor/patch versions.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI (weeklyCommand)
    participant DataLoader
    participant Formatter

    User->>CLI (weeklyCommand): Run "weekly" report command with options
    CLI (weeklyCommand)->>DataLoader: loadWeeklyUsageData(options)
    DataLoader->>DataLoader: Aggregate daily usage into weekly buckets
    DataLoader-->>CLI (weeklyCommand): Return WeeklyUsage[]
    CLI (weeklyCommand)->>Formatter: Format data (table or JSON)
    Formatter-->>CLI (weeklyCommand): Formatted output
    CLI (weeklyCommand)-->>User: Display weekly usage report
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇
A week of tokens, counted neat,
New buckets where the numbers meet.
CLI commands with tables bright,
Aggregations done just right.
From daily logs to weekly cheer—
Review these changes, have no fear!
—Your code rabbit, always near.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5e16ab5 and cc1d784.

📒 Files selected for processing (3)
  • src/_consts.ts (1 hunks)
  • src/commands/weekly.ts (1 hunks)
  • src/data-loader.ts (11 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @juicemia, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new weekly command to the CLI tool, providing users with the ability to view their Claude API usage aggregated on a weekly basis. This enhancement expands the reporting capabilities of the tool, offering a new temporal granularity for usage analysis, and includes flexible configuration for defining the start of the week.

Highlights

  • New weekly CLI Command: A new command weekly has been added to the CLI, enabling users to generate usage reports grouped by week, similar to the existing daily and monthly reports.
  • Weekly Data Aggregation Logic: New data loading and aggregation logic (loadWeeklyUsageData) has been implemented to process daily usage data and group it into weekly summaries, including detailed token counts, costs, and model breakdowns.
  • Flexible Week Start Configuration: The weekly aggregation logic is designed to easily switch between Monday (currently configured) and Sunday as the start of the week, providing flexibility for future adjustments based on how usage windows are defined.
  • New Data Types and Schemas: Introduced a WeeklyDate type and weeklyDateSchema for YYYY-MM-DD date format validation, along with a WeeklyUsage schema to define the structure of the aggregated weekly data.
  • Enhanced Reporting Capabilities: The new weekly command supports both human-readable table output (with a compact mode for smaller terminals) and JSON output, integrating existing features like model breakdown views and debug information.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new weekly command to display usage data aggregated by week. The implementation is consistent with the existing daily and monthly commands. I've identified a few areas for improvement, including a critical bug in the sorting logic, code duplication in the data loading function, documentation inconsistencies, and a lack of unit tests. Addressing these points will significantly improve the quality and maintainability of the code.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
.gitignore (1)

38-39: Duplicate .eslintcache entry – keep only one

.eslintcache is already listed at line 26. Keeping a second identical pattern is redundant and clutters the ignore list.

- .eslintcache
src/data-loader.ts (2)

267-270: Fix incorrect comment.

The comment incorrectly refers to "monthly usage aggregation" instead of "weekly usage aggregation".

 /**
- * Type definition for monthly usage aggregation
+ * Type definition for weekly usage aggregation
  */
 export type WeeklyUsage = z.infer<typeof weeklyUsageSchema>;

1145-1166: Week calculation logic is correct.

The getDateWeek function correctly calculates the Monday start of the week for any given date. The approach of making the week start day configurable is good design given the uncertainty about Anthropic's billing window.

Consider cleaning up the unused SUNDAY constant and related comment since it's not currently used:

-// SUNDAY and MONDAY are both here because we don't know yet how Anthropic
-// is going to group the weekly usage. The code is written this way so that
-// if it needs to be changed it'll be easy to just change it.
-// const SUNDAY: DayOfWeek = 0;
+// Currently using Monday as week start. This can be easily changed
+// to Sunday (0) if needed once Anthropic's billing window is confirmed.
 const MONDAY: DayOfWeek = 1;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f77833d and 0e7c5ba145852b151b30014272ad0cfee38f8f5d.

📒 Files selected for processing (6)
  • .gitignore (1 hunks)
  • src/_types.ts (3 hunks)
  • src/calculate-cost.ts (2 hunks)
  • src/commands/index.ts (1 hunks)
  • src/commands/weekly.ts (1 hunks)
  • src/data-loader.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.{js,jsx,ts,tsx}: Lint code using ESLint MCP server (available via Claude Code tools)
Format code with ESLint (writes changes) using bun run format
No console.log allowed except where explicitly disabled with eslint-disable
Do not use console.log. Use logger.ts instead.

Files:

  • src/calculate-cost.ts
  • src/_types.ts
  • src/commands/weekly.ts
  • src/commands/index.ts
  • src/data-loader.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Type check with TypeScript using bun typecheck

Files:

  • src/calculate-cost.ts
  • src/_types.ts
  • src/commands/weekly.ts
  • src/commands/index.ts
  • src/data-loader.ts
**/*.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.ts: File paths always use Node.js path utilities for cross-platform compatibility
Use .ts extensions for local file imports (e.g., import { foo } from './utils.ts')
Prefer @praha/byethrow Result type over traditional try-catch for functional error handling
Use Result.try() for wrapping operations that may throw (JSON parsing, etc.)
Use Result.isFailure() for checking errors (more readable than !Result.isSuccess())
Use early return pattern (if (Result.isFailure(result)) continue;) instead of ternary operators
For async operations: create wrapper function with Result.try() then call it
Keep traditional try-catch only for: file I/O with complex error handling, legacy code that's hard to refactor
Always use Result.isFailure() and Result.isSuccess() type guards for better code clarity
Variables: start with lowercase (camelCase) - e.g., usageDataSchema, modelBreakdownSchema
Types: start with uppercase (PascalCase) - e.g., UsageData, ModelBreakdown
Constants: can use UPPER_SNAKE_CASE - e.g., DEFAULT_CLAUDE_CODE_PATH
Only export constants, functions, and types that are actually used by other modules
Internal/private constants that are only used within the same file should NOT be exported
Always check if a constant is used elsewhere before making it export const vs just const
All test files must use current Claude 4 models, not outdated Claude 3 models
Test coverage should include both Sonnet and Opus models for comprehensive validation
Model names in tests must exactly match LiteLLM's pricing database entries
When adding new model tests, verify the model exists in LiteLLM before implementation
Tests depend on real pricing data from LiteLLM - failures may indicate model availability issues
Dynamic imports using await import() should only be used within test blocks to avoid tree-shaking issues
Mock data is created using fs-fixture with createFixture() for Claude data directory simulation
In-source testing pattern: Tests are written...

Files:

  • src/calculate-cost.ts
  • src/_types.ts
  • src/commands/weekly.ts
  • src/commands/index.ts
  • src/data-loader.ts
**/_*.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

Internal files: use underscore prefix - e.g., _types.ts, _utils.ts, _consts.ts

Files:

  • src/_types.ts
🧠 Learnings (5)
.gitignore (6)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Lint code using ESLint MCP server (available via Claude Code tools)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Constants: can use UPPER_SNAKE_CASE - e.g., DEFAULT_CLAUDE_CODE_PATH

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Model naming convention: Pattern is claude-{model-type}-{generation}-{date} (e.g., claude-sonnet-4-20250514), not claude-4-sonnet-20250514

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Mock data is created using fs-fixture with createFixture() for Claude data directory simulation

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : All test files must use current Claude 4 models, not outdated Claude 3 models

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Format code with ESLint (writes changes) using bun run format

src/calculate-cost.ts (2)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : The application cannot calculate costs for models not supported by LiteLLM

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Cost calculations require exact model name matches with LiteLLM's database

src/_types.ts (1)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Variables: start with lowercase (camelCase) - e.g., usageDataSchema, modelBreakdownSchema

src/commands/index.ts (1)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Lint code using ESLint MCP server (available via Claude Code tools)

src/data-loader.ts (2)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Variables: start with lowercase (camelCase) - e.g., usageDataSchema, modelBreakdownSchema

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : File paths always use Node.js path utilities for cross-platform compatibility

🧬 Code Graph Analysis (2)
src/calculate-cost.ts (1)
src/data-loader.ts (4)
  • DailyUsage (208-208)
  • MonthlyUsage (250-250)
  • WeeklyUsage (270-270)
  • SessionUsage (230-230)
src/data-loader.ts (1)
src/_types.ts (5)
  • weeklyDateSchema (42-45)
  • modelNameSchema (9-11)
  • WeeklyDate (71-71)
  • createWeeklyDate (88-88)
  • ModelName (63-63)
🪛 ESLint
src/_types.ts

[error] 42-45: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 42-45: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 42-44: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 42-43: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 43-43: Unsafe member access .string on an error typed value.

(ts/no-unsafe-member-access)


[error] 44-44: Unsafe member access .regex on an error typed value.

(ts/no-unsafe-member-access)


[error] 45-45: Unsafe member access .brand on an error typed value.

(ts/no-unsafe-member-access)


[error] 88-88: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 88-88: Unsafe member access .parse on an error typed value.

(ts/no-unsafe-member-access)

src/commands/weekly.ts

[error] 15-180: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 15-15: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 20-20: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 20-20: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 21-21: Unsafe member access .level on an error typed value.

(ts/no-unsafe-member-access)


[error] 25-25: Unsafe assignment of an any value.

(ts/no-unsafe-assignment)


[error] 25-25: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 26-26: Unsafe assignment of an any value.

(ts/no-unsafe-assignment)


[error] 26-26: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 27-27: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 28-28: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 29-29: Unsafe assignment of an any value.

(ts/no-unsafe-assignment)


[error] 29-29: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 33-33: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 33-33: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 45-45: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 48-48: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 48-48: Unsafe member access .warn on an error typed value.

(ts/no-unsafe-member-access)


[error] 50-50: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 50-50: Unsafe member access .exit on an error typed value.

(ts/no-unsafe-member-access)


[error] 57-57: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 57-57: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 57-57: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 57-57: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 59-59: Unsafe argument of type any assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 59-59: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 62-62: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 62-62: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 66-66: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 66-66: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 67-67: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 67-67: Unsafe member access .inputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 68-68: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 68-68: Unsafe member access .outputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 69-69: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 69-69: Unsafe member access .cacheCreationTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 70-70: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 70-70: Unsafe member access .cacheReadTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 71-71: Unsafe argument of type error typed assigned to a parameter of type AnyTokenCounts.

(ts/no-unsafe-argument)


[error] 72-72: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 72-72: Unsafe member access .totalCost on an error typed value.

(ts/no-unsafe-member-access)


[error] 73-73: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 73-73: Unsafe member access .modelsUsed on an error typed value.

(ts/no-unsafe-member-access)


[error] 74-74: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 74-74: Unsafe member access .modelBreakdowns on an error typed value.

(ts/no-unsafe-member-access)


[error] 78-78: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 82-82: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 82-82: Unsafe member access .box on an error typed value.

(ts/no-unsafe-member-access)


[error] 130-139: Unsafe argument of type any[] assigned to a parameter of type TableRow.

(ts/no-unsafe-argument)


[error] 131-131: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 132-132: Unsafe argument of type error typed assigned to a parameter of type string[].

(ts/no-unsafe-argument)


[error] 132-132: Unsafe member access .modelsUsed on an error typed value.

(ts/no-unsafe-member-access)


[error] 133-133: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 133-133: Unsafe member access .inputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 134-134: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 134-134: Unsafe member access .outputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 135-135: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 135-135: Unsafe member access .cacheCreationTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 136-136: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 136-136: Unsafe member access .cacheReadTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 137-137: Unsafe argument of type error typed assigned to a parameter of type AnyTokenCounts.

(ts/no-unsafe-argument)


[error] 138-138: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 138-138: Unsafe member access .totalCost on an error typed value.

(ts/no-unsafe-member-access)


[error] 142-142: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 142-142: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 143-143: Unsafe argument of type error typed assigned to a parameter of type { modelName: string; inputTokens: number; outputTokens: number; cacheCreationTokens: number; cacheReadTokens: number; cost: number; }[].

(ts/no-unsafe-argument)


[error] 143-143: Unsafe member access .modelBreakdowns on an error typed value.

(ts/no-unsafe-member-access)


[error] 160-169: Unsafe argument of type any[] assigned to a parameter of type TableRow.

(ts/no-unsafe-argument)


[error] 161-161: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 161-161: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 163-163: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 163-163: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 164-164: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 164-164: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 165-165: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 165-165: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 166-166: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 166-166: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 167-167: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 167-167: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 168-168: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 168-168: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 171-171: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 175-175: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 175-175: Unsafe member access .info on an error typed value.

(ts/no-unsafe-member-access)


[error] 176-176: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 176-176: Unsafe member access .info on an error typed value.

(ts/no-unsafe-member-access)

src/data-loader.ts

[error] 255-265: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 255-255: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 255-255: Unsafe member access .object on an error typed value.

(ts/no-unsafe-member-access)


[error] 256-256: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 257-257: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 257-257: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 257-257: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 258-258: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 258-258: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 258-258: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 259-259: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 259-259: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 259-259: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 260-260: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 260-260: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 260-260: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 261-261: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 261-261: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 261-261: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 262-262: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 262-262: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 262-262: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 263-263: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 263-263: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 263-263: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 264-264: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 264-264: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 264-264: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 264-264: Unsafe member access .string on an error typed value.

(ts/no-unsafe-member-access)


[error] 264-264: Unsafe member access .optional on an error typed value.

(ts/no-unsafe-member-access)


[error] 1180-1180: Unsafe argument of type error typed assigned to a parameter of type string | number | Date.

(ts/no-unsafe-argument)


[error] 1180-1180: Unsafe member access .date on an error typed value.

(ts/no-unsafe-member-access)


[error] 1180-1180: Unsafe member access .project on an error typed value.

(ts/no-unsafe-member-access)


[error] 1181-1181: Unsafe argument of type error typed assigned to a parameter of type string | number | Date.

(ts/no-unsafe-argument)


[error] 1181-1181: Unsafe member access .date on an error typed value.

(ts/no-unsafe-member-access)


[error] 1183-1183: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1183-1183: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1187-1187: Unsafe argument of type error typed assigned to a parameter of type { [s: string]: unknown; } | ArrayLike<unknown>.

(ts/no-unsafe-argument)


[error] 1198-1200: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1198-1198: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1199-1199: Unsafe return of a value of type any.

(ts/no-unsafe-return)


[error] 1199-1199: Unsafe member access .modelBreakdowns on an any value.

(ts/no-unsafe-member-access)


[error] 1201-1201: Unsafe argument of type error typed assigned to a parameter of type z.infer<any>[].

(ts/no-unsafe-argument)


[error] 1209-1209: Unsafe member access .modelsUsed on an any value.

(ts/no-unsafe-member-access)


[error] 1212-1212: Unsafe argument of type any assigned to a parameter of type string.

(ts/no-unsafe-argument)


[error] 1225-1225: Unsafe member access .inputTokens on an any value.

(ts/no-unsafe-member-access)


[error] 1226-1226: Unsafe member access .outputTokens on an any value.

(ts/no-unsafe-member-access)


[error] 1227-1227: Unsafe member access .cacheCreationTokens on an any value.

(ts/no-unsafe-member-access)


[error] 1228-1228: Unsafe member access .cacheReadTokens on an any value.

(ts/no-unsafe-member-access)


[error] 1229-1229: Unsafe member access .totalCost on an any value.

(ts/no-unsafe-member-access)


[error] 1232-1232: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1238-1238: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1247-1247: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)

🔇 Additional comments (20)
.gitignore (1)

40-40: Addition of .vscode directory is appropriate

Ignoring local VS Code settings prevents accidental commits of developer-specific configuration. No further action needed.

src/_types.ts (3)

42-45: LGTM! Consistent with existing date schema patterns.

The weeklyDateSchema follows the same pattern as dailyDateSchema and activityDateSchema, using the YYYY-MM-DD format which is appropriate for representing week start dates.


71-71: LGTM! Type export follows established conventions.

The WeeklyDate type export is consistent with other branded date types in the file.


88-88: LGTM! Helper function follows established pattern.

The createWeeklyDate helper function follows the same pattern as other date creation helpers, providing proper validation and type safety.

src/commands/index.ts (2)

9-9: LGTM! Import follows established pattern.

The import of weeklyCommand is consistent with other command imports in the file.


17-17: LGTM! Command registration follows established pattern.

The weekly command is properly registered in the subCommands map, maintaining consistency with existing commands.

src/calculate-cost.ts (2)

12-12: LGTM! Import addition is appropriate.

Adding WeeklyUsage to the import statement extends the type support for the calculateTotals function.


49-49: LGTM! Type extension follows established pattern.

Extending the calculateTotals function parameter type to include WeeklyUsage is appropriate, as weekly usage data follows the same structure as other usage types with common token count and cost properties.

src/commands/weekly.ts (9)

1-14: LGTM! Imports are well-organized and appropriate.

The imports follow established patterns and include all necessary utilities for the weekly command implementation.


15-18: LGTM! Command definition follows established pattern.

The command definition uses the shared configuration and provides an appropriate description for the weekly usage report.


19-31: LGTM! Data loading logic is consistent with other commands.

The weekly data loading follows the same pattern as other commands, properly passing through the configuration options from the CLI context.


32-51: LGTM! Empty data handling is appropriate.

The empty data scenario is handled correctly with proper JSON output structure and user feedback, maintaining consistency with other commands.


53-61: LGTM! Debug functionality integration is correct.

The debug information integration follows the established pattern used in other commands.


62-79: LGTM! JSON output structure is well-designed.

The JSON output provides comprehensive weekly data with proper token calculations and maintains consistency with other command outputs.


80-126: LGTM! Table configuration supports responsive design.

The responsive table configuration with compact mode support follows established patterns and provides appropriate column headers and alignment for weekly data display.


127-145: LGTM! Data row generation logic is consistent.

The table row generation for weekly data follows the same pattern as other commands, with proper formatting and optional breakdown support.


147-178: LGTM! Totals display and compact mode guidance are appropriate.

The totals row formatting with visual highlighting and compact mode guidance messages follow established patterns and provide good user experience.

src/data-loader.ts (3)

18-18: LGTM!

The WeeklyDate type import follows the established pattern and is correctly placed with other type imports.


48-48: LGTM!

The createWeeklyDate and weeklyDateSchema imports follow the established patterns and are correctly placed with similar utility imports.

Also applies to: 58-58


252-265: Schema definition follows established patterns.

The weeklyUsageSchema correctly mirrors the structure of existing usage schemas (dailyUsageSchema, monthlyUsageSchema) with appropriate field types. The ESLint warnings about "unsafe assignments" are false positives common with Zod schema definitions and can be safely ignored.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/_types.ts (1)

42-45: Consider consolidating redundant date schemas.

The weeklyDateSchema uses the same regex pattern (/^\d{4}-\d{2}-\d{2}$/) as dailyDateSchema and activityDateSchema. While the different branding serves type safety purposes, this creates maintenance overhead with duplicate validation logic.

Consider creating a base schema and reusing it:

+const dateYMDSchema = z.string()
+  .regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be in YYYY-MM-DD format');
+
 export const dailyDateSchema = z.string()
-  .regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be in YYYY-MM-DD format')
+  .pipe(dateYMDSchema)
   .brand<'DailyDate'>();

 export const activityDateSchema = z.string()
-  .regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be in YYYY-MM-DD format')
+  .pipe(dateYMDSchema)
   .brand<'ActivityDate'>();

 export const weeklyDateSchema = z.string()
-  .regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be in YYYY-MM-DD format')
+  .pipe(dateYMDSchema)
   .brand<'WeeklyDate'>();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e7c5ba145852b151b30014272ad0cfee38f8f5d and df2bfb78317e6288825021c4eef096abb771b7ea.

📒 Files selected for processing (3)
  • package.json (1 hunks)
  • src/_types.ts (3 hunks)
  • src/data-loader.ts (9 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
package.json

📄 CodeRabbit Inference Engine (CLAUDE.md)

Dependencies should always be added as devDependencies unless explicitly requested otherwise

Files:

  • package.json
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.{js,jsx,ts,tsx}: Lint code using ESLint MCP server (available via Claude Code tools)
Format code with ESLint (writes changes) using bun run format
No console.log allowed except where explicitly disabled with eslint-disable
Do not use console.log. Use logger.ts instead.

Files:

  • src/data-loader.ts
  • src/_types.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Type check with TypeScript using bun typecheck

Files:

  • src/data-loader.ts
  • src/_types.ts
**/*.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.ts: File paths always use Node.js path utilities for cross-platform compatibility
Use .ts extensions for local file imports (e.g., import { foo } from './utils.ts')
Prefer @praha/byethrow Result type over traditional try-catch for functional error handling
Use Result.try() for wrapping operations that may throw (JSON parsing, etc.)
Use Result.isFailure() for checking errors (more readable than !Result.isSuccess())
Use early return pattern (if (Result.isFailure(result)) continue;) instead of ternary operators
For async operations: create wrapper function with Result.try() then call it
Keep traditional try-catch only for: file I/O with complex error handling, legacy code that's hard to refactor
Always use Result.isFailure() and Result.isSuccess() type guards for better code clarity
Variables: start with lowercase (camelCase) - e.g., usageDataSchema, modelBreakdownSchema
Types: start with uppercase (PascalCase) - e.g., UsageData, ModelBreakdown
Constants: can use UPPER_SNAKE_CASE - e.g., DEFAULT_CLAUDE_CODE_PATH
Only export constants, functions, and types that are actually used by other modules
Internal/private constants that are only used within the same file should NOT be exported
Always check if a constant is used elsewhere before making it export const vs just const
All test files must use current Claude 4 models, not outdated Claude 3 models
Test coverage should include both Sonnet and Opus models for comprehensive validation
Model names in tests must exactly match LiteLLM's pricing database entries
When adding new model tests, verify the model exists in LiteLLM before implementation
Tests depend on real pricing data from LiteLLM - failures may indicate model availability issues
Dynamic imports using await import() should only be used within test blocks to avoid tree-shaking issues
Mock data is created using fs-fixture with createFixture() for Claude data directory simulation
In-source testing pattern: Tests are written...

Files:

  • src/data-loader.ts
  • src/_types.ts
**/_*.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

Internal files: use underscore prefix - e.g., _types.ts, _utils.ts, _consts.ts

Files:

  • src/_types.ts
🧠 Learnings (3)
package.json (4)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Vitest globals (describe, it, expect) are available automatically without imports in test blocks

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : In-source testing pattern: Tests are written directly in the same files as the source code, not in separate test files, using if (import.meta.vitest != null) blocks

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.{ts,tsx} : Type check with TypeScript using bun typecheck

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Format code with ESLint (writes changes) using bun run format

src/data-loader.ts (7)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Variables: start with lowercase (camelCase) - e.g., usageDataSchema, modelBreakdownSchema

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Types: start with uppercase (PascalCase) - e.g., UsageData, ModelBreakdown

Learnt from: AsPulse
PR: #328
File: src/_live-rendering.ts:133-167
Timestamp: 2025-07-20T23:46:21.740Z
Learning: When AsPulse points out that variables are clearly type-inferred as strings from their construction (using template literals, string methods like .toFixed(), .padStart(), etc.), avoid suggesting unnecessary type assertions that would reduce code readability. ESLint type safety errors about "error type" often indicate type definition issues with imported packages rather than actual type problems in the user's code.

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Tests depend on real pricing data from LiteLLM - failures may indicate model availability issues

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Cost calculations require exact model name matches with LiteLLM's database

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Only export constants, functions, and types that are actually used by other modules

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Mock data is created using fs-fixture with createFixture() for Claude data directory simulation

src/_types.ts (1)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Variables: start with lowercase (camelCase) - e.g., usageDataSchema, modelBreakdownSchema

🧬 Code Graph Analysis (1)
src/data-loader.ts (1)
src/_types.ts (9)
  • weeklyDateSchema (42-45)
  • modelNameSchema (9-11)
  • monthlyDateSchema (38-40)
  • createMonthlyDate (88-88)
  • WeeklyDate (71-71)
  • createWeeklyDate (89-89)
  • Bucket (72-72)
  • createBucket (94-99)
  • createISOTimestamp (85-85)
🪛 ESLint
src/data-loader.ts

[error] 257-267: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 257-257: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 257-257: Unsafe member access .object on an error typed value.

(ts/no-unsafe-member-access)


[error] 258-258: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 259-259: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 259-259: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 259-259: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 260-260: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 260-260: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 260-260: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 261-261: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 261-261: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 261-261: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 262-262: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 262-262: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 262-262: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 263-263: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 263-263: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 263-263: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 264-264: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 264-264: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 264-264: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 265-265: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 265-265: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 265-265: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 266-266: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 266-266: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 266-266: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 266-266: Unsafe member access .string on an error typed value.

(ts/no-unsafe-member-access)


[error] 266-266: Unsafe member access .optional on an error typed value.

(ts/no-unsafe-member-access)


[error] 277-287: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 277-277: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 277-277: Unsafe member access .object on an error typed value.

(ts/no-unsafe-member-access)


[error] 278-278: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 278-278: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 278-278: Unsafe member access .union on an error typed value.

(ts/no-unsafe-member-access)


[error] 279-279: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 279-279: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 279-279: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 280-280: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 280-280: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 280-280: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 281-281: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 281-281: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 281-281: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 282-282: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 282-282: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 282-282: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 283-283: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 283-283: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 283-283: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 284-284: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 284-284: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 284-284: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 285-285: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 285-285: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 285-285: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 286-286: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 286-286: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 286-286: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 286-286: Unsafe member access .string on an error typed value.

(ts/no-unsafe-member-access)


[error] 286-286: Unsafe member access .optional on an error typed value.

(ts/no-unsafe-member-access)


[error] 1093-1093: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 1093-1093: Unsafe argument of type error typed assigned to a parameter of type string.

(ts/no-unsafe-argument)


[error] 1093-1093: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1093-1093: Unsafe member access .date on an error typed value.

(ts/no-unsafe-member-access)


[error] 1094-1097: Unsafe return of a value of type any[].

(ts/no-unsafe-return)


[error] 1094-1097: Unsafe return of a value of type any.

(ts/no-unsafe-return)


[error] 1095-1095: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1095-1095: Unsafe argument of type error typed assigned to a parameter of type string.

(ts/no-unsafe-argument)


[error] 1095-1095: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1095-1095: Unsafe member access .toString on an error typed value.

(ts/no-unsafe-member-access)


[error] 1126-1126: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 1126-1126: Unsafe argument of type error typed assigned to a parameter of type string | number | Date.

(ts/no-unsafe-argument)


[error] 1126-1126: Unsafe member access .date on an error typed value.

(ts/no-unsafe-member-access)


[error] 1127-1130: Unsafe return of a value of type any[].

(ts/no-unsafe-return)


[error] 1127-1130: Unsafe return of a value of type any.

(ts/no-unsafe-return)


[error] 1128-1128: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1128-1128: Unsafe argument of type error typed assigned to a parameter of type string.

(ts/no-unsafe-argument)


[error] 1128-1128: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1128-1128: Unsafe member access .toString on an error typed value.

(ts/no-unsafe-member-access)


[error] 1146-1146: Unsafe member access .project on an error typed value.

(ts/no-unsafe-member-access)


[error] 1149-1149: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1149-1149: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1152-1152: Unsafe argument of type error typed assigned to a parameter of type { [s: string]: unknown; } | ArrayLike<unknown>.

(ts/no-unsafe-argument)


[error] 1158-1158: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1162-1164: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1162-1162: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1163-1163: Unsafe return of a value of type any.

(ts/no-unsafe-return)


[error] 1163-1163: Unsafe member access .modelBreakdowns on an any value.

(ts/no-unsafe-member-access)


[error] 1196-1196: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1210-1210: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 1210-1210: Unsafe member access .bucket on an error typed value.

(ts/no-unsafe-member-access)


[error] 2018-2018: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2019-2019: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2022-2022: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2027-2027: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2032-2032: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2038-2046: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2038-2038: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2048-2048: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2048-2048: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2051-2051: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2051-2051: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2051-2051: Unsafe member access .toHaveLength on an error typed value.

(ts/no-unsafe-member-access)


[error] 2052-2052: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2052-2052: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2052-2052: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2069-2069: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2069-2069: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2069-2069: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2088-2088: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2089-2091: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2089-2089: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2093-2093: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2093-2093: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2094-2094: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2094-2094: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2094-2094: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2097-2097: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2100-2100: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2105-2105: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2111-2119: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2111-2111: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2121-2121: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2121-2121: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2123-2123: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2123-2123: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2123-2123: Unsafe member access .toHaveLength on an error typed value.

(ts/no-unsafe-member-access)


[error] 2124-2124: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2124-2124: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2124-2124: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2143-2143: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2146-2146: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2151-2151: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2156-2156: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2161-2161: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2167-2175: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2167-2167: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2177-2177: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2177-2177: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2178-2178: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 2178-2178: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2180-2180: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2180-2180: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2180-2180: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2183-2183: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2186-2186: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2191-2191: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2196-2196: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2201-2201: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2207-2215: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2207-2207: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2217-2217: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2217-2217: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2218-2218: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 2218-2218: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2220-2220: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2220-2220: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2220-2220: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2223-2223: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2226-2226: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2231-2231: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2236-2236: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2241-2241: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2247-2255: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2247-2247: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2259-2259: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2259-2259: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2262-2262: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 2262-2262: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2263-2263: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2263-2263: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2263-2263: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2267-2267: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2267-2267: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2270-2270: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 2270-2270: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2271-2271: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2271-2271: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2271-2271: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2274-2274: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2277-2277: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2282-2282: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2287-2287: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2293-2301: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2293-2293: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2304-2304: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2304-2304: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2310-2310: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2310-2310: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2310-2310: Unsafe member access .toHaveLength on an error typed value.

(ts/no-unsafe-member-access)


[error] 2311-2311: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2311-2311: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2311-2311: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2311-2311: Unsafe member access .toBe on an error typed value.

(ts/no-unsafe-member-access)


[error] 2312-2312: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2312-2312: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2312-2312: Unsafe member access .inputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 2312-2312: Unsafe member access .toBe on an error typed value.

(ts/no-unsafe-member-access)


[error] 2315-2315: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2318-2318: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2330-2330: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2343-2351: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2343-2343: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2353-2353: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2353-2353: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2355-2355: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2355-2355: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2355-2355: Unsafe member access .toHaveLength on an error typed value.

(ts/no-unsafe-member-access)


[error] 2356-2356: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2356-2356: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2356-2356: Unsafe member access .cacheCreationTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 2356-2356: Unsafe member access .toBe on an error typed value.

(ts/no-unsafe-member-access)


[error] 2357-2357: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2357-2357: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2357-2357: Unsafe member access .cacheReadTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 2357-2357: Unsafe member access .toBe on an error typed value.

(ts/no-unsafe-member-access)

src/_types.ts

[error] 42-45: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 42-45: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 42-44: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 42-43: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 43-43: Unsafe member access .string on an error typed value.

(ts/no-unsafe-member-access)


[error] 44-44: Unsafe member access .regex on an error typed value.

(ts/no-unsafe-member-access)


[error] 45-45: Unsafe member access .brand on an error typed value.

(ts/no-unsafe-member-access)


[error] 89-89: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 89-89: Unsafe member access .parse on an error typed value.

(ts/no-unsafe-member-access)


[error] 90-90: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 90-90: Unsafe member access .parse on an error typed value.

(ts/no-unsafe-member-access)


[error] 91-91: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 91-91: Unsafe member access .parse on an error typed value.

(ts/no-unsafe-member-access)


[error] 92-92: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 92-92: Unsafe member access .parse on an error typed value.

(ts/no-unsafe-member-access)


[error] 95-95: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 95-95: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 95-95: Unsafe member access .safeParse on an error typed value.

(ts/no-unsafe-member-access)


[error] 95-95: Unsafe member access .success on an error typed value.

(ts/no-unsafe-member-access)

🔇 Additional comments (7)
package.json (1)

54-54: Good addition of timezone consistency for tests.

Setting TZ=UTC ensures consistent test results across different environments, which is especially important for the new weekly usage features that involve date calculations and timezone-sensitive operations.

src/_types.ts (3)

71-72: LGTM!

The WeeklyDate type and Bucket union type follow established patterns and provide good type safety for the new weekly usage functionality.


89-89: LGTM!

The createWeeklyDate function follows the established pattern for creating branded types from the schema.


94-99: Good implementation of bucket type discrimination.

The createBucket function correctly uses safeParse to attempt weekly format first, then falls back to monthly format. This approach handles the union type creation properly without throwing exceptions during the discrimination process.

src/data-loader.ts (3)

1090-1098: Excellent refactoring to eliminate code duplication!

The delegation to loadBucketUsageData with appropriate type transformations is clean and maintains type safety while eliminating the previously duplicated aggregation logic.


1133-1211: Well-designed generic aggregation function!

The loadBucketUsageData successfully eliminates code duplication between weekly and monthly aggregation while maintaining type safety. The sorting logic correctly uses the bucket dates directly, addressing the previous concern about incorrect date formatting.


2018-2359: Comprehensive test coverage for weekly usage functionality!

The tests thoroughly cover all aspects of weekly aggregation including edge cases like year boundaries, date filtering, and cache token handling. This addresses the previous concern about missing tests.

@juicemia juicemia force-pushed the add-weekly-usage-command branch from df2bfb7 to 8eb5992 Compare July 29, 2025 17:33
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/data-loader.ts (1)

1107-1121: Fix JSDoc comment to accurately describe return value.

The function implementation is correct, but the JSDoc comment is misleading as noted in previous reviews.

 /**
+ * Gets the start date (Monday) of the week containing the given date
  * @param date - The date to get the week for
- * @returns The week of the year in which the given date falls into
+ * @returns The date of the Monday of the week containing the given date (YYYY-MM-DD format)
  */
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df2bfb78317e6288825021c4eef096abb771b7ea and 8eb599224ceed0ca5ce488cbaf1c4708b3b1275a.

📒 Files selected for processing (7)
  • .gitignore (1 hunks)
  • package.json (1 hunks)
  • src/_types.ts (3 hunks)
  • src/calculate-cost.ts (2 hunks)
  • src/commands/index.ts (1 hunks)
  • src/commands/weekly.ts (1 hunks)
  • src/data-loader.ts (9 hunks)
✅ Files skipped from review due to trivial changes (1)
  • package.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/calculate-cost.ts
  • src/commands/index.ts
  • .gitignore
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.{js,jsx,ts,tsx}: Lint code using ESLint MCP server (available via Claude Code tools)
Format code with ESLint (writes changes) using bun run format
No console.log allowed except where explicitly disabled with eslint-disable
Do not use console.log. Use logger.ts instead.

Files:

  • src/data-loader.ts
  • src/_types.ts
  • src/commands/weekly.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Type check with TypeScript using bun typecheck

Files:

  • src/data-loader.ts
  • src/_types.ts
  • src/commands/weekly.ts
**/*.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.ts: File paths always use Node.js path utilities for cross-platform compatibility
Use .ts extensions for local file imports (e.g., import { foo } from './utils.ts')
Prefer @praha/byethrow Result type over traditional try-catch for functional error handling
Use Result.try() for wrapping operations that may throw (JSON parsing, etc.)
Use Result.isFailure() for checking errors (more readable than !Result.isSuccess())
Use early return pattern (if (Result.isFailure(result)) continue;) instead of ternary operators
For async operations: create wrapper function with Result.try() then call it
Keep traditional try-catch only for: file I/O with complex error handling, legacy code that's hard to refactor
Always use Result.isFailure() and Result.isSuccess() type guards for better code clarity
Variables: start with lowercase (camelCase) - e.g., usageDataSchema, modelBreakdownSchema
Types: start with uppercase (PascalCase) - e.g., UsageData, ModelBreakdown
Constants: can use UPPER_SNAKE_CASE - e.g., DEFAULT_CLAUDE_CODE_PATH
Only export constants, functions, and types that are actually used by other modules
Internal/private constants that are only used within the same file should NOT be exported
Always check if a constant is used elsewhere before making it export const vs just const
All test files must use current Claude 4 models, not outdated Claude 3 models
Test coverage should include both Sonnet and Opus models for comprehensive validation
Model names in tests must exactly match LiteLLM's pricing database entries
When adding new model tests, verify the model exists in LiteLLM before implementation
Tests depend on real pricing data from LiteLLM - failures may indicate model availability issues
Dynamic imports using await import() should only be used within test blocks to avoid tree-shaking issues
Mock data is created using fs-fixture with createFixture() for Claude data directory simulation
In-source testing pattern: Tests are written...

Files:

  • src/data-loader.ts
  • src/_types.ts
  • src/commands/weekly.ts
**/_*.ts

📄 CodeRabbit Inference Engine (CLAUDE.md)

Internal files: use underscore prefix - e.g., _types.ts, _utils.ts, _consts.ts

Files:

  • src/_types.ts
🧠 Learnings (2)
src/data-loader.ts (6)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Variables: start with lowercase (camelCase) - e.g., usageDataSchema, modelBreakdownSchema

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Types: start with uppercase (PascalCase) - e.g., UsageData, ModelBreakdown

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Tests depend on real pricing data from LiteLLM - failures may indicate model availability issues

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Cost calculations require exact model name matches with LiteLLM's database

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Only export constants, functions, and types that are actually used by other modules

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Mock data is created using fs-fixture with createFixture() for Claude data directory simulation

src/_types.ts (1)

Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-19T10:58:04.397Z
Learning: Applies to **/*.ts : Variables: start with lowercase (camelCase) - e.g., usageDataSchema, modelBreakdownSchema

🧬 Code Graph Analysis (1)
src/data-loader.ts (1)
src/_types.ts (9)
  • weeklyDateSchema (42-45)
  • modelNameSchema (9-11)
  • monthlyDateSchema (38-40)
  • createMonthlyDate (88-88)
  • WeeklyDate (71-71)
  • createWeeklyDate (89-89)
  • Bucket (72-72)
  • createBucket (94-99)
  • createISOTimestamp (85-85)
🪛 ESLint
src/data-loader.ts

[error] 257-267: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 257-257: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 257-257: Unsafe member access .object on an error typed value.

(ts/no-unsafe-member-access)


[error] 258-258: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 259-259: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 259-259: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 259-259: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 260-260: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 260-260: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 260-260: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 261-261: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 261-261: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 261-261: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 262-262: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 262-262: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 262-262: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 263-263: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 263-263: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 263-263: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 264-264: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 264-264: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 264-264: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 265-265: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 265-265: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 265-265: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 266-266: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 266-266: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 266-266: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 266-266: Unsafe member access .string on an error typed value.

(ts/no-unsafe-member-access)


[error] 266-266: Unsafe member access .optional on an error typed value.

(ts/no-unsafe-member-access)


[error] 277-287: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 277-277: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 277-277: Unsafe member access .object on an error typed value.

(ts/no-unsafe-member-access)


[error] 278-278: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 278-278: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 278-278: Unsafe member access .union on an error typed value.

(ts/no-unsafe-member-access)


[error] 279-279: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 279-279: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 279-279: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 280-280: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 280-280: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 280-280: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 281-281: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 281-281: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 281-281: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 282-282: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 282-282: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 282-282: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 283-283: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 283-283: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 283-283: Unsafe member access .number on an error typed value.

(ts/no-unsafe-member-access)


[error] 284-284: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 284-284: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 284-284: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 285-285: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 285-285: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 285-285: Unsafe member access .array on an error typed value.

(ts/no-unsafe-member-access)


[error] 286-286: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 286-286: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 286-286: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 286-286: Unsafe member access .string on an error typed value.

(ts/no-unsafe-member-access)


[error] 286-286: Unsafe member access .optional on an error typed value.

(ts/no-unsafe-member-access)


[error] 1093-1093: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 1093-1093: Unsafe argument of type error typed assigned to a parameter of type string.

(ts/no-unsafe-argument)


[error] 1093-1093: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1093-1093: Unsafe member access .date on an error typed value.

(ts/no-unsafe-member-access)


[error] 1094-1097: Unsafe return of a value of type any[].

(ts/no-unsafe-return)


[error] 1094-1097: Unsafe return of a value of type any.

(ts/no-unsafe-return)


[error] 1095-1095: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1095-1095: Unsafe argument of type error typed assigned to a parameter of type string.

(ts/no-unsafe-argument)


[error] 1095-1095: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1095-1095: Unsafe member access .toString on an error typed value.

(ts/no-unsafe-member-access)


[error] 1126-1126: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 1126-1126: Unsafe argument of type error typed assigned to a parameter of type string | number | Date.

(ts/no-unsafe-argument)


[error] 1126-1126: Unsafe member access .date on an error typed value.

(ts/no-unsafe-member-access)


[error] 1127-1130: Unsafe return of a value of type any[].

(ts/no-unsafe-return)


[error] 1127-1130: Unsafe return of a value of type any.

(ts/no-unsafe-return)


[error] 1128-1128: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1128-1128: Unsafe argument of type error typed assigned to a parameter of type string.

(ts/no-unsafe-argument)


[error] 1128-1128: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1128-1128: Unsafe member access .toString on an error typed value.

(ts/no-unsafe-member-access)


[error] 1146-1146: Unsafe member access .project on an error typed value.

(ts/no-unsafe-member-access)


[error] 1149-1149: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1149-1149: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1152-1152: Unsafe argument of type error typed assigned to a parameter of type { [s: string]: unknown; } | ArrayLike<unknown>.

(ts/no-unsafe-argument)


[error] 1158-1158: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1162-1164: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1162-1162: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 1163-1163: Unsafe return of a value of type any.

(ts/no-unsafe-return)


[error] 1163-1163: Unsafe member access .modelBreakdowns on an any value.

(ts/no-unsafe-member-access)


[error] 1196-1196: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 1210-1210: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 1210-1210: Unsafe member access .bucket on an error typed value.

(ts/no-unsafe-member-access)


[error] 2018-2018: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2019-2019: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2022-2022: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2027-2027: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2032-2032: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2038-2046: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2038-2038: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2048-2048: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2048-2048: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2051-2051: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2051-2051: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2051-2051: Unsafe member access .toHaveLength on an error typed value.

(ts/no-unsafe-member-access)


[error] 2052-2052: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2052-2052: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2052-2052: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2069-2069: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2069-2069: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2069-2069: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2088-2088: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2089-2091: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2089-2089: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2093-2093: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2093-2093: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2094-2094: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2094-2094: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2094-2094: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2097-2097: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2100-2100: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2105-2105: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2111-2119: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2111-2111: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2121-2121: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2121-2121: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2123-2123: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2123-2123: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2123-2123: Unsafe member access .toHaveLength on an error typed value.

(ts/no-unsafe-member-access)


[error] 2124-2124: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2124-2124: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2124-2124: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2143-2143: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2146-2146: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2151-2151: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2156-2156: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2161-2161: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2167-2175: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2167-2167: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2177-2177: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2177-2177: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2178-2178: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 2178-2178: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2180-2180: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2180-2180: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2180-2180: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2183-2183: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2186-2186: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2191-2191: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2196-2196: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2201-2201: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2207-2215: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2207-2207: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2217-2217: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2217-2217: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2218-2218: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 2218-2218: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2220-2220: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2220-2220: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2220-2220: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2223-2223: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2226-2226: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2231-2231: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2236-2236: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2241-2241: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2247-2255: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2247-2247: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2259-2259: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2259-2259: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2262-2262: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 2262-2262: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2263-2263: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2263-2263: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2263-2263: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2267-2267: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2267-2267: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2270-2270: Unsafe return of a value of type error.

(ts/no-unsafe-return)


[error] 2270-2270: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2271-2271: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2271-2271: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2271-2271: Unsafe member access .toEqual on an error typed value.

(ts/no-unsafe-member-access)


[error] 2274-2274: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2277-2277: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2282-2282: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2287-2287: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2293-2301: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2293-2293: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2304-2304: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2304-2304: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2310-2310: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2310-2310: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2310-2310: Unsafe member access .toHaveLength on an error typed value.

(ts/no-unsafe-member-access)


[error] 2311-2311: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2311-2311: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2311-2311: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 2311-2311: Unsafe member access .toBe on an error typed value.

(ts/no-unsafe-member-access)


[error] 2312-2312: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2312-2312: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2312-2312: Unsafe member access .inputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 2312-2312: Unsafe member access .toBe on an error typed value.

(ts/no-unsafe-member-access)


[error] 2315-2315: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2318-2318: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2330-2330: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2343-2351: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2343-2343: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2353-2353: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 2353-2353: Unsafe member access .path on an error typed value.

(ts/no-unsafe-member-access)


[error] 2355-2355: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2355-2355: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2355-2355: Unsafe member access .toHaveLength on an error typed value.

(ts/no-unsafe-member-access)


[error] 2356-2356: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2356-2356: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2356-2356: Unsafe member access .cacheCreationTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 2356-2356: Unsafe member access .toBe on an error typed value.

(ts/no-unsafe-member-access)


[error] 2357-2357: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2357-2357: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 2357-2357: Unsafe member access .cacheReadTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 2357-2357: Unsafe member access .toBe on an error typed value.

(ts/no-unsafe-member-access)

src/_types.ts

[error] 42-45: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 42-45: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 42-44: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 42-43: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 43-43: Unsafe member access .string on an error typed value.

(ts/no-unsafe-member-access)


[error] 44-44: Unsafe member access .regex on an error typed value.

(ts/no-unsafe-member-access)


[error] 45-45: Unsafe member access .brand on an error typed value.

(ts/no-unsafe-member-access)


[error] 89-89: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 89-89: Unsafe member access .parse on an error typed value.

(ts/no-unsafe-member-access)


[error] 90-90: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 90-90: Unsafe member access .parse on an error typed value.

(ts/no-unsafe-member-access)


[error] 91-91: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 91-91: Unsafe member access .parse on an error typed value.

(ts/no-unsafe-member-access)


[error] 92-92: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 92-92: Unsafe member access .parse on an error typed value.

(ts/no-unsafe-member-access)


[error] 95-95: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 95-95: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 95-95: Unsafe member access .safeParse on an error typed value.

(ts/no-unsafe-member-access)


[error] 95-95: Unsafe member access .success on an error typed value.

(ts/no-unsafe-member-access)

src/commands/weekly.ts

[error] 15-180: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 15-15: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 20-20: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 20-20: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 21-21: Unsafe member access .level on an error typed value.

(ts/no-unsafe-member-access)


[error] 25-25: Unsafe assignment of an any value.

(ts/no-unsafe-assignment)


[error] 25-25: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 26-26: Unsafe assignment of an any value.

(ts/no-unsafe-assignment)


[error] 26-26: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 27-27: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 28-28: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 29-29: Unsafe assignment of an any value.

(ts/no-unsafe-assignment)


[error] 29-29: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 33-33: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 33-33: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 45-45: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 48-48: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 48-48: Unsafe member access .warn on an error typed value.

(ts/no-unsafe-member-access)


[error] 50-50: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 50-50: Unsafe member access .exit on an error typed value.

(ts/no-unsafe-member-access)


[error] 57-57: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 57-57: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 57-57: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 57-57: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 59-59: Unsafe argument of type any assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 59-59: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 62-62: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 62-62: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 66-66: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 66-66: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 67-67: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 67-67: Unsafe member access .inputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 68-68: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 68-68: Unsafe member access .outputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 69-69: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 69-69: Unsafe member access .cacheCreationTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 70-70: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 70-70: Unsafe member access .cacheReadTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 71-71: Unsafe argument of type error typed assigned to a parameter of type AnyTokenCounts.

(ts/no-unsafe-argument)


[error] 72-72: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 72-72: Unsafe member access .totalCost on an error typed value.

(ts/no-unsafe-member-access)


[error] 73-73: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 73-73: Unsafe member access .modelsUsed on an error typed value.

(ts/no-unsafe-member-access)


[error] 74-74: Unsafe assignment of an error typed value.

(ts/no-unsafe-assignment)


[error] 74-74: Unsafe member access .modelBreakdowns on an error typed value.

(ts/no-unsafe-member-access)


[error] 78-78: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 82-82: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 82-82: Unsafe member access .box on an error typed value.

(ts/no-unsafe-member-access)


[error] 130-139: Unsafe argument of type any[] assigned to a parameter of type TableRow.

(ts/no-unsafe-argument)


[error] 131-131: Unsafe member access .week on an error typed value.

(ts/no-unsafe-member-access)


[error] 132-132: Unsafe argument of type error typed assigned to a parameter of type string[].

(ts/no-unsafe-argument)


[error] 132-132: Unsafe member access .modelsUsed on an error typed value.

(ts/no-unsafe-member-access)


[error] 133-133: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 133-133: Unsafe member access .inputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 134-134: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 134-134: Unsafe member access .outputTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 135-135: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 135-135: Unsafe member access .cacheCreationTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 136-136: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 136-136: Unsafe member access .cacheReadTokens on an error typed value.

(ts/no-unsafe-member-access)


[error] 137-137: Unsafe argument of type error typed assigned to a parameter of type AnyTokenCounts.

(ts/no-unsafe-argument)


[error] 138-138: Unsafe argument of type error typed assigned to a parameter of type number.

(ts/no-unsafe-argument)


[error] 138-138: Unsafe member access .totalCost on an error typed value.

(ts/no-unsafe-member-access)


[error] 142-142: Unexpected any value in conditional. An explicit comparison or type conversion is required.

(ts/strict-boolean-expressions)


[error] 142-142: Unsafe member access .values on an any value.

(ts/no-unsafe-member-access)


[error] 143-143: Unsafe argument of type error typed assigned to a parameter of type { modelName: string; inputTokens: number; outputTokens: number; cacheCreationTokens: number; cacheReadTokens: number; cost: number; }[].

(ts/no-unsafe-argument)


[error] 143-143: Unsafe member access .modelBreakdowns on an error typed value.

(ts/no-unsafe-member-access)


[error] 160-169: Unsafe argument of type any[] assigned to a parameter of type TableRow.

(ts/no-unsafe-argument)


[error] 161-161: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 161-161: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 163-163: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 163-163: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 164-164: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 164-164: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 165-165: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 165-165: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 166-166: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 166-166: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 167-167: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 167-167: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 168-168: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 168-168: Unsafe member access .yellow on an error typed value.

(ts/no-unsafe-member-access)


[error] 171-171: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 175-175: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 175-175: Unsafe member access .info on an error typed value.

(ts/no-unsafe-member-access)


[error] 176-176: Unsafe call of a(n) error type typed value.

(ts/no-unsafe-call)


[error] 176-176: Unsafe member access .info on an error typed value.

(ts/no-unsafe-member-access)

🔇 Additional comments (18)
src/_types.ts (4)

42-45: LGTM! WeeklyDate schema follows established patterns.

The weeklyDateSchema is correctly implemented using the same pattern as other date schemas in the file, with appropriate regex validation and branding.


71-72: Well-designed type definitions for weekly usage.

The WeeklyDate type inference and Bucket union type are clean and will enable flexible handling of both monthly and weekly data aggregation.


89-89: Helper function follows established pattern.

The createWeeklyDate function maintains consistency with other create functions in the file.


94-99: Smart bucket creation logic with appropriate fallback.

The createBucket function intelligently attempts to parse as WeeklyDate first, then falls back to MonthlyDate. The use of safeParse prevents exceptions and allows graceful type determination.

src/commands/weekly.ts (8)

15-19: Command definition follows established patterns.

The command structure and configuration properly extend the shared command config and follow the same pattern as other commands in the codebase.


24-30: Proper data loading with comprehensive options.

The weekly data loading correctly passes through all the command options (since, until, mode, order, offline) to the data loader function.


32-51: Excellent empty data handling for both output formats.

The implementation provides appropriate responses for both JSON and interactive modes when no data is found, with a well-structured empty JSON response and user-friendly warning message.


62-78: Well-structured JSON output format.

The JSON serialization includes all relevant weekly data fields and totals, providing a comprehensive machine-readable format that matches the expected structure.


84-125: Comprehensive responsive table configuration.

The table setup includes proper column alignment, responsive design with compact mode, and clear headers. The compact threshold and alternative column set provide good user experience across different terminal sizes.


127-145: Proper data presentation with optional breakdown.

The table population correctly formats all data fields and conditionally includes model breakdown rows when requested, following the established pattern from other commands.


159-169: Clear totals presentation with visual highlighting.

The totals row uses consistent formatting and color highlighting to distinguish it from the data rows, providing clear summary information.


173-177: Helpful user guidance for compact mode.

The guidance message helps users understand when they're in compact mode and how to see additional metrics, improving the user experience.

src/data-loader.ts (6)

254-292: LGTM! Well-structured schema definitions.

The new weekly and bucket usage schemas follow the established patterns and naming conventions perfectly. The bucketUsageSchema provides a clean abstraction for handling both weekly and monthly aggregation, which supports the generic approach implemented in loadBucketUsageData.


1090-1098: Excellent refactoring that eliminates code duplication.

This refactoring successfully addresses the code duplication concern raised in previous reviews by leveraging the new generic loadBucketUsageData function. The transformation from BucketUsage to MonthlyUsage is clean and maintains the same interface for consumers.


1100-1106: Week start configuration is clear and well-documented.

The code correctly implements Monday as the start of the week, and the comments clearly explain the uncertainty about Anthropic's billing cycle. This addresses the contradiction mentioned in previous reviews between the code and PR description.


1123-1131: Clean implementation of weekly usage aggregation.

The function follows the same pattern as the refactored loadMonthlyUsageData, providing consistent behavior and interface. The use of getDateWeek as the grouping function correctly groups daily data by Monday-based weeks.


1133-1211: Excellent generic implementation that eliminates code duplication.

This function successfully generalizes the aggregation logic that was previously duplicated between monthly and weekly aggregation. The design is clean and flexible, allowing different grouping strategies via the groupingFn parameter.

The ESLint "unsafe" warnings are false positives due to TypeScript's limitations with complex type inference in the aggregation logic - similar to what exists in other aggregation functions in this codebase.

The sorting logic on line 1210 is now correct, directly using item.bucket without any problematic string manipulation that was mentioned in previous reviews.


2018-2359: Comprehensive test coverage addresses previous feedback.

Excellent test suite that addresses the concern from previous reviews about missing tests for weekly functionality. The tests cover all important scenarios including:

  • Basic weekly aggregation
  • Edge cases (empty data, single week, year boundaries)
  • Sorting behavior (ascending/descending)
  • Date filtering
  • Cache token handling

The tests follow established patterns and use current Claude 4 model names as required by the coding guidelines.

@dv8silencer
Copy link

(Question regarding how Anthropic actually does it)
Question -- is it like the 5 hour thing where the 5 hour window starts the first time you use it (or at least that is what I've seen people say about the 5hr window)? So the "week" usage "metering" would start whenever the user first starts using Claude? Or does it start at a particular calendar time? If I started for the first time on Wednesday for example, then I wonder if it 7*24 hours from then.

@juicemia
Copy link
Contributor Author

That's a good question. I honestly don't know. I figured they would just do it by the first day of the week. But if they already do the 5 hour window from when you start there's no reason to think they can't do it for the weekly window as well. I'll try to find more information.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jul 30, 2025

Open in StackBlitz

npm i https://pkg.pr.new/ryoppippi/ccusage@378

commit: 5e16ab5

package.json Outdated
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏

@juicemia
Copy link
Contributor Author

juicemia commented Jul 30, 2025

@dv8silencer I asked Perplexity.

If the universal weekly limit window is set to start on Wednesdays (the rollout date), your counter would reset every Wednesday at a fixed time for all users, not the day you personally began using Claude.

Perplexity seems to think it's going to be based on the start day they roll it out. I hadn't thought of that but now it seems to me like that's most likely how they would do it because it seems like the simplest way to do it on their side. I'm gonna update the implementation to go based on that.

@juicemia juicemia force-pushed the add-weekly-usage-command branch from 9511618 to 7a7b0de Compare July 31, 2025 13:59
@socket-security
Copy link

socket-security bot commented Jul 31, 2025

*/
function getDateWeek(date: Date): WeeklyDate {
// Anthropic is rolling this out on August 28, 2025. We're assuming that's when the
// weekly window is starting. Using Luxon here allows the code to easily account for
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

luxon is too large,
we need alternative

.gitignore Outdated

.eslintcache

.vscode
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stop adding .vscode here wtf

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to future travelers: add .vscode/ to your .git/info/exclude file -- that way we don't pollute gitignores with ide-specific stuff.

- Add --start-of-week/-w flag to weekly command with default of Thursday

- Update getDateWeek function to accept configurable start day parameter

- Add type-fest dependency for better TypeScript utility types

- Use ValueOf and satisfies for improved type safety

- Remove Luxon dependency to reduce bundle size by ~50KB
- Change default start of week from Thursday to Sunday

- Extract getDayNumber function for better code organization

- Move dayNameToNumber mapping to module level as const

- Use getDayNumber("sunday") instead of magic number 0
- Define DayOfWeek type as IntRange<0, 7> for day number validation

- Update getDayNumber return type to use DayOfWeek

- Update getDateWeek parameter type to use DayOfWeek

- Improve type safety by restricting day numbers to valid range
- Move WEEK_DAYS to _consts.ts to avoid duplication

- Update imports in weekly.ts and data-loader.ts

- Use typeof WEEK_DAYS[number] for WeekDay type definition
- Use typeof WEEK_DAYS["length"] instead of hardcoded 7

- Automatically adjust type range if days are added/removed

- Improve maintainability and reduce magic numbers
- Replace typeof WEEK_DAYS[number] with TupleToUnion<typeof WEEK_DAYS>

- Leverage type-fest utility for more explicit type transformation
Copy link
Owner

@ryoppippi ryoppippi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ryoppippi ryoppippi merged commit 84865a6 into ryoppippi:main Aug 3, 2025
2 of 3 checks passed
ryoppippi added a commit that referenced this pull request Aug 3, 2025
- Add weekly reports to introduction page feature list

- Create dedicated weekly-reports.md guide page with full command documentation

- Update homepage to include weekly reports feature card

- Add weekly reports to getting started next steps

- Update navigation sidebar to include weekly reports link

The weekly command was added in #378 but documentation was missing.

This adds complete documentation covering all features and options.
ryoppippi added a commit that referenced this pull request Aug 3, 2025
- Add weekly reports to introduction page feature list

- Create dedicated weekly-reports.md guide page with full command documentation

- Update homepage to include weekly reports feature card

- Add weekly reports to getting started next steps

- Update navigation sidebar to include weekly reports link

The weekly command was added in #378 but documentation was missing.

This adds complete documentation covering all features and options.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants