Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,6 @@ ClaudeUsageMonitor
*~
*.bak
*.backup

.claude
CLAUDE.md
1 change: 1 addition & 0 deletions .serena/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/cache
71 changes: 71 additions & 0 deletions .serena/memories/code_style_conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Code Style and Conventions

## Swift Style

### Formatting
- **Indentation**: 4 spaces (no tabs)
- **Line length**: No strict limit, but keep reasonable
- **File size**: Target 300-600 lines per file

### Naming
- **Types**: PascalCase (e.g., `MenuBarManager`, `UserSettings`)
- **Functions/Methods**: camelCase (e.g., `updateMenuBarIcon()`, `setupDataBindings()`)
- **Variables/Properties**: camelCase (e.g., `usageData`, `isLoading`)
- **Constants**: camelCase (e.g., `defaultTimeout`)

### Code Organization
Use `// MARK: -` sections to organize code:
```swift
// MARK: - Properties
// MARK: - Initialization
// MARK: - Public Methods
// MARK: - Private Methods
```

### Documentation
- Code comments in Chinese or English are acceptable (existing codebase uses Chinese)
- DocC-style comments for public APIs:
```swift
/// 刷新状态管理器
/// 用于在视图间同步刷新状态,支持响应式更新
class RefreshState: ObservableObject { ... }
```

## Localization

### Type-Safe Access
Use `LocalizationHelper.swift` for all UI strings:
```swift
L.Menu.settings // Menu items
L.Usage.title // Usage-related text
L.Settings.general // Settings labels
```

### Adding New Strings
When adding UI text, update ALL 5 language files:
- `Resources/en.lproj/Localizable.strings`
- `Resources/ja.lproj/Localizable.strings`
- `Resources/zh-Hans.lproj/Localizable.strings`
- `Resources/zh-Hant.lproj/Localizable.strings`
- `Resources/ko.lproj/Localizable.strings`

## Design Patterns

### Colors
Use `ColorScheme.swift` for all usage-related colors:
- 5-hour limit: green → orange → red progression
- 7-day limit: purple gradient

### Data Storage
- **Sensitive data** (session keys): `KeychainManager`
- **User preferences**: `UserSettings` (UserDefaults)

### Refresh Logic
`DataRefreshManager` implements 4-level adaptive refresh based on usage activity.

## Commit Messages
- Format: Conventional commits (`feat:`, `fix:`, `docs:`, `style:`, `refactor:`, `perf:`, `test:`, `chore:`)
- Concise messages
- No emojis
- No co-authoring footers
- Include `[release]` to trigger GitHub Actions release
42 changes: 42 additions & 0 deletions .serena/memories/project_overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Usage4Claude - Project Overview

## Purpose
Usage4Claude is a native macOS menu bar application that monitors Claude AI usage quotas in real-time. It tracks usage across all Claude platforms: Web, Claude Code, Desktop, and Mobile App.

## Tech Stack
- **Language**: Swift 5.0+
- **Frameworks**: SwiftUI + AppKit (hybrid approach)
- **Platform**: macOS 13.0+ (Ventura and later)
- **IDE**: Xcode 15.0+
- **Dependencies**: Zero third-party dependencies (fully native)

## Architecture
MVVM pattern with 4 core classes:

1. **MenuBarManager** (App/) - Coordination layer, manages UI↔data binding
2. **MenuBarUI** (App/) - Menu bar icon, popover, and click handling
3. **MenuBarIconRenderer** (App/) - Renders ring indicators with usage percentages
4. **DataRefreshManager** (Helpers/) - Smart 4-level adaptive refresh logic

### Data Flow
```
ClaudeAPIService → DataRefreshManager → MenuBarManager → MenuBarUI → MenuBarIconRenderer
```

## Directory Structure
```
Usage4Claude/
├── App/ # Core app: MenuBarManager, MenuBarUI, MenuBarIconRenderer
├── Views/ # SwiftUI views (Settings, UsageDetail, Welcome)
├── Models/ # UserSettings, DiagnosticReport
├── Services/ # ClaudeAPIService, KeychainManager, UpdateChecker
├── Helpers/ # DataRefreshManager, LocalizationHelper, ColorScheme, TimerManager
└── Resources/ # Assets + localization strings (en, ja, zh-Hans, zh-Hant, ko)
```

## Key Features
- Real-time usage monitoring
- Multi-limit support (5-hour/7-day/Extra)
- Smart 4-level adaptive refresh (1/3/5/10 min)
- 5 language support (English, Japanese, Chinese Simplified/Traditional, Korean)
- Native macOS experience with no external dependencies
72 changes: 72 additions & 0 deletions .serena/memories/suggested_commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Suggested Commands for Usage4Claude

## Build Commands

### Open in Xcode
```bash
open Usage4Claude.xcodeproj
```
Then press Cmd+R to build and run.

### Build Release with DMG
```bash
# Standard release build (clean + build + DMG)
./scripts/build.sh

# Skip clean step (faster rebuilds)
./scripts/build.sh --no-clean

# Debug build
./scripts/build.sh --config Debug

# Verbose output (show full xcodebuild logs)
./scripts/build.sh --verbose
```

**Note**: DMG creation requires `create-dmg`:
```bash
brew install create-dmg
```

### Build Output
Release artifacts are placed in:
```
build/Usage4Claude-Release-{version}/Usage4Claude-v{version}.dmg
```

## Development Commands

### View Build Logs
```bash
# After a build failure
tail -n 50 build/Usage4Claude-Release-*/build.log
```

