Skip to content

Conversation

@ryoppippi
Copy link
Owner

@ryoppippi ryoppippi commented Jun 17, 2025

Summary

  • Added --session-length (-l) option to customize session block duration in hours
  • Default remains 5 hours for backward compatibility
  • Supports any positive number of hours (including decimals like 2.5)
  • Added validation to ensure session length is positive
  • Comprehensive test coverage for various duration scenarios

Changes Made

Core Implementation

  • session-blocks.internal.ts: Made session duration configurable by updating identifySessionBlocks() to accept optional sessionDurationHours parameter
  • data-loader.ts: Added sessionDurationHours to LoadOptions and passed through to session block identification
  • blocks.ts: Added CLI option with validation and help text

Testing

  • Added 9 comprehensive tests covering custom durations (1h, 2h, 2.5h, 3h, 24h, 0.5h)
  • Tests verify correct block creation, gap detection, and timing
  • Edge cases covered: fractional hours, exactly equal durations, backward compatibility

Validation

  • Input validation ensures positive session lengths
  • All existing functionality preserved (164 tests pass)
  • Code formatted and type-checked

Usage Examples

Default 5-hour sessions (backward compatible):
bun run start blocks

Custom 3-hour sessions:
bun run start blocks --session-length 3

Short 1-hour sessions for fine-grained tracking:
bun run start blocks -l 1

Fractional hours:
bun run start blocks --session-length 2.5

Works with all existing options:
bun run start blocks --session-length 8 --recent --json

Test Plan

  • ✅ Run bun test - all 164 tests pass
  • ✅ Test blocks command with default duration
  • ✅ Test with custom duration and fractional hours
  • ✅ Verify gap detection works with custom durations
  • ✅ Test edge cases (very small/large durations)
  • ✅ Run linting and type checking
  • ✅ Test validation with invalid values
  • ✅ Verify JSON output includes correct timing
  • ✅ Test table display shows correct durations

Implementation Notes

The feature correctly handles:

  • Gap Detection: Gaps created only when time between entries exceeds custom session duration
  • Block Timing: End times are exactly sessionDurationHours after start times
  • Active Blocks: Properly calculates remaining time based on custom duration
  • JSON Output: Includes correct timing information in API responses
  • Table Display: Shows correct durations and remaining time in CLI tables

Full backward compatibility maintained while providing flexibility for different use cases.

Summary by CodeRabbit

  • New Features
    • Added a command-line option to customize the session block duration in hours.
  • Bug Fixes
    • Improved validation for session duration input to ensure only positive values are accepted.
  • Tests
    • Introduced comprehensive tests to verify correct grouping of session blocks with various session durations.
  • Documentation
    • Updated descriptions and help text to reflect the new configurable session duration option.

- Add DEFAULT_SESSION_DURATION_HOURS constant (5 hours)
- Update identifySessionBlocks to accept optional sessionDurationHours parameter
- Update createBlock and createGapBlock to use configurable duration
- Add sessionDurationHours to LoadOptions type in data-loader
- Pass session duration through loadSessionBlockData to identifySessionBlocks

This change maintains backward compatibility by using 5 hours as the default
session duration when no custom value is provided.
- Test custom session durations (1h, 2h, 2.5h, 3h, 24h, 0.5h)
- Test gap block creation with custom durations
- Test edge cases (exactly equal durations, fractional hours)
- Test backward compatibility (default 5h behavior)
- All tests verify correct block creation, gap detection, and timing

Covers various scenarios to ensure robust session block identification
with configurable durations across different time ranges.
@coderabbitai
Copy link

coderabbitai bot commented Jun 17, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

A configurable session duration parameter was introduced, allowing the session block duration to be specified via a command-line argument. This parameter propagates through the command, data loading, and session block identification logic, replacing the previously hardcoded 5-hour duration. Comprehensive tests were added to verify correct behavior with various durations.

Changes

File(s) Change Summary
src/commands/blocks.ts Added sessionLength CLI argument; validates and passes it as sessionDurationHours downstream.
src/data-loader.ts Added optional sessionDurationHours to LoadOptions and passes it to session block logic.
src/session-blocks.internal.ts Made session duration configurable; updated logic to use parameter throughout block computation.
src/session-blocks.internal.test.ts Added tests for custom session durations, verifying block and gap creation under various scenarios.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI (blocksCommand)
    participant DataLoader
    participant SessionBlocks

    User->>CLI (blocksCommand): Run with --sessionLength/-l argument
    CLI (blocksCommand)->>DataLoader: loadSessionBlockData({ sessionDurationHours })
    DataLoader->>SessionBlocks: identifySessionBlocks(entries, sessionDurationHours)
    SessionBlocks-->>DataLoader: SessionBlock[]
    DataLoader-->>CLI (blocksCommand): SessionBlock[]
    CLI (blocksCommand)-->>User: Output session block data
Loading

Possibly related PRs

  • ryoppippi/ccusage#80: Introduced the initial 5-hour blocks command and fixed-duration block processing, which this PR extends by making the duration configurable.

Poem

A session can now be long or short,
Five hours fixed? No longer the sort!
With a hop and a skip, the rabbit now knows,
To group your blocks as your custom time flows.
🕰️🐇
Hooray for sessions, flexible and new—
The code now listens to you!


📜 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 671bb42 and e10c9e4.

