-
-
Notifications
You must be signed in to change notification settings - Fork 317
Add real-time monitoring for active session block #120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughA new CLI subcommand "watch" has been introduced, providing real-time monitoring of session usage statistics with interactive terminal controls. Supporting utilities were updated to recognize an additional legacy model name format. New modules were added for progress bar rendering, session tracking, burn rate analysis, detailed table display, adaptive scheduling, keyboard input handling, and dynamic watch display updates. Existing commands and behaviors remain unchanged. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI
participant WatchCommand
participant SessionData
User->>CLI: Run "watch" command
CLI->>WatchCommand: Initialize and start watch
loop Every interval
WatchCommand->>SessionData: Load latest session block data
SessionData-->>WatchCommand: Return usage stats
WatchCommand->>CLI: Update terminal display
User->>WatchCommand: Toggle display or exit (key input)
end
WatchCommand->>CLI: Display session summary on exit
Suggested reviewers
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 @infonobody, 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 significantly enhances the CLI's capabilities by adding a real-time monitoring tool for active Claude session blocks. The new watch command provides developers with an immediate, interactive overview of their AI usage, helping them manage resources and stay within budget through dynamic visualizations and detailed statistics.
Highlights
- New
watchCommand: Introduced a newwatchcommand that provides real-time, interactive monitoring of your active Claude session block usage directly in the terminal. This helps users keep track of their token consumption and costs. - Live Dashboard & Visualizations: The
watchcommand displays a live dashboard featuring a time countdown bar with color-coded warnings, and a cost usage bar visualizing spending by model type (Opus, Sonnet, Haiku). It also shows current and projected token/cost statistics. - Interactive Controls & Adaptive Updates: Users can toggle detailed views for token breakdown, cost breakdown, and burn rate analysis using keyboard shortcuts (T, C, P). The display automatically adjusts its update frequency (5s to 60s) based on activity, ensuring an efficient monitoring experience.
- Session Summary: Upon exiting the
watchcommand, a summary of the session's duration, tokens used, and cost incurred during the monitoring period is displayed. - Improved Model Name Formatting: The utility function for formatting model names has been enhanced to correctly parse and display older Claude model name conventions, ensuring consistency across the application.
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
-
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. ↩
There was a problem hiding this 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 watch command for real-time monitoring of Claude Code usage. The implementation includes dynamic progress bars, cost estimations, and interactive controls. I've provided suggestions for minor code cleanup in watch.ts and utils.internal.ts to improve maintainability.
src/commands/watch.ts
Outdated
| * @param _allBlocks - All blocks for historical comparison | ||
| * @returns Burn rate analysis object | ||
| */ | ||
| function calculateBurnRateAnalysis(block: SessionBlock, _allBlocks: SessionBlock[]): BurnRateAnalysis { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/commands/watch.ts
Outdated
| if (firstEntry == null || lastEntry == null) { | ||
| return nullResult; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this 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 (2)
src/commands/watch.ts (2)
10-12: Improve import consistency for better code style.Consider using top-level type-only imports instead of inline type specifiers for consistency with the project's linting rules.
Apply this diff to improve import style:
- type LoadedUsageEntry, + type LoadedUsageEntry, projectBlockUsage, - type SessionBlock, + type SessionBlock,And add a separate type import:
+import type { LoadedUsageEntry, SessionBlock } from '../session-blocks.internal.ts'; import { calculateBurnRate, DEFAULT_SESSION_DURATION_HOURS, - type LoadedUsageEntry, projectBlockUsage, - type SessionBlock, } from '../session-blocks.internal.ts';
314-322: Cost breakdown estimation limitation.The proportional cost calculation assumes equal cost per token across all token types (input, output, cache create, cache read), which may not reflect actual pricing differences. However, this is a reasonable approximation given that detailed cost breakdowns aren't available in the source data.
Consider adding a comment to document this limitation:
// Calculate individual cost components - // We need to estimate the cost breakdown since we only have total costUSD + // We need to estimate the cost breakdown since we only have total costUSD + // Note: This assumes equal cost per token across all types, which may not be accurate const totalTokens = entry.usage.inputTokens + entry.usage.outputTokens + entry.usage.cacheCreationInputTokens + entry.usage.cacheReadInputTokens;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/commands/index.ts(2 hunks)src/commands/watch.ts(1 hunks)src/utils.internal.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/commands/index.ts (1)
src/commands/watch.ts (1)
watchCommand(706-912)
🪛 ESLint
src/commands/watch.ts
[error] 10-10: Prefer using a top-level type-only import instead of inline type specifiers.
(import/consistent-type-specifier-style)
[error] 12-12: Prefer using a top-level type-only import instead of inline type specifiers.
(import/consistent-type-specifier-style)
[error] 182-182: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 182-182: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 182-182: Unsafe member access .blue on an error typed value.
(ts/no-unsafe-member-access)
[error] 183-183: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 183-183: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 183-183: Unsafe member access .cyan on an error typed value.
(ts/no-unsafe-member-access)
[error] 184-184: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 184-184: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 184-184: Unsafe member access .magenta on an error typed value.
(ts/no-unsafe-member-access)
[error] 185-185: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 185-185: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 185-185: Unsafe member access .gray on an error typed value.
(ts/no-unsafe-member-access)
[error] 197-197: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 197-197: Unsafe member access .red on an error typed value.
(ts/no-unsafe-member-access)
[error] 205-205: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 211-211: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 211-211: Unsafe member access .blue on an error typed value.
(ts/no-unsafe-member-access)
[error] 215-215: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 215-215: Unsafe member access .cyan on an error typed value.
(ts/no-unsafe-member-access)
[error] 219-219: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 219-219: Unsafe member access .magenta on an error typed value.
(ts/no-unsafe-member-access)
[error] 221-221: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 221-221: Unsafe member access .gray on an error typed value.
(ts/no-unsafe-member-access)
[error] 222-222: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 223-223: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 230-234: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 230-234: Unsafe construction 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 .push on an error typed value.
(ts/no-unsafe-member-access)
[error] 281-281: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 281-281: Unsafe member access .push on an error typed value.
(ts/no-unsafe-member-access)
[error] 282-282: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 282-282: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 283-283: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 283-283: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 284-284: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 284-284: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 285-285: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 285-285: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 286-286: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 286-286: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 287-287: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 287-287: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 291-291: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 291-291: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 291-291: Unsafe member access .toString on an error typed value.
(ts/no-unsafe-member-access)
[error] 298-302: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 298-302: Unsafe construction of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 339-339: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 339-339: Unsafe member access .push on an error typed value.
(ts/no-unsafe-member-access)
[error] 356-356: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 356-356: Unsafe member access .push on an error typed value.
(ts/no-unsafe-member-access)
[error] 357-357: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 357-357: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 358-358: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 358-358: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 359-359: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 359-359: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 360-360: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 360-360: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 361-361: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 361-361: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 362-362: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 362-362: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 366-366: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 366-366: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 366-366: Unsafe member access .toString on an error typed value.
(ts/no-unsafe-member-access)
[error] 373-377: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 373-377: Unsafe construction of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 383-383: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 383-383: Unsafe member access .push on an error typed value.
(ts/no-unsafe-member-access)
[error] 389-389: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 389-389: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 389-389: Unsafe member access .toString on an error typed value.
(ts/no-unsafe-member-access)
[error] 429-429: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 429-429: Unsafe member access .green on an error typed value.
(ts/no-unsafe-member-access)
[error] 429-429: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 429-429: Unsafe member access .red on an error typed value.
(ts/no-unsafe-member-access)
[error] 448-448: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 448-448: Unsafe member access .stdout on an error typed value.
(ts/no-unsafe-member-access)
[error] 601-601: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 601-601: Unsafe member access .green on an error typed value.
(ts/no-unsafe-member-access)
[error] 603-603: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 603-603: Unsafe member access .red on an error typed value.
(ts/no-unsafe-member-access)
[error] 606-606: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 606-606: Unsafe member access .yellow on an error typed value.
(ts/no-unsafe-member-access)
[error] 613-613: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 613-613: Unsafe member access .gray on an error typed value.
(ts/no-unsafe-member-access)
[error] 614-614: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 617-617: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 676-676: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 677-677: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 681-681: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 686-686: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 691-691: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 694-694: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 703-703: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 706-912: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 706-706: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 709-717: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 721-721: Unsafe member access .level on an error typed value.
(ts/no-unsafe-member-access)
[error] 724-724: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 724-724: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 727-727: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 727-727: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 728-728: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 728-728: Unsafe member access .error on an error typed value.
(ts/no-unsafe-member-access)
[error] 729-729: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 729-729: Unsafe member access .exit on an error typed value.
(ts/no-unsafe-member-access)
[error] 749-749: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 749-749: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 750-750: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 750-750: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 753-753: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 754-754: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 754-754: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 761-761: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 761-761: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 761-761: Unsafe member access .yellow on an error typed value.
(ts/no-unsafe-member-access)
[error] 762-762: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 763-763: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 813-813: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 813-813: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 813-813: Unsafe member access .red on an error typed value.
(ts/no-unsafe-member-access)
[error] 814-814: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 814-814: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 814-814: Unsafe member access .gray on an error typed value.
(ts/no-unsafe-member-access)
[error] 815-815: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 816-816: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 825-831: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 825-825: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 829-829: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 829-829: Unsafe member access .error on an error typed value.
(ts/no-unsafe-member-access)
[error] 837-837: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 837-837: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 838-838: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 838-838: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 839-839: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 839-839: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 842-842: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 843-843: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 843-843: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 844-844: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 844-844: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 871-871: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 871-871: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 871-871: Unsafe member access .cyan on an error typed value.
(ts/no-unsafe-member-access)
[error] 872-872: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 872-872: Unsafe member access .exit on an error typed value.
(ts/no-unsafe-member-access)
[error] 902-902: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 902-902: Unsafe member access .error on an error typed value.
(ts/no-unsafe-member-access)
[error] 907-907: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 907-907: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 910-910: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 910-910: Unsafe member access .on on an error typed value.
(ts/no-unsafe-member-access)
🔇 Additional comments (5)
src/commands/index.ts (1)
9-9: Clean integration of the new watch command.The import and registration follow the established pattern and integrate seamlessly with the existing CLI structure.
Also applies to: 19-19
src/utils.internal.ts (1)
235-240: Good backward compatibility enhancement.The addition properly handles legacy model name formats while maintaining the existing functionality. The regex pattern correctly captures and reorders the components from the old
claude-<major>-<minor>-<type>-<date>format.src/commands/watch.ts (3)
151-176: Robust progress bar width calculation.The proportional width distribution logic handles edge cases well, including rounding adjustments to prevent overflow and minimum width guarantees for visibility. The implementation ensures visual consistency across different usage patterns.
836-911: Excellent resource management and user experience.The implementation demonstrates thorough attention to detail:
- Proper terminal state management with raw mode setup/cleanup
- Comprehensive keyboard input handling for interactive controls
- Graceful cleanup with meaningful session summaries
- Robust error handling throughout the lifecycle
The user experience is well-designed with clear exit strategies and informative feedback.
706-912: Well-architected real-time monitoring solution.This watch command implementation successfully delivers the PR objectives with:
- Adaptive monitoring: Intelligent update intervals based on activity levels
- Rich visualizations: Color-coded progress bars and detailed breakdowns
- Interactive controls: User-friendly toggles for different views
- Comprehensive tracking: Session summaries and burn rate analysis
The architecture demonstrates good separation of concerns and provides a professional monitoring experience for Claude usage tracking.
ryoppippi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@infonobody This PR looks neat! I need a test BTW
Also please create a file including logic and avoid implementing logic in command file.
commit: |
- Remove unused _allBlocks parameter from function signature - Update JSDoc to remove parameter documentation - Update function call site to not pass unused parameter Addresses PR feedback about unused parameter causing confusion.
- Extract cleanup logic into createCleanupHandler function - Extract keyboard input handling into setupKeyboardHandling function - Modify variable declarations to use reference objects for extracted functions - Reduce complexity of main run function by separating concerns This addresses PR feedback about high cyclomatic complexity by breaking down the large function into smaller, focused functions.
- Extract session tracking into createSessionTracker function - Extract main update logic into createUpdateDisplay function - Create proper type definitions for configuration and state management - Further reduce complexity of main run function This completes the refactoring to address PR feedback about high cyclomatic complexity by breaking down the large run function into smaller, focused, reusable functions.
- Move formatDuration and clearScreen from watch.ts to utils.internal.ts - Add comprehensive tests for formatDuration function - Improve error handling with explicit type annotations - Clean up inline duration formatting logic
- Move DisplayOptions and ModelType from watch.ts to types.internal.ts - Define ModelTypes constant array for better type safety - Remove duplicate type definitions to improve maintainability
- Extract display logic to watch-display.internal.ts (328 lines) - Extract input/keyboard handling to watch-input.internal.ts (110 lines) - Extract adaptive scheduler to watch-scheduler.internal.ts (40 lines) - Reduce watch.ts from 512 to 82 lines for better maintainability - Each module now has single responsibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/commands/watch.ts (1)
8-8: Prefer top-level type-only imports for consistencySplit the mixed import into separate type-only and regular imports for better clarity and consistency.
-import { createUpdateDisplay, UPDATE_INTERVALS, type UpdateDisplayConfig, type UpdateDisplayState } from '../watch-display.internal.ts'; +import type { UpdateDisplayConfig, UpdateDisplayState } from '../watch-display.internal.ts'; +import { createUpdateDisplay, UPDATE_INTERVALS } from '../watch-display.internal.ts';src/progress-bar.internal.ts (1)
18-29: Consider case-insensitive model type detectionThe current implementation only matches lowercase model names. Consider making it case-insensitive to handle variations like "Opus", "OPUS", etc.
export function getModelType(model: string): ModelType | null { - if (model.includes('opus')) { + const modelLower = model.toLowerCase(); + if (modelLower.includes('opus')) { return 'opus'; } - if (model.includes('sonnet')) { + if (modelLower.includes('sonnet')) { return 'sonnet'; } - if (model.includes('haiku')) { + if (modelLower.includes('haiku')) { return 'haiku'; } return null; }src/watch-display.internal.ts (1)
82-196: Consider breaking downdisplayActiveBlockinto smaller functionsThis function has multiple responsibilities and is quite long. Consider extracting some logic into separate functions for better maintainability and testability.
For example, you could extract:
- Time progress bar display (lines 92-109)
- Cost calculation and display (lines 111-142)
- Statistics display (lines 144-169)
- Optional tables display (lines 172-185)
This would make the main function more readable and each piece more testable.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
src/commands/watch.ts(1 hunks)src/progress-bar.internal.ts(1 hunks)src/session-blocks.internal.ts(2 hunks)src/session-tracker.internal.ts(1 hunks)src/table-display.internal.ts(1 hunks)src/types.internal.ts(1 hunks)src/utils.internal.ts(3 hunks)src/watch-display.internal.ts(1 hunks)src/watch-input.internal.ts(1 hunks)src/watch-scheduler.internal.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/types.internal.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/watch-input.internal.ts (4)
src/session-blocks.internal.ts (1)
SessionBlock(38-49)src/utils.internal.ts (4)
clearScreen(244-246)formatDuration(227-239)formatNumber(208-210)formatCurrency(217-219)src/logger.ts (1)
log(14-14)src/types.internal.ts (1)
DisplayOptions(143-147)
src/progress-bar.internal.ts (2)
src/types.internal.ts (1)
ModelType(138-138)src/logger.ts (1)
log(14-14)
🪛 ESLint
src/watch-scheduler.internal.ts
[error] 16-16: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 19-25: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 19-19: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 23-23: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 23-23: Unsafe member access .error on an error typed value.
(ts/no-unsafe-member-access)
[error] 34-34: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
src/watch-input.internal.ts
[error] 28-28: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 30-30: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 30-30: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 31-31: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 31-31: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 52-52: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 52-52: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 52-52: Unsafe member access .cyan on an error typed value.
(ts/no-unsafe-member-access)
[error] 53-53: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 53-53: Unsafe member access .exit on an error typed value.
(ts/no-unsafe-member-access)
[error] 69-69: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 69-69: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 70-70: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 70-70: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 71-71: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 71-71: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 100-100: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 100-100: Unsafe member access .error on an error typed value.
(ts/no-unsafe-member-access)
[error] 105-105: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 105-105: Unsafe member access .stdin on an error typed value.
(ts/no-unsafe-member-access)
[error] 108-108: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 108-108: Unsafe member access .on on an error typed value.
(ts/no-unsafe-member-access)
src/table-display.internal.ts
[error] 120-127: Unsafe argument of type any[] assigned to a parameter of type TableRow.
(ts/no-unsafe-argument)
[error] 121-121: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 121-121: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 122-122: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 122-122: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 123-123: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 123-123: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 124-124: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 124-124: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 125-125: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 125-125: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 126-126: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 126-126: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 179-186: Unsafe argument of type any[] assigned to a parameter of type TableRow.
(ts/no-unsafe-argument)
[error] 180-180: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 180-180: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 181-181: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 181-181: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 182-182: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 182-182: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 183-183: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 183-183: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 184-184: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 184-184: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 185-185: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 185-185: Unsafe member access .bold on an error typed value.
(ts/no-unsafe-member-access)
[error] 212-216: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 212-216: Unsafe construction of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 222-222: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 222-222: Unsafe member access .push on an error typed value.
(ts/no-unsafe-member-access)
[error] 235-235: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 236-236: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 236-236: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 236-236: Unsafe member access .toString on an error typed value.
(ts/no-unsafe-member-access)
src/watch-display.internal.ts
[error] 93-93: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 93-93: Unsafe member access .green on an error typed value.
(ts/no-unsafe-member-access)
[error] 95-95: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 95-95: Unsafe member access .red on an error typed value.
(ts/no-unsafe-member-access)
[error] 98-98: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 98-98: Unsafe member access .yellow on an error typed value.
(ts/no-unsafe-member-access)
[error] 105-105: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 105-105: Unsafe member access .gray on an error typed value.
(ts/no-unsafe-member-access)
[error] 106-106: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 109-109: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 168-168: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 169-169: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 173-173: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 174-174: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 178-178: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 179-179: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 183-183: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 184-184: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 186-186: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 195-195: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 272-272: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 272-272: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 272-272: Unsafe member access .yellow on an error typed value.
(ts/no-unsafe-member-access)
[error] 273-273: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 274-274: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 321-321: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 321-321: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 321-321: Unsafe member access .red on an error typed value.
(ts/no-unsafe-member-access)
[error] 322-322: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 322-322: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 322-322: Unsafe member access .gray on an error typed value.
(ts/no-unsafe-member-access)
[error] 323-323: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 324-324: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
src/progress-bar.internal.ts
[error] 50-50: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 50-50: Unsafe member access .green on an error typed value.
(ts/no-unsafe-member-access)
[error] 50-50: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 50-50: Unsafe member access .red on an error typed value.
(ts/no-unsafe-member-access)
[error] 79-79: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 141-141: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 141-141: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 141-141: Unsafe member access .blue on an error typed value.
(ts/no-unsafe-member-access)
[error] 142-142: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 142-142: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 142-142: Unsafe member access .cyan on an error typed value.
(ts/no-unsafe-member-access)
[error] 143-143: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 143-143: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 143-143: Unsafe member access .magenta on an error typed value.
(ts/no-unsafe-member-access)
[error] 144-144: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 144-144: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 144-144: Unsafe member access .gray on an error typed value.
(ts/no-unsafe-member-access)
[error] 156-156: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 156-156: Unsafe member access .red 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] 170-170: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 170-170: Unsafe member access .blue on an error typed value.
(ts/no-unsafe-member-access)
[error] 174-174: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 174-174: Unsafe member access .cyan on an error typed value.
(ts/no-unsafe-member-access)
[error] 178-178: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 178-178: Unsafe member access .magenta on an error typed value.
(ts/no-unsafe-member-access)
[error] 180-180: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 180-180: Unsafe member access .gray on an error typed value.
(ts/no-unsafe-member-access)
[error] 181-181: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 182-182: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
src/commands/watch.ts
[error] 8-8: Prefer using a top-level type-only import instead of inline type specifiers.
(import/consistent-type-specifier-style)
[error] 8-8: Prefer using a top-level type-only import instead of inline type specifiers.
(import/consistent-type-specifier-style)
[error] 12-82: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 12-12: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 15-23: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 27-27: Unsafe member access .level on an error typed value.
(ts/no-unsafe-member-access)
[error] 30-30: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 30-30: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 31-31: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 31-31: Unsafe member access .error on an error typed value.
(ts/no-unsafe-member-access)
[error] 32-32: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 32-32: Unsafe member access .exit on an error typed value.
(ts/no-unsafe-member-access)
[error] 51-51: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 51-51: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 52-52: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 52-52: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 53-53: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 53-53: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 54-54: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 54-54: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
[error] 55-55: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 55-55: Unsafe member access .values on an any value.
(ts/no-unsafe-member-access)
src/utils.internal.ts
[error] 245-245: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 245-245: Unsafe member access .stdout on an error typed value.
(ts/no-unsafe-member-access)
[error] 336-336: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 337-337: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 338-338: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 338-338: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 338-338: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 339-339: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 339-339: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 339-339: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 340-340: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 340-340: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 340-340: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 343-343: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 344-344: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 344-344: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 344-344: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 345-345: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 345-345: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 345-345: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 346-346: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 346-346: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 346-346: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 349-349: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 350-350: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 350-350: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 350-350: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 351-351: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 351-351: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 351-351: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 352-352: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 352-352: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 352-352: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 355-355: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 356-356: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 356-356: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 356-356: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 357-357: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 357-357: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 357-357: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 358-358: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 358-358: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 358-358: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 359-359: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 359-359: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 359-359: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 362-362: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 363-363: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 363-363: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 363-363: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 364-364: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 364-364: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 364-364: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 365-365: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 365-365: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 365-365: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 369-369: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 370-370: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 371-371: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 371-371: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 371-371: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
🔇 Additional comments (9)
src/utils.internal.ts (3)
221-246: Excellent implementation of utility functions.The
formatDurationandclearScreenfunctions are well-implemented with clear logic and appropriate ANSI escape codes for terminal control.
262-267: Good addition of legacy model name format support.The extension to support the older
claude-(major)-(minor)-(type)-dateformat maintains backward compatibility while correctly extracting and reordering components.
336-374: Comprehensive test coverage for new functions.The test suite covers all important edge cases including:
- Duration formatting with hours/minutes/seconds
- Edge cases for time boundaries
- Seconds handling for sub-minute durations
- Function existence verification for clearScreen
src/session-blocks.internal.ts (2)
68-85: Well-defined types and constants.The
BurnRateAnalysistype provides clear structure for different time periods, and theTIME_CONSTANTSobject centralizes time interval definitions for maintainability.
324-394: Robust burn rate calculation implementation.The functions properly handle edge cases:
- Empty entries return null appropriately
- Proper sorting ensures correct time calculations
- Duration validation prevents division by zero
- Separate token type calculations provide granular metrics
The mathematical logic is correct for calculating tokens per minute across different periods.
src/watch-scheduler.internal.ts (1)
8-40: Well-designed adaptive scheduler.The implementation provides:
- Clean separation of concerns with configurable update function
- Proper error handling that doesn't stop the scheduler
- Recursive scheduling that waits for completion before next cycle
- Clean start/stop lifecycle management
The exposed
intervalIdallows external control while maintaining encapsulation.src/table-display.internal.ts (3)
29-72: Solid token and cost breakdown calculations.The functions properly aggregate data by model and handle the cost estimation challenge well. Since only total cost is available per entry, using proportional distribution based on token counts is a reasonable approximation.
77-131: Well-structured table creation with proper formatting.The tokens table implementation:
- Uses responsive table design for terminal compatibility
- Properly sorts models for consistent display
- Includes totals row when multiple models are present
- Applies appropriate formatting and alignment
211-237: Clean period burn rate table implementation.The period table provides clear visualization of burn rates across different time spans with proper null handling and formatting.
| setStartValues(tokens: number, cost: number) { | ||
| // Only set values once at the beginning of the session | ||
| if (startTokens === 0 && startCost === 0) { | ||
| startTokens = tokens; | ||
| startCost = cost; | ||
| } | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the one-time initialization logic.
The current implementation only allows setting values once when both startTokens and startCost are 0. This could prevent legitimate re-initialization and may not work correctly if either the initial tokens or cost is actually 0.
Consider using a boolean flag instead:
export function createSessionTracker(): SessionTracker {
let startTokens = 0;
let startCost = 0;
+ let initialized = false;
return {
get startTokens() {
return startTokens;
},
get startCost() {
return startCost;
},
setStartValues(tokens: number, cost: number) {
- // Only set values once at the beginning of the session
- if (startTokens === 0 && startCost === 0) {
+ if (!initialized) {
startTokens = tokens;
startCost = cost;
+ initialized = true;
}
},
};
}🤖 Prompt for AI Agents
In src/session-tracker.internal.ts around lines 29 to 35, the current logic to
set startTokens and startCost only if both are zero can fail if either value is
legitimately zero, preventing proper initialization. Replace this check with a
boolean flag that tracks whether the start values have been set, and use this
flag to ensure the values are only initialized once regardless of their numeric
values.
| if (intervalId.current != null) { | ||
| clearTimeout(intervalId.current); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use clearInterval instead of clearTimeout for consistency
The parameter is named intervalId which suggests it contains a timer interval ID, but the code uses clearTimeout. For consistency and correctness, use clearInterval instead.
-if (intervalId.current != null) {
- clearTimeout(intervalId.current);
-}
+if (intervalId.current != null) {
+ clearInterval(intervalId.current);
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (intervalId.current != null) { | |
| clearTimeout(intervalId.current); | |
| } | |
| if (intervalId.current != null) { | |
| clearInterval(intervalId.current); | |
| } |
🧰 Tools
🪛 ESLint
[error] 28-28: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
🤖 Prompt for AI Agents
In src/watch-input.internal.ts around lines 27 to 29, the code uses clearTimeout
to clear a timer stored in intervalId.current, but since the variable name
suggests it is an interval ID, replace clearTimeout with clearInterval to
correctly clear the interval timer.
Done. Now the command file only operates on logic, with some reusable logic split into existing files, and other logic written in components based on their respective responsibilities. Just fix some little display issues, I didn't change any features and flow. You can modify anything if you want. Thanks. |
|
@infonobody
overall this PR is so good |
|
Ha, congrats on the PR, annoyingly i just created one for adding --live on blocks, but this one may be better. Sorry - i didn't spot this sooner. Happy to abandon my PR if this one is better. |
|
Actually I'm always wondering if we have to add watch feature. If there is an extra feature we should otherwise just use via Hmm it is hard to choose. both #126 and #120 look good Anyway, I'm a little bit tired of maintaining |
|
@ryoppippi
OK. I'm happy you like it. Why I choice write new command and code in one file in the first commit?
If this version implements -watch flag, please merge as soon as possible to prevent conflict in other contributor's work So, there are two different strategies we can choose before I start
Two commands aren't built-in on macOS, maybe not everyone wants to install just for use ccusage |
|
@a-c-m Your PR also meets my needs. |
|
Well I'll take a rest and come back in a couple of days! |
|
Thank you both so much for your contributions! I took some time to consider both designs, and honestly, it was a very close call — both had their strengths, and it was hard to choose between them. In the end, I decided to go with @a-c-m’s design, which I personally preferred a bit more. I’m really sorry @infonobody — I truly appreciate the time and effort you put into this. I hope you’ll consider contributing again in the future. Also, as noted in #126, we may still need to add some info per models, so there could be more opportunities to collaborate. Thanks again! 🙏 |
The watch command provides real-time monitoring within the current active block. It displays a live dashboard showing:
Key Features:
Visual Elements:
Smart Features:
This tool is perfect for developers who want to keep an eye on their Claude Code usage in real-time, helping them stay within budget and manage their token consumption
effectively.
Summary by CodeRabbit
New Features
Improvements