### Clean Build Artifacts
```bash
rm -rf build/
```

## Git Commands
```bash
# Standard git operations
git status
git add .
git commit -m "feat: description"
git push

# View recent commits
git log --oneline -10

# GitHub CLI for PRs
gh pr create --title "Title" --body "Description"
```

## Testing
No automated test suite. Manual testing:
- Enable Debug Mode in Settings for fake data
- Test on both Intel and Apple Silicon Macs
- Verify 0 compilation warnings

## Release
Include `[release]` in commit message to trigger GitHub Actions release workflow.
43 changes: 43 additions & 0 deletions .serena/memories/task_completion_checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Task Completion Checklist

When completing a coding task, verify the following:

## Before Committing

### Code Quality
- [ ] No compilation warnings (Swift 6 concurrent mode compliant)
- [ ] Code follows existing patterns and conventions
- [ ] No over-engineering or unnecessary abstractions
- [ ] Changes are minimal and focused on the task

### Localization
- [ ] If UI text was added/changed, all 5 language files updated:
- `en.lproj/Localizable.strings`
- `ja.lproj/Localizable.strings`
- `zh-Hans.lproj/Localizable.strings`
- `zh-Hant.lproj/Localizable.strings`
- `ko.lproj/Localizable.strings`

### Security
- [ ] No hardcoded secrets or credentials
- [ ] Sensitive data uses KeychainManager

### Testing (Manual)
- [ ] Build succeeds in Xcode (Cmd+B)
- [ ] Run and verify functionality (Cmd+R)
- [ ] Test with Debug Mode if applicable
- [ ] Test on target macOS version (13.0+)

## Commit
```bash
git add .
git commit -m "type: concise description"
```

Commit types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`

## Release (if applicable)
Include `[release]` in commit message to trigger GitHub Actions:
```bash
git commit -m "feat: new feature [release]"
```
89 changes: 89 additions & 0 deletions .serena/project.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# list of languages for which language servers are started; choose from:
# al bash clojure cpp csharp
# csharp_omnisharp dart elixir elm erlang
# fortran fsharp go groovy haskell
# java julia kotlin lua markdown
# matlab nix pascal perl php
# powershell python python_jedi r rego
# ruby ruby_solargraph rust scala swift
# terraform toml typescript typescript_vts vue
# yaml zig
# (This list may be outdated. For the current list, see values of Language enum here:
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
# Note:
# - For C, use cpp
# - For JavaScript, use typescript
# - For Free Pascal/Lazarus, use pascal
# Special requirements:
# - csharp: Requires the presence of a .sln file in the project folder.
# - pascal: Requires Free Pascal Compiler (fpc) and optionally Lazarus.
# When using multiple languages, the first language server that supports a given file will be used for that file.
# The first language is the default language and the respective language server will be used as a fallback.
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
languages:
- swift

# the encoding used by text files in the project
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
encoding: "utf-8"

# whether to use project's .gitignore files to ignore files
ignore_all_files_in_gitignore: true

# list of additional paths to ignore in all projects
# same syntax as gitignore, so you can use * and **
ignored_paths: []

# whether the project is in read-only mode
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
# Added on 2025-04-18
read_only: false

# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
# Below is the complete list of tools for convenience.
# To make sure you have the latest list of tools, and to view their descriptions,
# execute `uv run scripts/print_tool_overview.py`.
#
# * `activate_project`: Activates a project by name.
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
# * `create_text_file`: Creates/overwrites a file in the project directory.
# * `delete_lines`: Deletes a range of lines within a file.
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
# * `execute_shell_command`: Executes a shell command.
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
# * `initial_instructions`: Gets the initial instructions for the current project.
# Should only be used in settings where the system prompt cannot be set,
# e.g. in clients you have no control over, like Claude Desktop.
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
# * `insert_at_line`: Inserts content at a given line in a file.
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
# * `list_memories`: Lists memories in Serena's project-specific memory store.
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
# * `read_file`: Reads a file within the project directory.
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
# * `remove_project`: Removes a project from the Serena configuration.
# * `replace_lines`: Replaces a range of lines within a file with new content.
# * `replace_symbol_body`: Replaces the full definition of a symbol.
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
# * `search_for_pattern`: Performs a search for a pattern in the project.
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
# * `switch_modes`: Activates modes by providing a list of their names
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
excluded_tools: []

# initial prompt for the project. It will always be given to the LLM upon activating the project
# (contrary to the memories, which are loaded on demand).
initial_prompt: ""

project_name: "Usage4Claude"
included_optional_tools: []
12 changes: 6 additions & 6 deletions Usage4Claude.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Usage4Claude-CodeSigning";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Usage4Claude-CodeSigning";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
Expand Down Expand Up @@ -306,9 +306,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Usage4Claude-CodeSigning";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Usage4Claude-CodeSigning";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
Expand Down
14 changes: 14 additions & 0 deletions Usage4Claude/Helpers/LocalizationHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,20 @@ enum L {
}
}

// MARK: - Graph Type
enum GraphType {
static var circular: String { localized("graph_type.circular") }
static var linear: String { localized("graph_type.linear") }
}

// MARK: - Graph Style Settings
enum GraphStyle {
static var title: String { localized("graph_style.title") }
static var hint: String { localized("graph_style.hint") }
static var circularDescription: String { localized("graph_style.circular_description") }
static var linearDescription: String { localized("graph_style.linear_description") }
}

// MARK: - Helper Methods

/// 本地化字符串辅助方法
Expand Down
Loading