Skip to content

Conversation

@yamato-snow
Copy link

@yamato-snow yamato-snow commented Aug 12, 2025

🌏 日本語ローカライゼーション対応の追加

概要

Claude Code Usage Monitorを日本人エンジニアが使いやすくするための包括的な日本語ローカライゼーション対応を追加しました。既存の国際的なユーザー向け機能を完全に保持しながら、日本のユーザー向けに最適化された体験を提供します。

🚀 主な変更点

📚 包括的な日本語ドキュメント

  • README_JP.md: 完全な日本語版README(インストール、使用方法、機能説明)
  • CHANGELOG_JP.md: 変更履歴の日本語版
  • USAGE_JP.md: 日本人開発者向けの詳細な使用ガイド

🌐 国際化(i18n)システム

  • 新しいsrc/claude_monitor/i18n/モジュールを追加
  • 自動ロケール検出機能
  • 英語と日本語のメッセージサポート
  • 環境変数CLAUDE_MONITOR_LOCALEによる手動制御

🎌 日本語UI対応

  • すべてのエラーメッセージの日本語化
  • ローディング画面の日本語化
  • ユーザー向け通知メッセージの日本語化
  • 日本語システムロケールの自動検出

🕐 日本向けデフォルト設定

  • デフォルトタイムゾーンをAsia/Tokyoに設定
  • 日本語ロケール検出時の自動日本語化
  • 設定に--localeオプション追加(auto/en/ja)

🔧 技術的な実装詳細

ファイル変更

  • src/claude_monitor/core/settings.py: ロケール設定追加
  • src/claude_monitor/cli/bootstrap.py: 自動ロケール検出とタイムゾーン設定
  • src/claude_monitor/ui/components.py: UIメッセージの国際化
  • src/claude_monitor/terminal/manager.py: ターミナルメッセージの国際化

新規ファイル

  • src/claude_monitor/i18n/__init__.py: i18nモジュールのエントリーポイント
  • src/claude_monitor/i18n/messages.py: メッセージ翻訳システム
  • README_JP.md: 日本語版README
  • CHANGELOG_JP.md: 日本語版変更履歴
  • USAGE_JP.md: 日本語使用ガイド

🎯 ユーザー体験の改善

日本人ユーザー向け

  • システムロケールが日本語の場合、自動的に日本語UIで起動
  • 東京タイムゾーンがデフォルト設定
  • 日本語の詳細ドキュメントとガイド
  • 日本の開発環境に最適化された使用例

国際ユーザー向け

  • 既存の機能は完全に保持
  • 英語UIはデフォルトで維持
  • 後方互換性を完全保証
  • パフォーマンスへの影響なし

🧪 テスト方法

日本語ロケールのテスト

# 日本語ロケールを強制設定
export CLAUDE_MONITOR_LOCALE=ja
claude-monitor

# システムロケールでの自動検出テスト
export LANG=ja_JP.UTF-8
claude-monitor

英語ロケールのテスト

# 英語ロケールを強制設定
export CLAUDE_MONITOR_LOCALE=en
claude-monitor

# デフォルト動作の確認
unset CLAUDE_MONITOR_LOCALE
claude-monitor

設定オプションのテスト

# コマンドライン経由でのロケール設定
claude-monitor --locale ja
claude-monitor --locale en
claude-monitor --locale auto

📋 チェックリスト

  • 包括的な日本語ドキュメント作成
  • i18nシステムの実装
  • 自動ロケール検出機能
  • 全UIメッセージの日本語化
  • 日本向けデフォルト設定
  • 後方互換性の保証
  • 適切なエラーハンドリング
  • コードの品質確保

🌟 期待される効果

日本の開発者コミュニティへの貢献

  • 日本人エンジニアがより簡単にツールを導入・使用可能
  • 日本語ドキュメントによる学習コストの削減
  • 日本の開発環境に最適化された設定

プロジェクトの国際化

  • 多言語対応の基盤を構築
  • 他言語への展開が容易
  • グローバルなユーザーベース拡大の基礎

🤝 貢献者への配慮