📒 Files selected for processing (4)
  • src/commands/blocks.ts (2 hunks)
  • src/data-loader.ts (2 hunks)
  • src/session-blocks.internal.test.ts (1 hunks)
  • src/session-blocks.internal.ts (5 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings

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 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.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jun 17, 2025

Open in StackBlitz

npm i https://pkg.pr.new/ryoppippi/ccusage@92

commit: e10c9e4

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 @ryoppippi, 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 significant enhancement to the blocks command by making the session block duration configurable. Previously fixed at 5 hours, users can now define custom session lengths via a new CLI option, providing greater flexibility for analyzing usage data. This change impacts how usage entries are grouped into sessions and how idle periods are identified as gaps, while maintaining full backward compatibility with the default 5-hour duration.

Highlights

  • Configurable Session Length: Added a new --session-length (or -l) CLI option to the blocks command, allowing users to specify the duration of a session block in hours. This option supports any positive number, including decimals, with a default of 5 hours for backward compatibility.
  • Input Validation: Implemented robust input validation for the new sessionLength option, ensuring that only positive numerical values are accepted, and providing an error message if an invalid value is provided.
  • Core Logic Adaptation: Updated the underlying identifySessionBlocks function and its helpers (createBlock, createGapBlock) to dynamically use the configured session duration. This change impacts how usage entries are grouped into sessions, how block end times are calculated, and how idle periods are identified as gaps.
  • Comprehensive Test Coverage: Expanded the test suite with 9 new comprehensive tests specifically for the configurable session duration. These tests cover various scenarios, including different custom durations (e.g., 1h, 2.5h, 24h), fractional hours, and edge cases like exact duration matches and default behavior, ensuring the feature works as expected.
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 is currently in preview and 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 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.

@ryoppippi ryoppippi requested a review from Copilot June 17, 2025 18:13
@ryoppippi ryoppippi merged commit f67f7eb into main Jun 17, 2025
9 of 10 checks passed
@ryoppippi ryoppippi deleted the session-length branch June 17, 2025 18:13
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 adds a configurable session length to the blocks command. The changes are well-implemented, and the addition of comprehensive unit tests is commendable. A few minor areas for potential code clarification were identified.

Comment on lines +129 to +132
if (ctx.values.sessionLength <= 0) {
logger.error('Session length must be a positive number');
process.exit(1);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Consider using gunshi's built-in mechanisms for argument validation, such as specifying a minimum value for the sessionLength option. This could lead to more standardized error messages and cleaner code.

function createBlock(startTime: Date, entries: LoadedUsageEntry[], now: Date, sessionDurationMs: number): SessionBlock {
const endTime = new Date(startTime.getTime() + sessionDurationMs);
const lastEntry = entries[entries.length - 1];
const actualEndTime = lastEntry != null ? lastEntry.timestamp : startTime;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The fallback to startTime in const actualEndTime = lastEntry != null ? lastEntry.timestamp : startTime; seems unnecessary, as lastEntry should never be null here. Simplify this to const actualEndTime = lastEntry!.timestamp;.

Suggested change
const actualEndTime = lastEntry != null ? lastEntry.timestamp : startTime;
const actualEndTime = lastEntry!.timestamp; // entries array is guaranteed to be non-empty here

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a configurable session duration for the blocks command, allowing users to override the default 5-hour window.

  • Updated core logic in identifySessionBlocks and related helpers to accept a sessionDurationHours parameter and compute durations in milliseconds.
  • Propagated the new sessionDurationHours option through the data loader and CLI (--session-length), including validation.
  • Added extensive tests covering custom durations (including fractional hours), gap detection, and backward compatibility.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/session-blocks.internal.ts Refactored identifySessionBlocks, createBlock, and createGapBlock to accept and use a configurable duration parameter.
src/session-blocks.internal.test.ts Added a new test suite verifying behavior for various custom session lengths and edge cases.
src/data-loader.ts Extended LoadOptions with sessionDurationHours and passed it into identifySessionBlocks.
src/commands/blocks.ts Introduced the --session-length (-l) CLI flag, defaulting to 5h, with validation.
Comments suppressed due to low confidence (2)

src/commands/blocks.ts:115

  • [nitpick] The CLI option is named sessionLength, but the internal API parameter is sessionDurationHours. Consider renaming the flag and context variables to match (sessionDurationHours) for clearer alignment between layers.
		sessionLength: {

src/commands/blocks.ts:130

  • [nitpick] This error message could be more user-friendly by naming the specific flag, e.g., Invalid value for --session-length: must be a positive number, so users know exactly which input failed.
			logger.error('Session length must be a positive number');

export function identifySessionBlocks(
entries: LoadedUsageEntry[],
sessionDurationHours = DEFAULT_SESSION_DURATION_HOURS,
): SessionBlock[] {
Copy link

Copilot AI Jun 17, 2025

Choose a reason for hiding this comment

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

Consider adding a guard in identifySessionBlocks to validate that sessionDurationHours is positive (e.g., throw or early return) to avoid unexpected behavior if called directly with invalid values.

Suggested change
): SessionBlock[] {
): SessionBlock[] {
if (sessionDurationHours <= 0) {
throw new Error("sessionDurationHours must be a positive number.");
}

Copilot uses AI. Check for mistakes.
ryoppippi added a commit that referenced this pull request Jun 22, 2025
feat: add configurable session length to blocks command
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.

2 participants