Complete file structure for the Claude Session Monitor macOS app.
claude-sessions/
├── claude-sessions.xcodeproj/ # Xcode project file
├── claude-sessions/ # Main source directory
│ ├── App/
│ │ └── (Xcode-managed files)
│ ├── Models/
│ │ ├── ClaudeSession.swift # Main session model with computed properties
│ │ ├── StatuslineData.swift # Raw JSON structure from statusline
│ │ └── SessionStatus.swift # Enum for active/idle/closed states
│ ├── Managers/
│ │ ├── SessionManager.swift # File monitoring, session loading, actions
│ │ └── PreferencesManager.swift # UserDefaults, launch at login
│ ├── Views/
│ │ ├── MenuBar/
│ │ │ ├── MenuBarLabel.swift # Main label switcher
│ │ │ ├── MultipleCirclesView.swift # Display: ●●●○
│ │ │ ├── SingleIconWithBadgeView.swift # Display: ◉ 5
│ │ │ └── CompactWithOverflowView.swift # Display: ●●● +2
│ │ ├── Menu/
│ │ │ ├── StatusMenuView.swift # Main dropdown container
│ │ │ ├── SessionRowView.swift # Individual session row
│ │ │ ├── SummaryView.swift # Cost & stats summary
│ │ │ └── EmptyStateView.swift # No sessions placeholder
│ │ └── Preferences/
│ │ └── PreferencesView.swift # Settings window
│ ├── claude_sessionsApp.swift # @main entry point with MenuBarExtra
│ ├── ContentView.swift # (Unused, from template)
│ ├── Info.plist # LSUIElement for menubar-only
│ ├── claude_sessions.entitlements # Sandbox, /tmp access, AppleScript
│ └── Assets.xcassets/ # App icons
├── README.md # Main documentation
├── SETUP.md # Detailed setup guide
├── QUICKSTART.md # 5-minute quick start
├── PROJECT_STRUCTURE.md # This file
├── LICENSE # MIT License
├── .gitignore # Xcode/Swift gitignore
└── statusline.sh # Example statusline script for users
ClaudeSession.swift
- Main data model representing a Claude session
- Computed
statusproperty based onlastUpdateTime - Computed
displayNameproperty for abbreviated paths - Contains nested structs: ModelInfo, ContextWindow, TokenUsage, Cost, CodeImpact
StatuslineData.swift
- Raw JSON structure matching statusline output
- Uses
CodingKeysfor snake_case to camelCase mapping - Nested structs mirror the JSON structure exactly
- Decoded from
/tmp/claude-status-*.jsonfiles
SessionStatus.swift
- Enum with cases: active, idle, closed
- Provides
color,emoji, andprioritycomputed properties - Used for sorting and visual display
SessionManager.swift
@Published var sessions: [ClaudeSession]- main data source- File system monitoring of
/tmpdirectory - Timer-based refresh (configurable interval)
- Session loading and JSON parsing
- Actions: removeSession, openInTerminal, openInFinder
PreferencesManager.swift
- Singleton pattern with
sharedinstance @Publishedproperties for all preferences- UserDefaults persistence
- Launch at login via SMAppService (macOS 13+)
- Display styles: multipleCircles, singleIconWithBadge, compactWithOverflow
MenuBarLabel.swift
- Switches between display styles based on preferences
- Receives sessions array and displayStyle
MultipleCirclesView.swift
- Shows up to 4 colored circles
- Default display style
SingleIconWithBadgeView.swift
- Single circle (color of most active session) + count badge
- Compact alternative
CompactWithOverflowView.swift
- Shows 3 circles + overflow count (e.g., "+2")
- Balance between detail and space
StatusMenuView.swift
- Main dropdown container (400pt wide)
- Header with title and refresh button
- Scrollable session list (max 400pt height)
- Summary section
- Footer with Preferences and Quit buttons
SessionRowView.swift
- Individual session display with hover state
- Shows: emoji, path, model, tokens, cost, context bar, duration
- Context menu: Copy Path, Open in Terminal/Finder, Remove
- Color-coded context bar (green/orange/red)
SummaryView.swift
- Total cost across all sessions
- Session count breakdown (active/idle/closed)
EmptyStateView.swift
- Shown when no sessions exist
- Icon + helpful message
PreferencesView.swift
- SwiftUI Form with grouped sections
- Display settings (style, show closed)
- Behavior settings (launch at login, intervals)
- About section (version, link)
claude_sessionsApp.swift
@mainstruct with SwiftUI App protocol@StateObjectfor SessionManager and PreferencesManager- MenuBarExtra scene with label and content
- Settings scene for preferences window
.menuBarExtraStyle(.window)for rich content
Info.plist
LSUIElement: true- No dock icon, menubar only- Copyright notice
claude_sessions.entitlements
- App Sandbox enabled
/tmp/read access (temporary exception)- AppleScript automation for Terminal/Finder
Assets.xcassets
- App icon (generated by Xcode)
- Can be customized with custom icon
┌─────────────────────────────────────────────────┐
│ Claude Code Session │
│ (running in terminal) │
└─────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ ~/.claude/statusline.sh │
│ - Reads JSON from stdin │
│ - Adds timestamp │
│ - Writes to /tmp/claude-status-{cwd}.json │
└─────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ SessionManager │
│ - File system monitoring (/tmp) │
│ - Timer-based refresh (2s default) │
│ - Reads & parses JSON files │
│ - Converts to ClaudeSession models │
│ - Publishes to @Published sessions array │
└─────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ MenuBarLabel (in menubar) │
│ - Observes sessions array │
│ - Displays colored circles │
│ - Updates automatically │
└─────────────────────────────────────────────────┘
│
▼ (on click)
┌─────────────────────────────────────────────────┐
│ StatusMenuView (dropdown) │
│ - Shows detailed session list │
│ - Summary statistics │
│ - Actions & preferences │
└─────────────────────────────────────────────────┘
- SwiftUI: All UI components
- MenuBarExtra: Modern menubar integration (macOS 13+)
- Combine: @Published properties for reactive updates
- DispatchSource: File system monitoring
- Timer: Periodic refresh
- UserDefaults: Preferences persistence
- SMAppService: Launch at login (macOS 13+)
- NSAppleScript: Terminal/Finder integration
- JSONDecoder: Parsing statusline JSON
- macOS 13.0+ (Ventura or later)
- Xcode 15.0+
- Swift 5.9+
- No external dependencies
- macOS 13.0+ (Ventura or later)
- Claude Code with statusline configured
jqinstalled (for statusline script)
- Add to Xcode Project: All Swift files need to be added to the Xcode project
- Configure Signing: Set development team in Signing & Capabilities
- Test Build: Build and run (⌘R)
- Test with Real Data: Start Claude session with statusline configured
- Package for Distribution: Archive and export with Developer ID
Since files were created outside Xcode, you need to add them:
- Open
claude-sessions.xcodeprojin Xcode - Right-click on
claude-sessionsgroup - Select "Add Files to 'claude-sessions'..."
- Navigate to each folder (Models, Managers, Views)
- Select all Swift files
- Ensure "Copy items if needed" is unchecked (files are already in place)
- Ensure "claude-sessions" target is checked
- Click "Add"
Or use the terminal:
# This will be done manually in Xcode as it's more reliable- App builds without errors
- App launches and shows menubar icon
- Menubar icon displays when sessions exist
- Clicking menubar shows dropdown
- Sessions load from /tmp
- Status indicators are correct (🟢🟡⚪)
- Context bars render correctly
- All metrics display properly
- Copy path works
- Open in Terminal works
- Open in Finder works
- Remove session deletes file
- Preferences save and apply
- All three display styles work
- Launch at login works
- App works with 0 sessions
- App works with 10+ sessions
- App updates when new session starts
- App updates when session closes
- macOS 13+ Only: MenuBarExtra requires Ventura or later
- Sandbox Restrictions: Requires temporary exception for /tmp access
- No App Store: Sandbox exceptions prevent App Store distribution
- Developer ID Required: For distribution outside development
- jq Dependency: Users must install jq for statusline script
See README.md Roadmap section for planned features.