この変更は以下のCONTRIBUTING.mdガイドラインに従っています:

  • 明確で説明的なコミットメッセージ
  • 適切なブランチ命名(feature/japanese-localization
  • 既存コードへの最小限の影響
  • 包括的なドキュメント更新
  • コードの品質とスタイル維持

📞 フィードバック歓迎

この実装について、以下の点でフィードバックをお待ちしています:

  • 翻訳の品質と自然さ
  • 技術的な実装方法
  • 日本人ユーザーの使いやすさ
  • 国際ユーザーへの影響

この変更により、Claude Code Usage Monitorがより多くの日本人開発者に愛用され、プロジェクトのグローバルな成長に貢献できることを期待しています。 🚀

Summary by CodeRabbit

  • New Features

    • Full Japanese localization (auto-detect, --locale / CLAUDE_MONITOR_LOCALE; auto/en/ja), localized UI, errors, prompts and exit message.
    • New display modes: realtime (default), daily (table), monthly (trend) via --view.
    • Enhanced session display, predictions, theming; default timezone switched to Asia/Tokyo.
  • Documentation

    • Japanese docs added: README_JP.md, USAGE_JP.md, CHANGELOG_JP.md.
  • Other

    • Locale persisted in saved settings; CLI/packaging usage standardized around claude-monitor.

- Add comprehensive Japanese documentation (README_JP.md, CHANGELOG_JP.md, USAGE_JP.md)
- Implement i18n system with automatic locale detection
- Add Japanese translations for all UI messages and error messages
- Set Asia/Tokyo as default timezone for Japanese users
- Add locale configuration option (--locale auto/en/ja)
- Auto-detect Japanese system locale and set appropriate defaults
- Maintain full backward compatibility with existing configurations

Features:
- Japanese translation of all user-facing messages
- Smart locale detection based on system settings
- Timezone defaults optimized for Japanese users
- Comprehensive Japanese usage guide
- Fully localized error messages and loading screens

This enhancement makes Claude Monitor more accessible to Japanese developers
while preserving all existing functionality for international users.
@coderabbitai
Copy link

coderabbitai bot commented Aug 12, 2025

Walkthrough

Adds a bilingual i18n subsystem (en/ja) with runtime locale selection (CLI/env/auto), wires locale into Settings and bootstrap, changes default timezone to Asia/Tokyo, localizes UI/terminal strings (lazy lookup), introduces SessionDisplayData and a v2 formatter, and adds Japanese docs and CLI --locale support.

Changes

Cohort / File(s) Summary
Internationalization core
src/claude_monitor/i18n/__init__.py, src/claude_monitor/i18n/messages.py
New i18n package with English/Japanese message catalog, environment/system locale detection/normalization, APIs set_locale/get_current_locale/get_message, English fallback and safe formatting.
Settings & bootstrap
src/claude_monitor/core/settings.py, src/claude_monitor/cli/bootstrap.py
Adds Settings.locale: Literal["auto","en","ja"] with validation and persistence to last-used; loads/applies locale (CLI > env > saved); bootstrap sets CLAUDE_MONITOR_LOCALE from system and changes default timezone to Asia/Tokyo.
UI localization & structured display
src/claude_monitor/ui/components.py, src/claude_monitor/ui/layouts.py, src/claude_monitor/ui/session_display.py
Replace hard-coded UI strings with get_message lookups; add SessionDisplayData and format_active_session_screen_v2 for structured rendering while keeping original formatter.
Terminal manager
src/claude_monitor/terminal/manager.py
handle_cleanup_and_exit now accepts message: Optional[str] = None; when None, lazily fetches localized session.monitoring_stopped via i18n before printing and exiting.
Public exports
src/claude_monitor/i18n/__init__.py
Re-exports get_message, set_locale, get_current_locale as package API.
Documentation (Japanese)
README_JP.md, USAGE_JP.md, CHANGELOG_JP.md, PULL_REQUEST_JP.md
Adds full Japanese README, usage guide, changelog, and PR notes describing --locale, CLAUDE_MONITOR_LOCALE, timezone default, UI localization, and testing guidance.
Docs / README updates
README.md, CONTRIBUTING.md
Standardizes CLI invocation to claude-monitor / python -m claude_monitor, documents --locale and CLAUDE_MONITOR_LOCALE, and removes chmod/script-based run examples.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI as Bootstrap
  participant Settings
  participant I18N as i18n.messages
  participant UI as UI/Terminal

  User->>CLI: start claude-monitor [--locale / env]
  CLI->>Settings: load settings (including locale)
  CLI->>CLI: if locale == "auto" detect system locale
  CLI->>I18N: set_locale(resolved_locale)
  CLI->>CLI: init_timezone(default=Asia/Tokyo)
  CLI->>UI: start render loop
  UI->>I18N: get_message(key...)
  I18N-->>UI: localized string
  UI-->>User: localized output

  User-->>UI: exit (Ctrl+C)
  UI->>UI: handle_cleanup_and_exit(message=None)
  UI->>I18N: get_message('session.monitoring_stopped')
  I18N-->>UI: localized exit message
  UI-->>User: localized exit message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • kory-
  • adawalli
  • rvaidya
  • PedramNavid

Poem

I nibble bytes beneath the moon,
翻訳の葉をちょいと齧って、
En and Ja hop into the view,
Tokyo time ticks, the UI feels true,
CLI bows — I twitch my whiskers, too. 🥕🐇

✨ 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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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

@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: 6

🔭 Outside diff range comments (5)
src/claude_monitor/core/settings.py (4)

318-335: Potential NameError when --clear is used due to cli_provided_fields scope

cli_provided_fields is defined only in the non-clear branch, yet referenced here. On --clear, this will attempt to evaluate "theme" not in cli_provided_fields and crash.

Fix by short-circuiting on not clear_config before referencing the variable:

-        if settings.theme == "auto" or (
-            "theme" not in cli_provided_fields and not clear_config
-        ):
+        if settings.theme == "auto" or (
+            not clear_config and "theme" not in cli_provided_fields
+        ):

Alternatively, initialize cli_provided_fields: Set[str] = set() at the top of the method and/or inside the clear_config branch.


342-359: Expose locale via to_namespace()

If any downstream code reads args (as main() does), locale should be included to maintain parity with other settings.

Proposed change:

         args.time_format = self.time_format
+        args.locale = self.locale
         args.log_level = self.log_level

27-42: Persist locale in last-used settings

To meet the PR objective “persisted locale preferences”, include locale in the saved params and apply it on load.

Outside this hunk, apply:

# In LastUsedParams.save()
params = {
    "theme": settings.theme,
    "timezone": settings.timezone,
    "time_format": settings.time_format,
    "refresh_rate": settings.refresh_rate,
    "reset_hour": settings.reset_hour,
    "view": settings.view,
    "locale": settings.locale,  # add this
    "timestamp": datetime.now().isoformat(),
}

This will then flow through the merge loop you already have.


310-317: Wire locale into i18n initialization in settings.load_with_last_used

After post-processing timezone, time_format, and debug, resolve settings.locale and propagate it into the env and i18n subsystem:

• File: src/claude_monitor/core/settings.py
• Method: Settings.load_with_last_used
• Insert immediately after the existing

    if settings.debug:
        settings.log_level = "DEBUG"

Proposed diff:

@@ src/claude_monitor/core/settings.py:312
-        if settings.debug:
-            settings.log_level = "DEBUG"
+        if settings.debug:
+            settings.log_level = "DEBUG"
+
+        # Wire locale into i18n and environment
+        import os
+        import locale as pylocale
+        from claude_monitor.i18n import set_locale
+
+        if settings.locale == "auto":
+            env_loc = os.environ.get("CLAUDE_MONITOR_LOCALE", "")
+            sys_loc = (pylocale.getlocale()[0] or os.environ.get("LANG", "") or "").lower()
+            chosen = env_loc or ("ja" if sys_loc.startswith("ja") else "en")
+        else:
+            chosen = settings.locale
+
+        os.environ["CLAUDE_MONITOR_LOCALE"] = chosen
+        set_locale(chosen)

This ensures the CLI/system locale, your --locale setting, and the i18n subsystem stay in sync.

src/claude_monitor/cli/bootstrap.py (1)

63-75: Timezone initialization bug: default handler remains UTC for Asia/Tokyo

TimezoneHandler() defaults to UTC. Skipping set_timezone when timezone == "Asia/Tokyo" leaves the handler at UTC, contrary to the new default goal.

Fix by initializing with the desired default or always setting:

-def init_timezone(timezone: str = "Asia/Tokyo") -> TimezoneHandler:
+def init_timezone(timezone: str = "Asia/Tokyo") -> TimezoneHandler:
@@
-    tz_handler = TimezoneHandler()
-    if timezone != "Asia/Tokyo":
-        tz_handler.set_timezone(timezone)
-    return tz_handler
+    # Initialize handler with the target timezone to avoid UTC fallback
+    tz_handler = TimezoneHandler(default_tz=timezone)
+    # Or, alternatively: tz_handler = TimezoneHandler(); tz_handler.set_timezone(timezone)
+    return tz_handler

Also update the docstring example to include "Asia/Tokyo".

🧹 Nitpick comments (10)
README_JP.md (5)

26-26: Fix invalid link fragment in TOC (MD051)

One or more TOC anchors don’t match headings. Please ensure the link fragments correspond to GitHub’s generated IDs (lowercased, spaces to dashes, punctuation removed).


680-680: Use proper headings instead of bold text (MD036)

Replace emphasis-as-headings (e.g., lines with bold-only section titles) with markdown headings (### or ####) for better structure and lint compliance.

Also applies to: 690-690, 699-699, 799-799, 812-812, 818-818, 1140-1140


719-721: Normalize unordered list indentation (MD007)

Indentation levels are inconsistent in nested lists. Align with a consistent 2-space (or 4-space) indentation to satisfy markdownlint.

Also applies to: 731-733, 756-758, 767-769


979-983: Add language tag to fenced block (MD040)

For the error output code fence, use a language (e.g., text) to satisfy linters:

-```
+```text
 error: externally-managed-environment
 × This environment is externally managed

205-205: Minor JP style: avoid repetitive “ことができる”

Consider tightening phrasing to avoid verbosity flagged by LanguageTool. Example: replace “持つことができる” with “持てます” or restructure the sentence.

Also applies to: 794-794

USAGE_JP.md (1)

163-166: Specify language for fenced code block (MD040)

Add text to the fence that shows the settings file path:

-```
+```text
 ~/.claude-monitor/last_used.json
src/claude_monitor/cli/bootstrap.py (1)

41-61: Optional: allow setup_environment to accept a preferred locale

To honor CLI --locale, accept an optional arg and set env accordingly (call site can be updated in cli/main.py):

-def setup_environment() -> None:
+def setup_environment(preferred_locale: Optional[str] = None) -> None:
@@
-    # Setup default locale for Japanese users
-    import locale as pylocale
-    if "CLAUDE_MONITOR_LOCALE" not in os.environ:
-        sys_loc = (pylocale.getlocale()[0] or os.environ.get("LANG", "") or "").lower()
-        os.environ.setdefault(
-            "CLAUDE_MONITOR_LOCALE",
-            "ja" if sys_loc.startswith("ja") else "en",
-        )
+    # Setup default locale (CLI/env/system)
+    import locale as pylocale
+    if preferred_locale in ("en", "ja"):
+        os.environ["CLAUDE_MONITOR_LOCALE"] = preferred_locale
+    elif "CLAUDE_MONITOR_LOCALE" not in os.environ:
+        sys_loc = (pylocale.getlocale()[0] or os.environ.get("LANG", "") or "").lower()
+        os.environ.setdefault("CLAUDE_MONITOR_LOCALE", "ja" if sys_loc.startswith("ja") else "en")

Then in cli/main.py (outside this PR file), pass settings.locale to setup_environment.

src/claude_monitor/ui/components.py (1)

86-88: Update default timezone arguments to align with new defaults

Function signatures still default to "Europe/Warsaw", which is stale given the PR shifts defaults to Asia/Tokyo/auto. These are only used if call sites rely on defaults, but better to stay consistent.

Proposed minimal alignment:

-    def format_error_screen(
-        self, plan: str = "pro", timezone: str = "Europe/Warsaw"
+    def format_error_screen(
+        self, plan: str = "pro", timezone: str = "Asia/Tokyo"
@@
-        plan: str = "pro",
-        timezone: str = "Europe/Warsaw",
+        plan: str = "pro",
+        timezone: str = "Asia/Tokyo",
@@
-        plan: str = "pro",
-        timezone: str = "Europe/Warsaw",
+        plan: str = "pro",
+        timezone: str = "Asia/Tokyo",
@@
-def format_error_screen(
-    plan: str = "pro", timezone: str = "Europe/Warsaw"
+def format_error_screen(
+    plan: str = "pro", timezone: str = "Asia/Tokyo"

Alternatively, consider "auto" for signatures if your header manager accepts it.

Also applies to: 123-127, 165-170, 301-304

PULL_REQUEST_JP.md (2)

14-19: Document precedence and accepted values for locale configuration

Clarify how --locale, CLAUDE_MONITOR_LOCALE, and system locale interact to reduce ambiguity.

Add bullets to this section:

 ### 🌐 国際化(i18n)システム
 - 新しい`src/claude_monitor/i18n/`モジュールを追加
 - 自動ロケール検出機能
 - 英語と日本語のメッセージサポート
 - 環境変数`CLAUDE_MONITOR_LOCALE`による手動制御
+ - 受け付ける値: `auto` / `en` / `ja`
+ - 優先順位: `--locale` (CLI) > `CLAUDE_MONITOR_LOCALE` (環境変数) > システムロケール検出

60-90: Expand testing matrix to include “auto” with explicit non-JP locale

You already cover auto + ja; add an explicit non-JP case to validate English fallback and prevent regressions.

Append to the test section:

 ### 設定オプションのテスト
 ```bash
 # コマンドライン経由でのロケール設定
 claude-monitor --locale ja
 claude-monitor --locale en
 claude-monitor --locale auto
+
+# auto の英語フォールバック確認(システムロケールが非日本語の場合)
+export LANG=en_US.UTF-8
+claude-monitor --locale auto

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

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


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 06f0fe11e694b8619f63f8b0db10dbdc5e7e5a44 and c150bec37525812ffeb7d560f736b9fa805380c9.

</details>

<details>
<summary>📒 Files selected for processing (10)</summary>

* `CHANGELOG_JP.md` (1 hunks)
* `PULL_REQUEST_JP.md` (1 hunks)
* `README_JP.md` (1 hunks)
* `USAGE_JP.md` (1 hunks)
* `src/claude_monitor/cli/bootstrap.py` (2 hunks)
* `src/claude_monitor/core/settings.py` (1 hunks)
* `src/claude_monitor/i18n/__init__.py` (1 hunks)
* `src/claude_monitor/i18n/messages.py` (1 hunks)
* `src/claude_monitor/terminal/manager.py` (2 hunks)
* `src/claude_monitor/ui/components.py` (2 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (7)</summary>

<details>
<summary>src/claude_monitor/terminal/manager.py (3)</summary><blockquote>

<details>
<summary>src/claude_monitor/i18n/messages.py (1)</summary>

* `get_message` (118-137)

</details>
<details>
<summary>src/claude_monitor/cli/main.py (2)</summary>

* `_run_monitoring` (110-260)
* `main` (72-107)

</details>
<details>
<summary>src/claude_monitor/__main__.py (1)</summary>

* `_main` (13-16)

</details>

</blockquote></details>
<details>
<summary>src/claude_monitor/i18n/__init__.py (1)</summary><blockquote>

<details>
<summary>src/claude_monitor/i18n/messages.py (3)</summary>

* `get_message` (118-137)
* `set_locale` (96-106)
* `get_current_locale` (109-115)

</details>

</blockquote></details>
<details>
<summary>USAGE_JP.md (1)</summary><blockquote>

<details>
<summary>src/tests/examples/api_examples.py (1)</summary>

* `print_usage_summary` (52-75)

</details>

</blockquote></details>
<details>
<summary>README_JP.md (1)</summary><blockquote>

<details>
<summary>src/tests/examples/api_examples.py (1)</summary>

* `print_usage_summary` (52-75)

</details>

</blockquote></details>
<details>
<summary>CHANGELOG_JP.md (1)</summary><blockquote>

<details>
<summary>src/tests/examples/api_examples.py (2)</summary>

* `print_usage_summary` (52-75)
* `example_advanced_usage` (152-185)

</details>

</blockquote></details>
<details>
<summary>src/claude_monitor/ui/components.py (1)</summary><blockquote>

<details>
<summary>src/claude_monitor/i18n/messages.py (1)</summary>

* `get_message` (118-137)

</details>

</blockquote></details>
<details>
<summary>src/claude_monitor/cli/bootstrap.py (3)</summary><blockquote>

<details>
<summary>src/claude_monitor/utils/time_utils.py (4)</summary>

* `TimezoneHandler` (348-458)
* `set_timezone` (433-435)
* `ensure_timezone` (412-416)
* `convert_to_timezone` (426-431)

</details>
<details>
<summary>src/claude_monitor/cli/main.py (1)</summary>

* `main` (72-107)

</details>
<details>
<summary>src/claude_monitor/ui/display_controller.py (1)</summary>

* `__init__` (578-580)

</details>

</blockquote></details>

</details><details>
<summary>🪛 markdownlint-cli2 (0.17.2)</summary>

<details>
<summary>USAGE_JP.md</summary>

163-163: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>
<details>
<summary>README_JP.md</summary>

26-26: Link fragments should be valid

(MD051, link-fragments)

---

680-680: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

---

690-690: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

---

699-699: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

---

719-719: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

720-720: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

721-721: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

731-731: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

732-732: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

733-733: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

756-756: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

757-757: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

758-758: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

767-767: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

768-768: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

769-769: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

---

799-799: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

---

812-812: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

---

818-818: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

---

979-979: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

---

1140-1140: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

</details>

</details>
<details>
<summary>🪛 LanguageTool</summary>

<details>
<summary>README_JP.md</summary>

[uncategorized] ~205-~205: 「ことができる」という表現は冗長な可能性があります。
Context: ...検出 |  #### コマンドエイリアス  このツールは以下のコマンドで呼び出すことができます: - claude-monitor(メイン) - claude-code-...

(DOUSI_KOTOGADEKIRU)

---

[uncategorized] ~794-~794: 「ことができる」という表現は冗長な可能性があります。
Context: ...ョンは正確に5時間継続することを覚えておく    - 複数の重複するセッションを持つことができる    - セッション境界をまたいで作業を計画  #### 実世界のワークフ...

(DOUSI_KOTOGADEKIRU)

</details>

</details>

</details>

<details>
<summary>🔇 Additional comments (5)</summary><blockquote>

<details>
<summary>CHANGELOG_JP.md (1)</summary>

`3-15`: **Changelog looks consistent; verify version/date alignment with tagged releases**

Content reads well and aligns with features introduced. Please ensure the dates and versions match actual release tags, especially 3.1.0.

</details>
<details>
<summary>src/claude_monitor/i18n/__init__.py (1)</summary>

`1-5`: **LGTM – clean public API re-exports**

Clear re-exports with `__all__` are appropriate and match the new i18n usage across the codebase.

</details>
<details>
<summary>src/claude_monitor/terminal/manager.py (1)</summary>

`70-85`: **Localized default exit message confirmed**

- Verified that `session.monitoring_stopped` is defined in:
  - src/claude_monitor/i18n/messages.py:31 (English)
  - src/claude_monitor/i18n/messages.py:70 (Japanese)

No further action required.

</details>
<details>
<summary>src/claude_monitor/ui/components.py (2)</summary>

`103-112`: **Good i18n integration for error screen**

Replacing hard-coded strings with `get_message` is correct. Keep the lazy import if it helps avoid cycles.

---

`142-162`: **Good i18n integration for loading screen**

All user-facing text now goes through the i18n layer, including the conditional custom plan message.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

🌐 日本語と英語の完全なローカライゼーション機能を追加

### 主な変更
- **i18nシステム拡張**: UI要素の完全な日本語化
- **タイトル日本語化**: 「🎯 Claude Code使用量監視ツール」に変更
- **セッション表示日本語化**: すべてのラベルとメッセージを日本語対応
- **言語設定オプション**: --localeパラメータと環境変数サポート

### 技術的実装
- src/claude_monitor/i18n/messages.py: UIメッセージの翻訳追加
- src/claude_monitor/ui/layouts.py: タイトルのi18n対応
- src/claude_monitor/ui/session_display.py: セッション表示のi18n対応

### ドキュメント更新
- README_JP.md: 日本語化機能の説明追加
- USAGE_JP.md: 言語設定の使用方法追加
- CHANGELOG_JP.md: 日本語化の変更履歴追加

### 使用方法
- デフォルト: 日本語(--locale ja)
- 英語: --locale en
- 自動検出: --locale auto
- 環境変数: CLAUDE_MONITOR_LOCALE=ja

Closes: #日本語化対応
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 (6)
README_JP.md (6)

26-26: Fix broken link fragment.

The table of contents link #-このリリースのテストにご協力ください doesn't match any heading in the document.

#!/bin/bash
# Verify if the heading exists in the document
rg "このリリースのテストにご協力ください" README_JP.md

206-206: Consider more concise phrasing.

The LanguageTool suggests that "呼び出すことができます" might be redundant. Consider using a more concise form like "呼び出せます".

-このツールは以下のコマンドで呼び出すことができます:
+このツールは以下のコマンドで呼び出せます:

814-814: Consider more concise phrasing.

Similar to the previous suggestion, "持つことができる" could be made more concise as "持てる".

-   - 複数の重複するセッションを持つことができる
+   - 複数の重複するセッションを持てる

739-741: Fix unordered list indentation.

Multiple unordered list items have incorrect indentation (3 spaces instead of expected 0). This affects the document structure and rendering.

-   - 開始からの正確なセッション追跡
-   - より良いバーンレート計算
-   - 制限接近の早期警告
+- 開始からの正確なセッション追跡
+- より良いバーンレート計算
+- 制限接近の早期警告

Apply similar fixes to all affected list items throughout the document.

Also applies to: 751-753, 776-778, 787-789


700-700: Use proper heading syntax instead of emphasis.

Several sections use emphasis (bold) instead of proper heading markup, which affects document structure and accessibility.

-**デフォルトから開始(新規ユーザー推奨)**
+#### デフォルトから開始(新規ユーザー推奨)

Apply similar changes to other emphasized pseudo-headings throughout the document.

Also applies to: 710-710, 719-719, 819-819, 832-832, 838-838


999-999: Specify language for fenced code block.

The error code block should specify a language for proper syntax highlighting.

-```
+```text
error: externally-managed-environment
× This environment is externally managed
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c150bec and 1a518e5.

📒 Files selected for processing (6)
  • CHANGELOG_JP.md (1 hunks)
  • README_JP.md (1 hunks)
  • USAGE_JP.md (1 hunks)
  • src/claude_monitor/i18n/messages.py (1 hunks)
  • src/claude_monitor/ui/layouts.py (2 hunks)
  • src/claude_monitor/ui/session_display.py (7 hunks)
✅ Files skipped from review due to trivial changes (1)
  • USAGE_JP.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/claude_monitor/i18n/messages.py
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/claude_monitor/ui/layouts.py (1)
src/claude_monitor/i18n/messages.py (1)
  • get_message (144-163)
src/claude_monitor/ui/session_display.py (3)
src/claude_monitor/i18n/messages.py (1)
  • get_message (144-163)
src/claude_monitor/ui/components.py (4)
  • render (44-58)
  • render (65-77)
  • VelocityIndicator (14-58)
  • get_velocity_emoji (18-28)
src/claude_monitor/ui/progress_bars.py (5)
  • render (43-45)
  • render (156-163)
  • render (185-221)
  • render (227-250)
  • render (256-333)
README_JP.md (1)
src/tests/examples/api_examples.py (1)
  • print_usage_summary (52-75)
🪛 LanguageTool
README_JP.md

[uncategorized] ~206-~206: 「ことができる」という表現は冗長な可能性があります。
Context: ...検出 | #### コマンドエイリアス このツールは以下のコマンドで呼び出すことができます: - claude-monitor(メイン) - claude-code-...

(DOUSI_KOTOGADEKIRU)


[uncategorized] ~814-~814: 「ことができる」という表現は冗長な可能性があります。
Context: ...ョンは正確に5時間継続することを覚えておく - 複数の重複するセッションを持つことができる - セッション境界をまたいで作業を計画 #### 実世界のワークフ...

(DOUSI_KOTOGADEKIRU)

🪛 markdownlint-cli2 (0.17.2)
README_JP.md

26-26: Link fragments should be valid

(MD051, link-fragments)


700-700: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


710-710: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


719-719: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


739-739: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


740-740: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


741-741: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


751-751: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


752-752: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


753-753: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


776-776: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


777-777: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


778-778: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


787-787: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


788-788: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


789-789: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


819-819: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


832-832: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


838-838: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


999-999: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


1160-1160: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (8)
src/claude_monitor/ui/layouts.py (2)

12-12: LGTM! Import added for i18n integration.

The import of get_message from the i18n module is properly added to support localization functionality.


41-41: LGTM! Header title localized correctly.

The hard-coded title has been correctly replaced with a localized version using get_message("ui.title"). This maintains the existing functionality while enabling proper internationalization.

README_JP.md (1)

1-1165: Well-structured Japanese documentation with comprehensive coverage.

This is an extensive and well-organized Japanese README that provides comprehensive documentation for the Claude Code Usage Monitor tool. The document covers all essential aspects including installation, usage, configuration, and troubleshooting. The formatting is consistent with proper markdown structure and includes appropriate badges and visual elements.

Key strengths:

  • Comprehensive coverage of all features and installation methods
  • Clear step-by-step instructions
  • Multiple installation options (uv, pip, pipx, conda)
  • Extensive troubleshooting section
  • Professional formatting and structure
  • Proper use of Japanese typography and conventions
CHANGELOG_JP.md (1)

1-232: Comprehensive Japanese changelog with excellent organization.

This Japanese changelog is well-structured and provides detailed documentation of version changes. It covers the major architectural changes, new features, and breaking changes comprehensively. The formatting follows standard changelog conventions with clear categorization of changes.

Key strengths:

  • Clear versioning and date information
  • Comprehensive coverage of v3.0.0 major rewrite
  • Good organization with sections for new features, breaking changes, and technical details
  • Proper use of Japanese technical terminology
  • Consistent formatting throughout
src/claude_monitor/ui/session_display.py (4)

12-12: LGTM! Import added for i18n support.

The import of get_message is correctly added to support localization in the UI components.


27-54: Well-designed data class for parameter consolidation.

The SessionDisplayData dataclass is an excellent solution to replace the 21 parameters in the format_active_session_screen method. It improves code maintainability, readability, and type safety. The field names are clear and descriptive, and the default values are appropriate.

This follows good software engineering practices by encapsulating related data and reducing parameter passing complexity.


98-130: Good refactoring approach with delegation pattern.

The format_active_session_screen_v2 method provides a clean transition path by delegating to the existing method while accepting the new data class. This maintains backward compatibility while providing the improved interface.

The parameter mapping is comprehensive and maintains all functionality from the original method.


197-197: Excellent integration of i18n messages.

The UI text has been properly localized using the get_message function. All user-facing text elements are now properly internationalized:

  • Session-based limits
  • Cost usage, token usage, messages usage labels
  • Time to reset, model distribution labels
  • Burn rate, cost rate labels
  • Predictions section

The message keys follow a consistent naming pattern (ui.*) and the integration is seamless with the existing UI structure.

Also applies to: 199-199, 212-212, 218-218, 229-229, 243-243, 249-249, 252-252, 257-257, 267-267, 313-313

### 🔧 主要な修正
- **get_message関数の改善**: 英語フォールバック処理と型安全性向上
- **ロケール検出システム**: 堅牢なシステムロケール検出と正規化
- **set_locale関数の拡張**: 'auto'オプションとバリアント対応
- **bootstrap.pyの改善**: 非推奨API回避と環境変数処理
- **settings.pyの統合**: locale設定の永続化とi18nシステム連携
- **ドキュメント修正**: タイムゾーン設定の正確な記述

### �� 技術的改善
1. **フォールバック処理**: 翻訳キーが見つからない場合の英語フォールバック
2. **ロケール正規化**: ja_JP、en-US等のバリアントを適切に処理
3. **設定永続化**: locale設定をLastUsedParamsに保存・復元
4. **ランタイム統合**: 設定読み込み時にi18nシステムに自動反映
5. **エラーハンドリング**: 非推奨APIの回避と例外処理改善

### 🌐 ユーザー体験向上
- グローバルユーザー向けの適切なデフォルト(英語)
- 日本語ユーザー向けの自動検出機能
- 設定の永続化による利便性向上
- 堅牢なロケール検出による安定性向上

### 📋 修正ファイル
- src/claude_monitor/i18n/messages.py: 完全なi18nシステム改善
- src/claude_monitor/cli/bootstrap.py: ロケール検出処理改善
- src/claude_monitor/core/settings.py: locale設定の統合
- PULL_REQUEST_JP.md: ドキュメントの正確性向上

Closes: Maciek-roboblog#134
- 目次リンクフラグメントの修正(#🙏-このリリースのテストにご協力ください)
- 冗長な表現の簡潔化(「呼び出すことができます」→「呼び出せます」、「持つことができる」→「持てる」)
- 順序なしリストのインデント修正(スペース3→0)
- 強調の代わりに見出し構文を使用(**→####)
- コードブロックに言語指定を追加(text)

これらの修正により、マークダウンの構造と可読性が向上し、リンターエラーが解消されます。
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

🔭 Outside diff range comments (1)
src/claude_monitor/core/settings.py (1)

319-336: Fix NameError risk when using --clear with --theme.

cli_provided_fields is undefined in the --clear path; current condition may evaluate it and crash. Reordering the condition avoids accessing it when clear_config is True.

Apply this diff:

-        if settings.theme == "auto" or (
-            "theme" not in cli_provided_fields and not clear_config
-        ):
+        if settings.theme == "auto" or (
+            not clear_config and "theme" not in cli_provided_fields
+        ):
🧹 Nitpick comments (5)
src/claude_monitor/i18n/messages.py (4)

20-35: Future-proof locale detection: prefer locale.getlocale() over getdefaultlocale().

locale.getdefaultlocale() is slated for deprecation in newer Python versions. Use locale.getlocale() first, then fall back to getdefaultlocale() for older environments.

Apply this diff:

-    # Fallback to system default
-    try:
-        loc = locale.getdefaultlocale()[0] or ""
-    except Exception:
-        loc = ""
-    return _normalize_locale(loc)
+    # Fallback to system default
+    try:
+        # Prefer getlocale() to avoid deprecation of getdefaultlocale() in newer Python
+        loc = ""
+        try:
+            loc = (locale.getlocale()[0] or "")
+        except Exception:
+            loc = ""
+        if not loc:
+            # Fallback for older Python versions/environments
+            try:
+                loc = (locale.getdefaultlocale()[0] or "")
+            except Exception:
+                loc = ""
+    except Exception:
+        loc = ""
+    return _normalize_locale(loc)

39-46: Add a type annotation to MESSAGES for better static checking.

Minor clarity improvement; helps tooling catch key/value type mistakes.

Apply this diff:

-MESSAGES = {
+MESSAGES: Dict[str, Dict[str, str]] = {

148-160: Optionally reflect changes to the environment variable for downstream consumers.

Setting CLAUDE_MONITOR_LOCALE when set_locale is called helps child processes or late readers stay consistent.

Apply this diff:

 def set_locale(locale: str) -> None:
@@
-    if locale and locale.lower() == "auto":
-        _current_locale = _detect_default_locale()
-        return
+    if locale and locale.lower() == "auto":
+        _current_locale = _detect_default_locale()
+        os.environ["CLAUDE_MONITOR_LOCALE"] = _current_locale
+        return
@@
-    _current_locale = normalized if normalized in MESSAGES else "en"  # fallback to English
+    _current_locale = normalized if normalized in MESSAGES else "en"  # fallback to English
+    os.environ["CLAUDE_MONITOR_LOCALE"] = _current_locale

171-193: Safe formatting is good; consider covering IndexError too.

IndexError can occur with positional placeholders; adding it is harmless and makes the guard complete.

Apply this diff:

-        except (KeyError, ValueError):
+        except (KeyError, ValueError, IndexError):
             return message
src/claude_monitor/core/settings.py (1)

337-340: Locale is correctly propagated to i18n. Optionally sync the env var as well.

For consistency with env-driven detection, consider setting CLAUDE_MONITOR_LOCALE here too.

Apply this diff:

         from claude_monitor.i18n import set_locale
         set_locale(settings.locale)
+        # Keep environment in sync for downstream readers/child processes
+        import os
+        if settings.locale == "auto":
+            # Reflect the detected current locale
+            from claude_monitor.i18n import get_current_locale
+            os.environ["CLAUDE_MONITOR_LOCALE"] = get_current_locale()
+        else:
+            os.environ["CLAUDE_MONITOR_LOCALE"] = settings.locale
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1a518e5 and 522e3f2.

📒 Files selected for processing (4)
  • PULL_REQUEST_JP.md (1 hunks)
  • src/claude_monitor/cli/bootstrap.py (2 hunks)
  • src/claude_monitor/core/settings.py (4 hunks)
  • src/claude_monitor/i18n/messages.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/claude_monitor/cli/bootstrap.py
  • PULL_REQUEST_JP.md
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/claude_monitor/core/settings.py (1)
src/claude_monitor/i18n/messages.py (1)
  • set_locale (148-159)
🔇 Additional comments (4)
src/claude_monitor/i18n/messages.py (2)

11-19: Locale normalization and fallback are implemented correctly.

Env/system detection with normalization to 'en'/'ja' looks solid and aligns with the PR objectives.


40-145: i18n key parity verified

All 21 get_message() keys are present in both locales (37 keys each), with no missing or extra entries detected. No further action required.

src/claude_monitor/core/settings.py (2)

37-38: Persisting locale in last-used params is correct.

Ensures --locale sticks across runs as expected.


360-361: Wiring locale into the CLI namespace looks good.

Downstream consumers can now access args.locale.

- Add validate_locale field validator to normalize locale inputs
- Support case-insensitive input for locale values (e.g., 'EN', 'Ja' -> 'en', 'ja')
- Validate against allowed values: auto, en, ja
- Improve UX consistency with other validators (plan, view, theme)
- Return normalized lowercase values for consistent storage
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: 7

🧹 Nitpick comments (2)
README_JP.md (2)

1160-1160: Use a proper heading instead of bold text.

markdownlint flagged emphasis used as a heading (MD036). Prefer a heading level for accessibility and consistency.

Apply this diff:

-**⭐ 有用だと思ったらこのリポジトリにスターを付けてください! ⭐**
+### ⭐ 有用だと思ったらこのリポジトリにスターを付けてください! ⭐

992-1043: Minor clarity and safety improvements in troubleshooting.

  • When recommending pipx installation, on some distros the command is “sudo apt install pipx && pipx ensurepath”.
  • For the “break-system-packages” path, reiterate that uv/pipx/venv are preferred to avoid system conflicts.

Optional doc tweak; I can provide a small PR diff if you want.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 522e3f2 and cf90ef3.

📒 Files selected for processing (1)
  • README_JP.md (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
README_JP.md (1)
src/tests/examples/api_examples.py (1)
  • print_usage_summary (52-75)
🪛 markdownlint-cli2 (0.17.2)
README_JP.md

26-26: Link fragments should be valid

(MD051, link-fragments)


1160-1160: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (3)
README_JP.md (3)

1-12: Overall: Excellent JP localization and comprehensive README.

Well-structured, actionable, and aligned with the new i18n subsystem and CLI. Once the small inconsistencies above are addressed, this will be top-notch.


206-212: All CLI aliases are defined in packaging; no changes needed

  • pyproject.toml (lines 85–90) declares all five entry points:
    • claude-monitor
    • claude-code-monitor
    • cmonitor
    • ccmonitor
    • ccm

The README_JP.md listing matches these definitions—no doc or packaging updates required.


352-368: No locale-specific default override; docs are accurate
The code’s SystemTimeDetector.get_timezone() always auto-detects the system timezone (falling back to UTC) and there is no special case that defaults to Asia/Tokyo for Japanese locales. The README text—“デフォルトのタイムゾーンはシステムから自動検出されます”—correctly reflects the implementation.

If you do want to override to Asia/Tokyo when the locale is ja, that behavior would need to be added in the code; otherwise, you can leave this section as-is.

- 目次から存在しないセクションへのリンクを削除
- Proプランのトークン制限を44kから約19kに統一
- --localeオプションをCLIパラメータテーブルに追加
- デフォルトロケールの説明を「自動検出」に修正
- 開発者向けインストール手順をモジュール実行に修正
- 環境変数によるロケール設定の注記を追加
- インストール時の安全性に関する重要な注意書きを追加
- pipxインストール手順に`pipx ensurepath`を追加してPATH設定を確実化
- 強制インストール(--break-system-packages)の警告を強化
- システム保護と安定性の重要性をより明確に説明
- 推奨インストール方法(uv/pipx/venv)の重要性を強調

これらの変更により、ユーザーが安全で適切なインストール方法を選択できるようになり、
システムの安定性を保護できます。
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: 4

🔭 Outside diff range comments (3)
src/claude_monitor/core/settings.py (3)

300-317: Avoid possible NameError when clear_config is true; initialize cli_provided_fields unconditionally.

When clear_config is true and theme != "auto", the compound condition can evaluate the right side first and reference an undefined cli_provided_fields.

Place this initialization before the clear/else branches:

-        if clear_config:
+        cli_provided_fields = set()
+        if clear_config:
             last_used = LastUsedParams()
             last_used.clear()
             settings = cls(_cli_parse_args=argv)
         else:
-            last_used = LastUsedParams()
+            last_used = LastUsedParams()
             last_params = last_used.load()
 
             settings = cls(_cli_parse_args=argv)
 
-            cli_provided_fields = set()
             if argv:
                 for _i, arg in enumerate(argv):
                     if arg.startswith("--"):
                         field_name = arg[2:].replace("-", "_")
                         if field_name in cls.model_fields:
                             cli_provided_fields.add(field_name)

325-329: Treat timezone="local" the same as "auto" during resolution.

validate_timezone accepts "local", but resolution only handles "auto". Propagate to a concrete tz name to avoid downstream ambiguity.

-        if settings.timezone == "auto":
+        if settings.timezone == "auto":
             settings.timezone = cls._get_system_timezone()
+        elif settings.timezone == "local":
+            settings.timezone = cls._get_system_timezone()

284-289: Support the short version flag (-v) for version output.

Currently only --version is checked. Either also check '-v' pre-parse or check settings.version after parse.

Apply this diff for a minimal fix:

-        if argv and "--version" in argv:
+        if argv and (("--version" in argv) or ("-v" in argv)):
             print(f"claude-monitor {__version__}")
             import sys
             sys.exit(0)

Optionally add a post-parse guard:

# After settings = cls(_cli_parse_args=argv)
if settings.version:
    print(f"claude-monitor {__version__}")
    import sys
    sys.exit(0)
🧹 Nitpick comments (2)
README_JP.md (1)

1048-1050: Fix list indentation to satisfy markdownlint MD007.

Bullets are indented by 3 spaces; expected top-level bullets (indentation 0).

Apply this diff:

-   - この方法はシステム保護をバイパスし、他のPythonパッケージとの競合を引き起こす可能性があります
-   - システムの安定性に影響を与える可能性があります
-   - **絶対に推奨しません** - 代わりに上記のuv、pipx、または仮想環境の使用を強く推奨します
+- この方法はシステム保護をバイパスし、他のPythonパッケージとの競合を引き起こす可能性があります
+- システムの安定性に影響を与える可能性があります
+- **絶対に推奨しません** - 代わりに上記のuv、pipx、または仮想環境の使用を強く推奨します
src/claude_monitor/core/settings.py (1)

46-49: Nit: Write JSON with explicit UTF-8 encoding for portability.

Be explicit about encoding to avoid locale-dependent behavior on some systems.

-            with open(temp_file, "w") as f:
+            with open(temp_file, "w", encoding="utf-8") as f:
                 json.dump(params, f, indent=2)
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between cf90ef3 and d674099.

📒 Files selected for processing (2)
  • README_JP.md (1 hunks)
  • src/claude_monitor/core/settings.py (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: yamato-snow
PR: Maciek-roboblog/Claude-Code-Usage-Monitor#134
File: src/claude_monitor/core/settings.py:132-135
Timestamp: 2025-08-12T01:53:56.354Z
Learning: yamato-snow prefers to document feature implementations in Japanese, providing detailed bullet points about functionality, validation behavior, and UX consistency improvements.
📚 Learning: 2025-08-12T01:53:56.354Z
Learnt from: yamato-snow
PR: Maciek-roboblog/Claude-Code-Usage-Monitor#134
File: src/claude_monitor/core/settings.py:132-135
Timestamp: 2025-08-12T01:53:56.354Z
Learning: yamato-snow prefers to document feature implementations in Japanese, providing detailed bullet points about functionality, validation behavior, and UX consistency improvements.

Applied to files:

  • src/claude_monitor/core/settings.py
🧬 Code Graph Analysis (1)
src/claude_monitor/core/settings.py (1)
src/claude_monitor/i18n/messages.py (1)
  • set_locale (148-159)
🪛 markdownlint-cli2 (0.17.2)
README_JP.md

1048-1048: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


1049-1049: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


1050-1050: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

🔇 Additional comments (6)
README_JP.md (3)

336-353: LGTM: Locale section matches runtime design (auto-detect default + en/ja overrides).

The wording correctly reflects auto-detect as default, with explicit overrides via --locale and CLAUDE_MONITOR_LOCALE.


357-371: PR description vs docs/code: default timezone is auto-detected, not Asia/Tokyo.

The PR objectives mention “default timezone set to Asia/Tokyo,” but code/docs state auto-detect. Keep docs as-is (auto), and update the PR description to avoid confusion.

Would you like me to update the PR description text to explicitly say “default timezone = auto-detected; examples show Asia/Tokyo for Japan users”?


207-215: All CLI aliases are correctly exposed
Verified that pyproject.toml under [project.scripts] defines all five commands—claude-monitor, claude-code-monitor, cmonitor, ccmonitor, and ccm—matching the README. No changes required.

src/claude_monitor/core/settings.py (3)

37-37: LGTM: Persisting locale in last_used.json.

This ensures --locale preference carries across runs and aligns with other persisted fields.


132-135: LGTM: New locale setting (auto/en/ja) with auto-detect default.

Matches the docs and i18n design; default “auto” is appropriate.


221-234: LGTM: Case-insensitive validator for locale.

Consistent with other validators; normalizes to lowercase and enforces allowed values.

- README_JP.md: --viewパラメータにsessionオプションを追加
- README_JP.md: custom_maxモードをcustom(P90自動検出)に修正
- README_JP.md: Windows実行コマンドをpython -m claude_monitorに修正
- settings.py: CLAUDE_MONITOR_LOCALE環境変数のサポートを実装

これらの修正により、ドキュメントとコードの整合性が向上し、
環境変数によるロケール設定が正しく動作するようになりました。
- cli_provided_fieldsをclear_config判定前に初期化
- clear_config=Trueの場合でもcli_provided_fieldsが定義されるように修正
- 潜在的なNameErrorを完全に回避

これにより、--clearオプション使用時にも安全に動作するようになりました。
- README.md: すべての./claude_monitor.pyをclaude-monitorまたはpython -m claude_monitorに修正
- README.md: chmod +xコマンドを削除(モジュールランナーでは不要)
- CONTRIBUTING.md: 古いchmodコマンドを削除し、モジュールランナーの説明に変更
- 開発モードでの実行コマンドを統一

これにより、ドキュメントが現在のモジュラーアーキテクチャと一致し、
ユーザーが正しいコマンドを使用できるようになりました。
- LastUsedParamsクラス内のparams_fileを開く際に、UTF-8エンコーディングを明示的に指定
- これにより、異なる環境での文字化けを防ぎ、ファイルの整合性を向上させる

この変更により、設定ファイルの読み書きがより安全に行えるようになります。
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

🔭 Outside diff range comments (1)
README.md (1)

187-203: Document the new --locale option in the parameters table

The PR introduces a --locale CLI option and env override, but the parameters table doesn’t list it. Add a row for visibility and parity with Settings.

Apply this addition to the table:

 | --time-format | string | auto | Time format: 12h, 24h, or auto |
+| --locale | string | auto | Language: auto (system), en (English), ja (Japanese) |
 | --theme | string | auto | Display theme: light, dark, classic, or auto |
♻️ Duplicate comments (1)
src/claude_monitor/core/settings.py (1)

221-234: Case-insensitive locale validation is solid and consistent

Lowercasing inputs and validating against the allowed set aligns with the other validators and avoids surprising behavior.

This addresses the earlier review suggestion confirming normalization and validation behavior.

🧹 Nitpick comments (4)
src/claude_monitor/core/settings.py (2)

127-131: Clarify timezone description to mention both “auto” and “local” sentinels

The validator accepts "auto" and "local". The field description only mentions auto-detection and doesn’t mention "local". Minor doc tweak will prevent confusion.

Apply this small wording change:

-        description="Timezone for display (auto-detected from system). Examples: UTC, America/New_York, Europe/London, Asia/Tokyo, Australia/Sydney",
+        description="Timezone for display. Use 'auto' to detect from system or 'local' to use OS local time. Examples: UTC, America/New_York, Europe/London, Asia/Tokyo, Australia/Sydney",

352-363: Locale application order (CLI > env > saved/default) is correct; add a debug log of the effective locale

The runtime wiring is correct and matches the documented precedence. To aid debugging, log the effective locale that gets applied.

         env_locale = os.getenv("CLAUDE_MONITOR_LOCALE")
         # CLI > env > last-used/default
         if env_locale and env_locale.strip() and ("locale" not in cli_provided_fields):
             # Allow broader formats like 'ja_JP'/'en-US' here; i18n.set_locale normalizes.
-            set_locale(env_locale)
+            set_locale(env_locale)
+            logger.debug(f"Applied locale from env: {env_locale}")
         else:
-            set_locale(settings.locale)
+            set_locale(settings.locale)
+            logger.debug(f"Applied locale from settings: {settings.locale}")

Note: This block’s correctness depends on fixing CLI field detection for --locale=ja (see Lines 292-300).

README.md (2)

226-234: Include “Locale” in the saved preferences list

Locale is persisted via LastUsedParams.save() and restored in load_with_last_used(). Reflect that under “What Gets Saved”.

 - Time format (--time-format)
+- Locale (--locale)
 - Refresh rates (--refresh-rate, --refresh-per-second)

344-360: Add a short “Localization” subsection with CLI and env examples

To make localization discoverable, include concise examples for both CLI option and env override with precedence (CLI > env). Given your preference for thorough JP documentation, consider mirroring this in README_JP.md as well.

Proposed text to insert after “Timezone Configuration”:

#### Localization

You can control the UI language via CLI or environment variable:

- CLI (takes precedence): claude-monitor --locale ja  # or en, auto
- Environment variable: CLAUDE_MONITOR_LOCALE=ja_JP claude-monitor

Notes:
- CLI accepts: auto, en, ja
- Env var accepts broader forms (e.g., ja_JP, en-US) and is normalized automatically
- Precedence: CLI > CLAUDE_MONITOR_LOCALE > saved/default

If you want, I can open a small doc PR snippet for both EN and JP READMEs.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d674099 and 1aa28ac.

📒 Files selected for processing (4)
  • CONTRIBUTING.md (1 hunks)
  • README.md (9 hunks)
  • README_JP.md (1 hunks)
  • src/claude_monitor/core/settings.py (6 hunks)
✅ Files skipped from review due to trivial changes (1)
  • CONTRIBUTING.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • README_JP.md
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: yamato-snow
PR: Maciek-roboblog/Claude-Code-Usage-Monitor#134
File: src/claude_monitor/core/settings.py:132-135
Timestamp: 2025-08-12T01:53:56.354Z
Learning: yamato-snow prefers to document feature implementations in Japanese, providing detailed bullet points about functionality, validation behavior, and UX consistency improvements.
📚 Learning: 2025-08-12T01:53:56.354Z
Learnt from: yamato-snow
PR: Maciek-roboblog/Claude-Code-Usage-Monitor#134
File: src/claude_monitor/core/settings.py:132-135
Timestamp: 2025-08-12T01:53:56.354Z
Learning: yamato-snow prefers to document feature implementations in Japanese, providing detailed bullet points about functionality, validation behavior, and UX consistency improvements.

Applied to files:

  • src/claude_monitor/core/settings.py
🧬 Code Graph Analysis (2)
README.md (1)
src/claude_monitor/cli/main.py (4)
  • _run_monitoring (110-260)
  • main (72-107)
  • on_data_update (175-204)
  • on_session_change (210-217)
src/claude_monitor/core/settings.py (1)
src/claude_monitor/i18n/messages.py (1)
  • set_locale (148-159)
🔇 Additional comments (4)
src/claude_monitor/core/settings.py (3)

37-37: Persisting locale in LastUsedParams looks correct

Locale is now saved alongside other persisted settings. This unblocks keeping user preference across runs.


132-135: New locale field (auto/en/ja) is well-scoped and documented

Defaulting to 'auto' and constraining accepted values matches the i18n subsystem. Good placement near timezone/time format.


383-384: Exposing locale via to_namespace is good for downstream consumers

Makes the effective locale reachable by CLI/main orchestration and UI components.

README.md (1)

600-604: LGTM: CLI invocation standardized to claude-monitor and module runner

The updated examples consistently use the public entrypoint and python -m for dev/aliases. This reduces confusion across OSes and install methods.

Also applies to: 617-621, 739-739, 762-762, 966-970, 986-988, 999-1000, 1140-1140

- --flag=value形式の引数を正しく解析するよう修正
- --no-flag形式の否定ブールフラグをサポート
- CLI提供フィールドの検出精度を向上
- 設定の優先順位チェックが正常に動作するよう改善

Fixes: --locale=jaなどの引数が正しく認識されない問題
- README.md/README_JP.mdに--localeオプションをパラメータテーブルに追加
- 保存設定リストにLocale項目を追加
- Localizationセクションを追加(CLI/環境変数の使用例と優先順位)
- settings.pyのタイムゾーン説明を改善(auto/localの説明を追加)
- ロケール適用時のデバッグログを追加

CodeRabbitレビューコメントに対応:
- パラメータテーブルの可視性向上
- タイムゾーン説明の明確化
- デバッグログの追加
- ドキュメントの完全性向上
- `messages.py`において、アクティブセッションが見つからないメッセージを日本語に翻訳
- 新しいUIメッセージを追加し、セッション表示コンポーネントでの表示を改善
- トークン、コスト、メッセージに関する表示を日本語に対応させ、ユーザー体験を向上させる

これにより、アプリケーションのローカライズが進み、日本語話者にとっての使いやすさが向上しました。
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

🔭 Outside diff range comments (7)
README.md (5)

289-291: Fix Pro plan token example (~44,000 → ~19,000).

Docs elsewhere (tables) use ~19,000 for Pro. Keep examples consistent.

-# Pro plan (~44,000 tokens)
+# Pro plan (~19,000 tokens)

416-419: Standardize “Updated Plan Limits” values (44k → 19k for Pro).

This line contradicts the plan tables and JP docs.

-**Updated Plan Limits**: Pro (44k), Max5 (88k), Max20 (220k) tokens
+**Updated Plan Limits**: Pro (~19k), Max5 (88k), Max20 (220k) tokens

586-593: Replace “custom_max mode” and remove “default Pro” wording.

  • “custom_max” isn’t a valid plan name.
  • Pro isn’t the default anymore (default is custom).
-When using the default Pro plan:
+When using the Pro plan:
@@
-3. **Switch**: Automatically changes to custom_max mode
+3. **Switch**: Automatically changes to custom (P90 auto-detection)

646-652: Replace invalid “custom_max” usage examples with “custom”.

The CLI doesn’t accept “custom_max”. Use “custom” (P90 auto-detect).

-claude-monitor --plan custom_max
+claude-monitor --plan custom
@@
-claude-monitor --plan custom_max --reset-hour 6
+claude-monitor --plan custom --reset-hour 6

186-204: Replace all remaining ‘custom_max’ references with ‘custom’

The plan name has been standardized to custom. Please update these outdated occurrences to align docs and examples with the current CLI behavior:

• README_JP.md (line 723):

  • “自動的にcustom_maxに切り替え” → “自動的にcustomに切り替え”

• README.md:

  • line 590: “Automatically changes to custom_max mode” → “custom mode”
  • lines 648 & 651: claude-monitor --plan custom_maxclaude-monitor --plan custom
  • line 722: “Automatically switches to custom_max if needed” → “custom if needed”
  • line 738: claude-monitor --plan custom_maxclaude-monitor --plan custom

• CONTRIBUTING.md (line 375):

  • “Maximum tokens reached (custom_max value)” → “(custom value)”

You can batch-apply these changes with:

rg -l 'custom_max' | xargs sed -i 's/custom_max/custom/g'
src/claude_monitor/ui/session_display.py (2)

86-94: Bug: Incorrect private API usage (_calculate_filled_segments called with 2 args).

TokenProgressBar._calculate_filled_segments takes a single percentage argument (see usages in progress_bars). Passing two arguments will raise a TypeError.

Apply this fix:

-        filled = progress_bar._calculate_filled_segments(capped_percentage, 100.0)
+        filled = progress_bar._calculate_filled_segments(capped_percentage)

195-213: Increase i18n coverage: replace hard-coded labels with localized messages.

Several UI labels remain hard-coded in English, reducing the benefit of the i18n system. Replace with get_message lookups to align with JP/EN locales.

-            screen_buffer.append(
-                f"{get_message('ui.cost_usage')}           {cost_bar} {cost_percentage:4.1f}%    [value]${session_cost:.2f}[/] / [dim]${cost_limit_p90:.2f}[/]"
-            )
+            screen_buffer.append(
+                f"{get_message('ui.cost_usage')}           {cost_bar} {cost_percentage:4.1f}%    [value]${session_cost:.2f}[/] / [dim]${cost_limit_p90:.2f}[/]"
+            )
@@
-            screen_buffer.append(
-                f"{get_message('ui.token_usage')}          {token_bar} {usage_percentage:4.1f}%    [value]{tokens_used:,}[/] / [dim]{token_limit:,}[/]"
-            )
+            screen_buffer.append(
+                f"{get_message('ui.token_usage')}          {token_bar} {usage_percentage:4.1f}%    [value]{tokens_used:,}[/] / [dim]{token_limit:,}[/]"
+            )
@@
-            screen_buffer.append(
-                f"{get_message('ui.messages_usage')}       {messages_bar} {messages_percentage:4.1f}%    [value]{sent_messages}[/] / [dim]{messages_limit_p90:,}[/]"
-            )
+            screen_buffer.append(
+                f"{get_message('ui.messages_usage')}       {messages_bar} {messages_percentage:4.1f}%    [value]{sent_messages}[/] / [dim]{messages_limit_p90:,}[/]"
+            )
@@
-            screen_buffer.append(
-                f"{get_message('ui.time_to_reset')}       {time_bar} {time_left_hours}h {time_left_mins}m"
-            )
+            screen_buffer.append(
+                f"{get_message('ui.time_to_reset')}       {time_bar} {time_left_hours}h {time_left_mins}m"
+            )
@@
-                screen_buffer.append(f"{get_message('ui.model_distribution')}   {model_bar}")
+                screen_buffer.append(f"{get_message('ui.model_distribution')}   {model_bar}")
@@
-            screen_buffer.append(
-                f"{get_message('ui.burn_rate')}              [warning]{burn_rate:.1f}[/] [dim]{get_message('ui.tokens_per_minute')}[/] {velocity_emoji}"
-            )
+            screen_buffer.append(
+                f"{get_message('ui.burn_rate')}              [warning]{burn_rate:.1f}[/] [dim]{get_message('ui.tokens_per_minute')}[/] {velocity_emoji}"
+            )
@@
-            screen_buffer.append(
-                f"{get_message('ui.cost_rate')}              {cost_per_min_display} [dim]{get_message('ui.dollars_per_minute')}[/]"
-            )
+            screen_buffer.append(
+                f"{get_message('ui.cost_rate')}              {cost_per_min_display} [dim]{get_message('ui.dollars_per_minute')}[/]"
+            )
@@
-            screen_buffer.append(f"💲 [value]Session Cost:[/]   {cost_display}")
+            screen_buffer.append(f"💰 [value]{get_message('ui.cost_usage')}[/]   {cost_display}")
@@
-            screen_buffer.append(f"📊 [value]Token Usage:[/]    {token_bar}")
+            screen_buffer.append(f"📊 [value]{get_message('ui.token_usage')}[/]    {token_bar}")
@@
-            screen_buffer.append(
-                f"🔥 [value]Burn Rate:[/]      [warning]{burn_rate:.1f}[/] [dim]{get_message('ui.tokens_per_minute')}[/] {velocity_emoji}"
-            )
+            screen_buffer.append(
+                f"🔥 [value]{get_message('ui.burn_rate')}[/]      [warning]{burn_rate:.1f}[/] [dim]{get_message('ui.tokens_per_minute')}[/] {velocity_emoji}"
+            )
@@
-            screen_buffer.append(
-                f"📨 [value]Sent Messages:[/]  [info]{sent_messages}[/] [dim]{get_message('ui.messages')}[/]"
-            )
+            screen_buffer.append(
+                f"📨 [value]{get_message('ui.messages_usage')}[/]  [info]{sent_messages}[/]"
+            )
@@
-            screen_buffer.append(f"⏱️  [value]Time to Reset:[/]  {time_bar}")
+            screen_buffer.append(f"⏱️  [value]{get_message('ui.time_to_reset')}[/]  {time_bar}")
@@
-        screen_buffer.append(f"{get_message('ui.predictions')}")
+        screen_buffer.append(f"{get_message('ui.predictions')}")

Note: If you prefer “Sent Messages” as a label distinct from “Messages Usage”, add a new i18n key (e.g., ui.sent_messages) in messages.py and reference it here.

I can prepare the messages.py updates (en/ja) for any new keys you choose.

Also applies to: 216-221, 227-231, 243-245, 247-253, 255-259, 265-269, 277-281, 283-286, 287-299, 306-311, 312-314, 331-333

♻️ Duplicate comments (1)
README_JP.md (1)

716-725: Replace invalid “custom_max” plan name with “custom”.

The codebase recognizes plans: pro, max5, max20, custom. “custom_max” will mislead users.

Apply this diff:

- - 必要に応じて自動的にcustom_maxに切り替え
+ - 必要に応じて自動的にcustom(P90自動検出)に切り替え
🧹 Nitpick comments (6)
README_JP.md (2)

1060-1064: Fix markdownlint MD007: adjust bullet indentation under the warning block.

The unordered list under “重大な警告” is indented by 3 spaces, violating MD007 (Expected: 0 or 2). Dedent the bullets to align with markdownlint defaults.

Apply this diff:

-   ⚠️ **重大な警告**: 
-   - この方法はシステム保護をバイパスし、他のPythonパッケージとの競合を引き起こす可能性があります
-   - システムの安定性に影響を与える可能性があります
-   - **絶対に推奨しません** - 代わりに上記のuv、pipx、または仮想環境の使用を強く推奨します
+⚠️ **重大な警告**:
+- この方法はシステム保護をバイパスし、他のPythonパッケージとの競合を引き起こす可能性があります
+- システムの安定性に影響を与える可能性があります
+- **絶対に推奨しません** - 代わりに上記のuv、pipx、または仮想環境の使用を強く推奨します

591-599: Correct default plan wording (“Pro” is no longer the default).

v3.0.0 changed the default plan to “custom”. This section still says “デフォルトのProプラン”. Clarify to avoid contradictions.

-デフォルトのProプランを使用している場合:
+Proプランを使用している場合:
README.md (2)

187-196: Document all accepted --view values (include “session”).

Settings support “session” in addition to realtime/daily/monthly. Update the table for consistency.

-| --view | string | realtime | View type: realtime, daily, or monthly |
+| --view | string | realtime | View type: realtime, daily, monthly, or session |

614-618: Use canonical timezone “America/New_York” instead of legacy alias.

For consistency with earlier examples and across docs, prefer “America/New_York” to “US/Eastern”.

-claude-monitor --reset-hour 9 --timezone US/Eastern
+claude-monitor --reset-hour 9 --timezone America/New_York
src/claude_monitor/i18n/messages.py (1)

31-35: Optional: future-proof getdefaultlocale() deprecation.

locale.getdefaultlocale() is deprecated in recent Python versions. Consider locale.getlocale()[0] or parsing LANG as you already do.

-    try:
-        loc = locale.getdefaultlocale()[0] or ""
-    except Exception:
-        loc = ""
+    try:
+        # Prefer getlocale to avoid deprecation; falls back to env parsing above
+        loc = (locale.getlocale()[0] or "")
+    except Exception:
+        loc = ""
src/claude_monitor/ui/session_display.py (1)

405-419: Localize the “no active session” screen labels for consistency.

A few labels are still hard-coded.

-        screen_buffer.append(f"📊 [value]Token Usage:[/]    {empty_token_bar}")
+        screen_buffer.append(f"📊 [value]{get_message('ui.token_usage')}[/]    {empty_token_bar}")
@@
-        screen_buffer.append(
-            f"🔥 [value]Burn Rate:[/]      [warning]0.0[/] [dim]{get_message('ui.tokens_per_minute')}[/]"
-        )
+        screen_buffer.append(
+            f"🔥 [value]{get_message('ui.burn_rate')}[/]      [warning]0.0[/] [dim]{get_message('ui.tokens_per_minute')}[/]"
+        )
@@
-        screen_buffer.append(
-            f"💲 [value]Cost Rate:[/]      [cost.low]$0.00[/] [dim]{get_message('ui.dollars_per_minute')}[/]"
-        )
+        screen_buffer.append(
+            f"💲 [value]{get_message('ui.cost_rate')}[/]      [cost.low]$0.00[/] [dim]{get_message('ui.dollars_per_minute')}[/]"
+        )
@@
-        screen_buffer.append(f"📨 [value]Sent Messages:[/]  [info]0[/] [dim]{get_message('ui.messages')}[/]")
+        screen_buffer.append(f"📨 [value]{get_message('ui.messages_usage')}[/]  [info]0[/]")

Also applies to: 431-441

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1aa28ac and f5efd2a.

📒 Files selected for processing (5)
  • README.md (12 hunks)
  • README_JP.md (1 hunks)
  • src/claude_monitor/core/settings.py (7 hunks)
  • src/claude_monitor/i18n/messages.py (1 hunks)
  • src/claude_monitor/ui/session_display.py (13 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/claude_monitor/core/settings.py
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: yamato-snow
PR: Maciek-roboblog/Claude-Code-Usage-Monitor#134
File: src/claude_monitor/core/settings.py:132-135
Timestamp: 2025-08-12T01:53:56.354Z
Learning: yamato-snow prefers to document feature implementations in Japanese, providing detailed bullet points about functionality, validation behavior, and UX consistency improvements.
🧬 Code Graph Analysis (2)
src/claude_monitor/ui/session_display.py (4)
src/claude_monitor/i18n/messages.py (1)
  • get_message (195-217)
src/claude_monitor/ui/components.py (4)
  • render (44-58)
  • render (65-77)
  • VelocityIndicator (14-58)
  • get_velocity_emoji (18-28)
src/claude_monitor/ui/progress_bars.py (5)
  • render (43-45)
  • render (156-163)
  • render (185-221)
  • render (227-250)
  • render (256-333)
src/claude_monitor/ui/display_controller.py (1)
  • SessionCalculator (574-676)
README_JP.md (1)
src/tests/examples/api_examples.py (1)
  • print_usage_summary (52-75)
🪛 markdownlint-cli2 (0.17.2)
README_JP.md

1061-1061: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


1062-1062: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)


1063-1063: Unordered list indentation
Expected: 0; Actual: 3

(MD007, ul-indent)

🔇 Additional comments (9)
README_JP.md (2)

337-354: LGTM: Locale docs are accurate and aligned with implementation.

The description of auto-detect default, CLI/env precedence, and normalization matches src/claude_monitor/i18n/messages.py.


178-186: LGTM: --locale option documented correctly in CLI table.

The table and the note below (“CLAUDE_MONITOR_LOCALE…”) align with CLI and i18n behavior.

README.md (4)

194-196: LGTM: Added --locale option to CLI table.

Accurately documents accepted values and default behavior.


345-356: LGTM: Localization section is clear and matches runtime behavior.

The precedence, accepted forms, and normalization notes are accurate.


980-984: LGTM: Development and alias instructions consistently use module runner or CLI.

This avoids implying a top-level claude_monitor.py script exists.

Also applies to: 1000-1002, 1013-1014


1153-1154: LGTM: Troubleshooting snippet uses CLI with CLAUDE_CONFIG_DIR.

Matches guidance across the docs.

src/claude_monitor/i18n/messages.py (2)

11-37: LGTM: Robust locale detection and normalization.

  • Honors CLAUDE_MONITOR_LOCALE, LC_ALL/LC_MESSAGES/LANG, then system locale.
  • Normalizes variants and falls back to English safely.

195-217: LGTM: get_message fallback to English and safe formatting.

Correctly avoids leaking raw keys and handles formatting errors gracefully.

src/claude_monitor/ui/session_display.py (1)

360-373: LGTM: Notifications now localized.

These use get_message keys and will work across locales.

- session.no_active_sessionを日本語から英語に修正
- 英語ロケールで正しい英語メッセージが表示されるように修正
- `messages.py`に新しいUIメッセージを追加し、セッション表示コンポーネントでの表示を改善
- トークン、コスト、メッセージに関するラベルを追加し、ユーザー体験を向上させる

これにより、アプリケーションのローカライズが進み、ユーザーにとっての使いやすさが向上しました。
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 (3)
src/claude_monitor/i18n/messages.py (3)

26-29: Honor the LANGUAGE environment variable (common on Linux) in detection

Many Linux distros set LANGUAGE (e.g., “ja_JP:en_US:en”). Checking it improves auto-detection accuracy.

Apply this diff:

-    # Common POSIX locale envs
-    for var in ("LC_ALL", "LC_MESSAGES", "LANG"):
+    # Common POSIX locale envs (LANGUAGE is widely used on Linux)
+    for var in ("LC_ALL", "LC_MESSAGES", "LANGUAGE", "LANG"):
         v = os.environ.get(var)
         if v:
             return _normalize_locale(v)

7-10: Prevent accidental mutation of MESSAGES by making it read-only

Freezing the messages mapping avoids accidental runtime mutation from other modules and clarifies API boundaries.

Apply this diff:

 import os
 import locale
-from typing import Dict, Any
+from typing import Any, Dict, Mapping, Final
+from types import MappingProxyType
@@
-# Message translations
-MESSAGES = {
+# Message translations (read-only)
+MESSAGES: Final[Mapping[str, Dict[str, str]]] = MappingProxyType({
@@
-    }
-}
+    }
+})

Also applies to: 39-41, 186-187


223-235: Guarantee get_message returns a string even if a non-string slips into MESSAGES

Type hint says str but a non-string value would currently propagate. Safeguard by converting non-strings to str before formatting/return.

Apply this diff:

     messages = MESSAGES.get(_current_locale, MESSAGES["en"])
     message = messages.get(key)
     if message is None:
         # Fallback to English if the key is missing in the active locale
         message = MESSAGES["en"].get(key, key)
 
-    if kwargs and isinstance(message, str):
+    if not isinstance(message, str):
+        return str(message)
+
+    if kwargs:
         try:
             return message.format(**kwargs)
         except (KeyError, ValueError):
             return message
     
     return message
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2d4d7be and f3948e3.

📒 Files selected for processing (2)
  • src/claude_monitor/i18n/messages.py (1 hunks)
  • src/claude_monitor/ui/session_display.py (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/claude_monitor/ui/session_display.py
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: yamato-snow
PR: Maciek-roboblog/Claude-Code-Usage-Monitor#134
File: src/claude_monitor/core/settings.py:132-135
Timestamp: 2025-08-12T01:53:56.354Z
Learning: yamato-snow prefers to document feature implementations in Japanese, providing detailed bullet points about functionality, validation behavior, and UX consistency improvements.
📚 Learning: 2025-08-12T01:53:56.354Z
Learnt from: yamato-snow
PR: Maciek-roboblog/Claude-Code-Usage-Monitor#134
File: src/claude_monitor/core/settings.py:132-135
Timestamp: 2025-08-12T01:53:56.354Z
Learning: yamato-snow prefers to document feature implementations in Japanese, providing detailed bullet points about functionality, validation behavior, and UX consistency improvements.

Applied to files:

  • src/claude_monitor/i18n/messages.py
🔇 Additional comments (2)
src/claude_monitor/i18n/messages.py (2)

190-202: LGTM: Public i18n API and fallback semantics are solid

  • set_locale supports 'auto' and normalization with correct fallback to English.
  • get_message falls back to English on missing keys and safely formats kwargs.
  • Defaults are environment/system-driven and normalized to 'en'/'ja'.

Also applies to: 213-235


31-35: Clarify Python version support before refactoring locale logic

The project’s pyproject.toml only declares “Programming Language :: Python :: 3” (no python_requires or specific minor versions), so it’s unclear whether you intend to support Python 3.15+ (where locale.getdefaultlocale() is deprecated).

• Add an explicit python_requires to pyproject.toml to pin your supported Python range.
• If you plan to adopt Python 3.15 or later soon, apply the suggested refactor in src/claude_monitor/i18n/messages.py—using locale.getlocale() first, then falling back to locale.getdefaultlocale().
• Otherwise, postponing this change until you upgrade will avoid unnecessary churn today.

@PabloLION
Copy link

@coderabbitai is this referencing #73?

@coderabbitai
Copy link

coderabbitai bot commented Aug 19, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for any references to #73 in the current PR files
echo "Searching for references to #73 in the codebase..."
rg -n "#73" --type=md --type=py

echo -e "\nSearching for issue references more broadly..."
rg -n "issue.*73|#73|73" --type=md --type=py -C2

echo -e "\nSearching for any GitHub issue references..."
rg -n "#[0-9]+" --type=md --type=py -C1

Length of output: 2836


External tools search results:

I apologize, but I wasn't able to retrieve information about issue #73 from the external tools. Let me try to get more information about this issue using GitHub CLI.


🏁 Script executed:

#!/bin/bash
# Try to get information about issue #73 using GitHub CLI
echo "Attempting to get information about issue #73..."
gh issue view 73 --repo Maciek-roboblog/Claude-Code-Usage-Monitor || echo "Could not retrieve issue #73"

echo -e "\nListing recent issues to see if #73 exists..."
gh issue list --repo Maciek-roboblog/Claude-Code-Usage-Monitor --limit 20 --state all

Length of output: 3834


@PabloLION Based on my search, there are no direct references to issue #73 in this PR's code or documentation. However, there is definitely a conceptual relationship.

Issue #73 (by GiGiDKR) proposes "Add multilingual support (i18n)" with:

  • Support for 4 languages: English, French, Spanish, German
  • gettext-based internationalization system
  • CLI --language/--lang options
  • Environment variable detection (LANG)

This PR #134 implements:

  • Japanese localization specifically
  • Custom i18n module (not gettext-based)
  • CLI --locale option
  • Environment variable CLAUDE_MONITOR_LOCALE

Both address internationalization but with different approaches:

While not explicitly referencing #73, this PR essentially implements a competing/alternative i18n solution. You might want to consider how these two approaches should be coordinated - whether to merge them, choose one, or maintain both systems.


🧠 Learnings used
Learnt from: yamato-snow
PR: Maciek-roboblog/Claude-Code-Usage-Monitor#134
File: src/claude_monitor/core/settings.py:132-135
Timestamp: 2025-08-12T01:53:56.377Z
Learning: yamato-snow prefers to document feature implementations in Japanese, providing detailed bullet points about functionality, validation behavior, and UX consistency improvements.

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